Stef,
I'm not sure that concurrent use of the ThreadSafe Transcript is any more or
less dangerous from the foreground process than from background process.
I've experimented with a mod to ThreadSafeTranscript>>endEntry that allows for
both foreground and background updating of the transcript. The following
expression:
| tt |
tt := (Smalltalk at: #Transcript).
"Background updates"
[1 to: 20 do: [:i | tt nextPutAll: '[', i printString, ']'; nextPutAll:
'*'; flush .
Processor yield ].
tt flush ] fork.
"Background updates"
[100 to: 120 do: [:i | tt nextPutAll: '{', i printString, '}';
nextPutAll: '-'; flush.
Processor yield ].
tt flush ] fork.
"Foreground updates"
200 to: 220 do: [:i | tt show: '---', i printString, '---'. Processor
yield ]
produces this output in the transcript:
---200---[1]{100}*---201----[2]---202---*{101}----203---[3]*{102}---204----[4]*---205---{103}-[5]---206---*{104}----207---[6]*{105}---208----[7]*---209---{106}-[8]---210---*{107}----211---[9]*{108}---212----[10]*---213---{109}-[11]---214---*{110}----215---[12]*{111}---216----[13]*---217---{112}-[14]---218---*{113}----219---[15]*{114}---220----[16]*{115}-[17]*{116}-[18]*{117}-[19]*{118}-[20]*{119}-{120}-
I protected the #changed: message and the #displayWorldSafely with the access
semaphore so at a minimum concurrent transcript accesses shouldn't be a
problem. With this mod,the transcript updates when called from a lone
foreground process, too.
If you want, I can can submit a bug along with the proposed
fix...Alternatively, I think I've probably got enough info to fix my problem in
isolation.
Hmmm, perhaps WorldState needs a mutex to make #displayWorldSafely truly safe?
Dale
----- "Stéphane Ducasse" <[email protected]> wrote:
| I m not really satisfied of what I did but I think that this is
| important to have a thread safe transcript.
| Now I have the impression that the Morphic concurrency model could
| really be rethought.
| I'm not good enough with process and the rest but I got so burnt by
| it
| (I had to cancel work made by nathanael for the botsinc environment
|
| to have animation in BotsInc
| because they worked on PC but blocked the UI on mac).
|
| On Aug 7, 2009, at 9:06 PM, Dale Henrichs wrote:
|
| > Igor,
| >
| > I appreciate what you are saying and in the fullness of time, we may
|
| > be able to do more things with background processes.
| >
| > However, we _are_ running a development environment for GemStone
| > that should appear to the user to be no different than the Pharo
| > development environment ... i.e., when you evaluate the following
| > expression in Pharo or The GemTools client:
| >
| > 10 timesRepeat: [ (Delay forSeconds: 1) wait ]
| >
| > you would expect the UI process to be blocked for the duration of
| > execution. This is why I _block_ the UI process during execution.
| >
| > If you have a long running process running in the foreground
| > (whether or not it is running on GemStone) you expect to be able to
|
| > interrupt the process and bring up a debugger on the interrupted
| > process. In order to do that with the GemTools client, we have to
| > use a non-blocking C call, so that the GemTools client can recognize
|
| > the interrupt and take appropriate action. This is why we are using
|
| > a non-blocking call.
| >
| > With that said, something subtle _has_ changed in the way that the
|
| > Pharo UI processes updates windows ... In earlier versions of Pharo,
|
| > the Transcript window (whether or not it was thread-safe) updated
| > without any special effort on my part, with the 1.0 beta, the
| > transcript window is not updating. I've tried both thread safe and
|
| > non-thread safe Transcripts and it doesn't appear to matter.
| >
| > While poking around, I have discovered that the transcript is not
| > updated until the process finishes in Pharo either. So the following
|
| > expression "misbehaves" whether executed in GemStone or Pharo:
| >
| > 10 timesRepeat: [
| > (Delay forSeconds: 1) wait.
| > Transcript cr; show: 'hi' ]
| >
| > I guess I _expect_ the display to be updated whether or not I am
| > running a process in the foreground.
| >
| > If I insert a 'World displayWorldSafely' into the loop then the
| > transcript is updated 'correctly':
| >
| > 10 timesRepeat: [
| > (Delay forSeconds: 1) wait.
| > Transcript cr; show: 'hi'.
| > World displayWorldSafely ]
| >
| > Is this expected behavior and the correct solution to my problem?
| >
| > Dale
| > ----- "Igor Stasenko" <[email protected]> wrote:
| >
| > | 2009/8/7 Dale Henrichs <[email protected]>:
| > | > I'm trying to characterize some differences in behavior for
| > GemTools
| > | between Squeak and the 1.0beta for Pharo. I'm not reporting a bug
| as
| > | much as trying to understand what I need to do differently in
| Pharo.
| > | >
| > | > In GemTools, I have a special workspace (GemTools Launcher),
| that
| > | causes doits to be evaluated in a GemStone server. This is done
| by
| > | using FFI to make calls to the GemStone GCI library.
| > | >
| > | > The string is passed to GemStone via a nonblocking C call. On
| the
| > | Pharo (client) side, we poll for a result. While an expression is
| > | evaluating, exceptions may be raised on the server-side and on
| the
| > | client, we convert the gemstone exception into a Pharo exception
| and
| > | signal it, if/when the exception is resumed, we pass a result back
|
| > to
| > | the server and continue waiting for the result of the original
| > | expression.
| > | >
| > | > There are two thing that might happen when a exception is raised
|
| > in
| > | this manner. If the exception is an error, we bring up a debugger
| > | window on the client and arrange to debug the process on the
| server
| > | (again using the GCI). If the exception is what we call a Client
| > | Forwarder exception, then we arrange to send a message to the
| client
| > | object and pass the result back to the server side. Using a
| client
| > | forwarder, the server can send messages to the client Transcript
|
| > with
| > | logging/progress messages.
| > | >
| > | > In earlier versions of Pharo and in the current version of
| Squeak,
| > | when we sent messages to the Transcript, the messages would show
| up
| > | immediately ... making it easy to watch progress of long running
| > | operations.
| > | >
| > | > In the 1.0 beta Pharo, this behavior has changed. It appears
| that
| > | the Transcript window is not updated until the polling process
| > | finishes, which makes the progress messages a little bit less
| than
| > | useful.
| > | >
| > | > I assume that I need to add a message to my polling loop to
| allow
| > | for display updates...I'm doing a Delay wait in the loop so the
| > | process is not in a tight loop.
| > | >
| > | > I am not running the poll in the background, because I want the
| UI
| > | process to be blocked ... this same mechanism is used for menu
| > items,
| > | etc. so blocking is important.
| > | >
| > | > Thanks for the help,
| > |
| > | Dale, the key problem of this is that 'wait loop' blocks the UI
| > | process. I know, it is simplest way to prevent user from doing
| > | anything while system is busy but its not very friendly,
| especially
| > | when you need to perform a remote processing which requires a
| > | substantional amount of time to complete.
| > | But, i wonder, what is the point in using a non-blocking calls to
| > | communicate with GemStone, when in the end its still blocks
| > | everything
| > | (from user's point of view) ? :)
| > |
| > | Stef did a good job making a Transcript thread-safe in Pharo, so
| it
| > | can be used by any process (not only UI one) safely.
| > | But this implies that you should not block the UI thread to give
|
| > it a
| > | chance to update the screen. In case if nothing blocks the
| process,
| > | the transcript window will be updated each 20ms or so (World
| update
| > | cycle), and such delay, i think will be hardly noticeable by
| users.
| > | Transcript is a stream , which updated immediately once you
| putting
| > | something to it, but there are no guarantees that any other
| objects
| > | (like window , which is displaying its contents) should be
| updated
| > | immediately as well.
| > |
| > | I am encouraging you to create a background process , which talks
| > | with
| > | GemStone, and then UI process just schedule user actions to it.
| This
| > | will make UI process non-blocking, but of course, requires
| > additional
| > | efforts, like disabling the user from doing anything while
| waiting
| > | response from G/S. But this could be done nicely, and user could
| go
| > | to
| > | any other window/menu etc, and do things there while G/S
| processing
| > | the actions. Which i think makes UI much more friendly.
| > |
| > |
| > | >
| > | > Dale
| > | >
| > | > _______________________________________________
| > | > Pharo-project mailing list
| > | > [email protected]
| > | > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-
| > project
| > | >
| > |
| > |
| > |
| > | --
| > | Best regards,
| > | Igor Stasenko AKA sig.
| >
| > _______________________________________________
| > Pharo-project mailing list
| > [email protected]
| > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project