[squeak-dev] Transcript error when forceUpdate: false (?)

Tobias Pape Das.Linux at gmx.de
Thu Jan 28 09:58:21 UTC 2021



> On 28. Jan 2021, at 10:41, Marcel Taeumel <marcel.taeumel at hpi.de> wrote:
> 
> Hi Tobias
> 
> > A separate kind of log (that optionally could output to the transcript)
> 
> Transcript can use stdout already. Not sure we want to shift the problem to the user again ... :-/ "Every time you provide an option, you expect users to make a decision." :-)
> 

That's not what I meant.

Transcript is Smalltalk for stdout, I would say.
Complicating it to act like a proper logger is IMHO ill-directed.

Neither C printf nor Java System.out.println[1] nor (i think) Racket display are thread safe.

And I think this is ok.

Transcript shouldn't break when used concurrently, but I don't think it should do something sophisticated…

Transcript is not a good logger. We shouldn't pretend it is.

Maybe GemStone's object log is a neat abstraction. Thread-safe, object based, with time stamps.



Best regards
	-Tobias

[1]: https://stackoverflow.com/questions/32880557/is-system-out-println-thread-safe-by-default
> Best,
> Marcel
>> Am 28.01.2021 10:32:27 schrieb Tobias Pape <das.linux at gmx.de>:
>> 
>> Hi
>> 
>> apart from the debuggers, why bother making Transcript thread-safe in the first place?
>> 
>> The Transcript is a mere output stream for debugging/logging etc., our stdout or stderr.
>> 
>> A separate kind of log (that optionally could output to the transcript) would be more apt IMHO.
>> Thread safety could be addressed there without complicating Transcript more…
>> 
>> my 2ct
>> -tobias
>> 
>> 
>> > On 28. Jan 2021, at 09:05, Marcel Taeumel wrote:
>> > 
>> > Hi Levente.
>> > 
>> > Thanks für clarification. We are talking about more than one problem here. :-) I did just address the issue with errors/debuggers happening due to UI process disruptions. You are also concerned about the order of contents in the Transcript's contents. Both are very important and required for claiming that it would be thread-safe.
>> > 
>> > (Which reminds me that I find it very strange that the UI components (e.g. PluggableTextMorph) do also check the Transcript's internal characterLimit. I would expect an append-only behavior when a Transcript window is open.)
>> > 
>> > Anyway, your proposal about a safelyNextPut(All): looks good. :-) +1
>> > 
>> > Best,
>> > Marcel
>> >> Am 27.01.2021 23:05:21 schrieb Levente Uzonyi :
>> >> 
>> >> Hi Marcel,
>> >> 
>> >> On Tue, 26 Jan 2021, Marcel Taeumel wrote:
>> >> 
>> >> > Hi Jaromir,
>> >> > please take a look at Collections-mt.923 (inbox). Maybe those changes would satisfy all your current needs in this regard. :-)
>> >> > 
>> >> > @all: Would Transcript now be thread-safe? Did I miss something?
>> >> 
>> >> Not at all. The problem is not #endEntry but all the other 
>> >> methods writing to the stream e.g.: #nextPutAll:.
>> >> The real solution is to replace the stream-like API with one that provides 
>> >> an easy way to write messages in a thread-safe way. E.g.:
>> >> 
>> >> Transcript showStream: [ :stream |
>> >> stream nextPutAll: 'Hello'; space; nextPutAll: ' World!'; cr ]
>> >> 
>> >> Which guarantees that 'Hello World!' appears on the Transcript without 
>> >> being mixed with other messages.
>> >> 
>> >> or
>> >> 
>> >> Transcript show: 'Hello {1}!{2}' format: { 'World'. String cr }.
>> >> 
>> >> The implementations could be e.g.:
>> >> 
>> >> showStream: aBlock
>> >> 
>> >> | string |
>> >> string := String streamContents: aBlock.
>> >> self safelyNextPutAll: string
>> >> 
>> >> show: aString format: arguments
>> >> 
>> >> | string |
>> >> string := aString format: arguments.
>> >> self safelyNextPutAll: string
>> >> 
>> >> The last challenge is to implement #safelyNextPutAll: which involves 
>> >> making Transcript not be a TranscriptStream.
>> >> Transcript should encapsulate the stream and use a Mutex (not a global one 
>> >> because its pointless) to provide thread-safety while writing the 
>> >> characters on it or reading its contents. E.g.:
>> >> 
>> >> safelyNextPutAll: aString
>> >> 
>> >> mutex critical: [
>> >> stream nextPutAll: aString ]
>> >> 
>> >> For backwards compatibility, the stream-API methods must be provided for a 
>> >> while but those methods should be thread-safe on their own. E.g.:
>> >> 
>> >> nextPutAll: aString
>> >> 
>> >> self safelyNextPutAll: aString
>> >> 
>> >> nextPut: aCharacter
>> >> 
>> >> self safelyNextPutAll: aCharacter asString
>> >> 
>> >> 
>> >> Levente
>> >> 
>> >> > 
>> >> > Best,
>> >> > Marcel
>> >> >
>> >> > Am 25.01.2021 21:38:36 schrieb jaromir :
>> >> >
>> >> > Well, I tried deferring the whole Transcript endEntry machinery to the UI
>> >> > doOneCycle (bypassing the changed: #appendEntryLater mechanism) for
>> >> > #forceUpdate = false only ... and it seems to avoid the problem!
>> >> >
>> >> > TranscriptStream >> endEntry
>> >> >
>> >> > deferredEntry ifNil: [ false ]. "this is a new instance variable"
>> >> > self semaphore critical:[
>> >> > self class forceUpdate
>> >> > ifTrue: [self changed: #appendEntry; reset]
>> >> > ifFalse: [deferredEntry := true].
>> >> > 
>> >> >
>> >> > TranscriptStream >> flushDeferredEntry
>> >> > "This is run every UI cycle in doOneCycleNowFor:"
>> >> >
>> >> > deferredEntry ifTrue: [
>> >> > self class forceUpdate: true.
>> >> > self endEntry.
>> >> > deferredEntry := false.
>> >> > self class forceUpdate: false.
>> >> > ]
>> >> >
>> >> > doOneCycleNowFor: aWorld
>> >> >
>> >> > "... the whole body remains unchanged except:"
>> >> >
>> >> > capturingGesture ifFalse:
>> >> > [aWorld runStepMethods.
>> >> > Transcript flushDeferredEntry. "this is printing for #forceUpdate =
>> >> > false"
>> >> > self displayWorldSafely: aWorld].
>> >> > 
>> >> >
>> >> > For #forceUpdate = true the endEntry mechanism remains unchanged and failing
>> >> > as before...
>> >> > 
>> >> > 
>> >> >
>> >> > --
>> >> > Sent from: http://forum.world.st/Squeak-Dev-f45488.html
>> >> > 
>> >> > 
>> >> >
>> >> 
>> > 
>> 
>> 
>> 
> 




More information about the Squeak-dev mailing list