[squeak-dev] Re: [Pharo-dev] Process>>restart

Eliot Miranda eliot.miranda at gmail.com
Thu Feb 25 18:29:17 UTC 2016


Hi Ben,

On Wed, Feb 24, 2016 at 10:44 PM, Ben Coman <btc at openinworld.com> wrote:

> On Thu, Feb 25, 2016 at 3:06 AM, Eliot Miranda <eliot.miranda at gmail.com>
> wrote:
> >
> >
> > On Wed, Feb 24, 2016 at 7:23 AM, Ben Coman <btc at 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]."
>

It can be built simply above signalException:.  So...

Process class methods for instance creation
forBlock: aBlockClosure priority: anInteger
"Answer an instance of me that has suspended aContext at priority
anInteger."

<primitive: 19> "Simulation guard"
| newProcess |
(newProcess := self new)
suspendedContext:
[[[newProcess result: aBlockClosure value.
  false]
on: ProcessRestart
do: [:ex| true]]
whileTrue.
"Since control is now at the bottom there is no need to terminate (which
runs unwinds) since all unwinds have been run.  Simply suspend.
Note that we must use this form rather than e.g. Processor suspendActive
so that isTerminated answers true.  isTerminated requires that if there is a
suspended context it is the bottom-most, but using a send would result in
the process's suspendedContext /not/ being the bottom-most."
newProcess suspend] asContext;
priority: anInteger.
^newProcess

Process methods for process state change
restart
self signalException: ProcessRestart


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.
>

Is there a missing yield somewhere?


>
> 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 at 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
>
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20160225/4a5fb121/attachment.htm


More information about the Squeak-dev mailing list