On Thu, Feb 25, 2016 at 3:06 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Wed, Feb 24, 2016 at 7:23 AM, Ben Coman <btc@openinworld.com> wrote:
Just sharing a passing thought so I don't forget it before I have time to think more deeply on it.
Several parts of Pharo (like SHTextStyler) are designed to have a background process running, and when new input arrives that process is killed so another can be immediately started - and sometimes we seem to end up with large amounts of zombie processes.
As I poke around Process>>terminate, I wonder if a different approach would be to have a Process>>restart. I see there is Context>>restart.
The starting the background process might look like...
stylingProcess := [ [ "do stuff with nextData". self suspend ] repeat ] forkAt: 30.
and the code in the main morphic priority 40 thread might look like...
sylingProcess suspend. nextData := 'blah'. sylingProcess restart.
Hi Ben, so I'm assuming restart differs from resume. Am I right in thinking it cuts back the process to the "start"? Is the start the block from which the process was spawned, the argument to fork or forkAt:?
Thats right. Essentially like Exception>>retry, to do something like this... restart := false. workAvailable := Semaphore new. process := [ [ Transcript crShow: 'At the start'. work := 0. [ work := work + 1. Transcript crShow: 'working on ' , work printString. 1 second wait. work>8 ifTrue: [ [Transcript crShow: 'Work complete.'] fork. workAvailable wait. restart := true. ]. restart ifTrue: [self error]. work ] repeat. ] on: Error do: [:err| restart := false. err retry]. ] newProcess name:'My Restartable Worker'. process resume. "later do..." restart := true. "or after work complete..." workAvailable signal. "later still do..." process terminate ...except being able to interrupt the process anytime, i.e. not needing to wait to get to "restart ifTrue: [self error]." btw, The requirement for the fork in "[Transcript crShow: 'Work complete.'] fork" is strange. Without it the semaphore does not wait, which seems a bug. btw2, I needed to hack OCUndeclaredVariableWarning>>defaultAction to stop the transcript being polluted by unknown playground variables. No warranty on whether this is suitable to be permanent... className = 'UndefinedObject' ifFalse: [ self methodNode selector ifNotNil: [self crTrace: className, '>>', selector, ' '] ifNil: [self traceCr:'']. self traceCr: '(' , varName , ' is Undeclared1) '. ]. On Thu, Feb 25, 2016 at 2:56 AM, Max Leske <maxleske@gmail.com> wrote:
Fast spawning processes are very hard to debug (e.g. in the process browser).
This is exactly the use case I was thinking of. Often they've been and gone before you even know they are there. Having a permanent process aids discoverability of system background functionality. cheers -ben