[squeak-dev] logging to Transcript from not-UI process

Eliot Miranda eliot.miranda at gmail.com
Mon Sep 14 05:18:07 UTC 2020


Hi Levente,

> On Sep 13, 2020, at 2:17 PM, Levente Uzonyi <leves at caesar.elte.hu> wrote:
> 
> Hi Tim,
> 
>> On Sun, 13 Sep 2020, tim Rowledge wrote:
>> 
>> The recent discussions about change logs etc, along with thinking about how the Toothpick package might do the job better (just realised that one could add an MQTT logger to it so that clusters of images could simply publish the logs and 'normal' tools could be used for sysadmin purposes) have reminded of a problem that has bitten me a couple of times over the last few weeks.
>> 
>> Basically, if we have a non-UI process (like Seaside handling) that tries to send something to the Transcript, then just occasionally and always, of course, during a demo, it will cause a problem. Obviously, I can't find a log file of it happening to illustrate; that would be far to helpful. IIRC it's something relating to the re-layout phase of the text morph.
>> 
>> Now I'd swear (and did!) that we 'fixed' this several years ago but I can't find any email about it so maybe I'm just hallucinating again.
>> 
>> Has anybody else seen this, or can remember about it or... ?
> 
> Only the #endEntry message is protected against concurrent access, so you can't write anything in a thread-safe manner outside the UI process.
> 
> I would say it was written with a single process in mind, and later "patched" to be able to "handle" concurrent access.
> 
> My workaround is that whenever I need to log something to the Transcript from potentially another process, I prepare the string to log in my process then use #addDeferredUIMessage: to inject it into the UI process in a safe way. E.g.
> 
> Transcript open.
> [
>        | message |
>        message := 'This is a very {1} log message at {2}.' format: { 'important'. DateAndTime now
> }.
>        Project current addDeferredUIMessage: [ Transcript nextPutAll:
> message; cr; endEntry ] ] fork.
> 
> What I've been thinking about in the past decade is to add new formatting messages to TranscriptStream. E.g. #show:formattedWith:, which does what the above thing would but you could just send it to Transcript directly, like:
> 
> Transcript show: 'This is a very {1} log message at {2}.{3}' formattedWith: { 'important'. DateAndTime now. String cr }
> 
> Or #showStream:, which would let you safely write a message on a stream. E.g.:
> 
> Transcript showStream: [ :stream | stream nextPutAll: 'foo'; nextPutAll: 'bar'; cr ].
> 
> However, that would require a few changes like turning AccessSema into a Mutex to be reentrant. (also, why is AccessSema a class variable used by an instance?)

Agreed.  We should at least fix this.  The mutex should be an inst var.

> #nextPut:, #nextPutAll: and all the other Stream API exposed by inheritance are useless, because tThey can't be made concurrent unless they are all overridden.
> So, IMHO TranscriptStream should be replaced with a new class inheriting from Object, containing a single WriteStream, and providing a thread-safe API (which can be the same as the current one).

Agreed.  And if the internal architecture uses a shared queue we can cleanly separate writing from rendering. 

> Levente
> 
>> 
>> tim
>> --
>> tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
>> Java:  the best argument for Smalltalk since C++
> 


More information about the Squeak-dev mailing list