[Glass] Can I plug a custom transcript proxy for one closure execution?

Mariano Martinez Peck via Glass glass at lists.gemtalksystems.com
Mon Aug 10 05:23:14 PDT 2015


On Fri, Aug 7, 2015 at 5:50 PM, Dale Henrichs via Glass <
glass at lists.gemtalksystems.com> wrote:

> On 08/07/2015 01:09 PM, Mariano Martinez Peck via Glass wrote:
>
> I think what I need is impossible to do...
>
> btw...* there is no way I can add a symbol dictionary to the symbolList
> of the current user but only for the scope of the running gem?*
>
> There are two symbol lists for a session available:
>
>   GsSession currentSession userProfile symbolList. "persistent symbolList"
>   GsSession currentSession symbolList.                   "transient copy
> of user's symbolList"
>
> Changes made to the transient copy of the symbolList are not persisted on
> a commit.
>
>
Hi Dale,

Having a transient version of the symbolList for inside the gem is a
brilliant idea!!! Thanks to whoever thought about that :)


> I know if I don't commit my changes will be only for current session. But
> my background processes DO commit and so they would also commit this
> change.
>
> It occurs to me that there is an alternate solution. in 3.x, there are two
> method dictionaries associated with a class: a persistentMethodDict and a
> transientMethodDict. methods stashed in the transientMethodDict override
> those methods in the persistentMethodDict, but the transientMethodDict is
> not persisted and is session specific ...
>
> So, if you arranged to compile a new version of TranscriptProxy
> class>>show: into the transientMethodDict, then you could effectively
> change the behavior for just the session even in the presence of commits.
>
> For 3.3 I've created a set of methods that make if easy to install and
> remove individual transient methods, but to be honest there is some fairly
> convoluted logic involved and I'm not sure that the code would translate
> straight from 3.3 to 3.1.0.6 without some work ...
>


OK...yes, i searched how I could install a transient compiled method that
would override the  behavior of the persistent one but I found no way in
3.1.0.6. So...I think I will leave with the override... (continue below)


>
> Hmmmmmmm,
>
> Perhaps if you changed the method to be something like the following:
>
>   show: anObject
>     | proxy |
>     (ObjectLogEntry transcript: anObject printString object: anObject)
> addToLog.
>     (proxy := self proxyTranscript) ~~ nil
>       ifTrue: [ proxy show: anObject ]
>       ifFalse: [
>         (GsSession currentSession symbolList objectNamed: #SkipLogging)
>           ifNotNil: [ GsFile gciLogServer: '--transcript--' , anObject
> printString ] ]
>
> And then in the gems where you want to skip tranlogging for the session,
> you do the following:
>
>   | skipLoggingDict symbolList |
>   skipLoggingDict := SymbolDictionary new.
>   skipLoggingDict at: #'SkipLogging' put: Object new.
>   symbolList := GsSession currentSession symbolList.
>   symbolList add: skipLoggingDict before: UserGlobals
>
> This code defines #'SkipLogging' in the transient symbol list so it is
> safe to commit ...
>
>
Thanks Dale. That works perfectly. Of course, to avoid the override of
#show: I tried my own subclass and I tried to do:

 skipLoggingDict at: #'Transcript' put: MyProxyTranscriptSubclass.

And of course, that doesn't work because I imagine all compiled methods
that were already compiled have an association pointing back to the
persistent user globals rather than my modified transient one. So yeah, a
solution would be installing a transient compiled method in TranscriptProxy
class. But if you say that this is complicated for 3.1.0.6, I think i can
live with the override.

BTW Dale, do you think we should add this in the real TranscriptProxy? If
true, let me know and I can open an issue. This is the code:

TranscriptProxy class >>  show: anObject
    | proxy |
 * (GsSession currentSession symbolList objectNamed:
#SkipObjectLogLogging) *
  ifNil: [ (ObjectLogEntry transcript: anObject printString object:
anObject) addToLog ].
    (proxy := self proxyTranscript) ~~ nil
      ifTrue: [ proxy show: anObject ]
      ifFalse: [
        *(GsSession currentSession symbolList objectNamed:
#SkipGemLogFileLogging) *
          ifNil: [ GsFile gciLogServer: '--transcript--' , anObject
printString ] ]


And an example of usage:

| skipLoggingDict symbolList |
  skipLoggingDict := SymbolDictionary new.
*  skipLoggingDict at: #'SkipObjectLogLogging' put: Object new.*
  symbolList := GsSession currentSession symbolList.
  symbolList add: skipLoggingDict before: UserGlobals.


Thanks,



> Dale
>
>
>
>
>
> On Thu, Aug 6, 2015 at 5:30 PM, Mariano Martinez Peck <
> marianopeck at gmail.com> wrote:
>
>> Hi guys,
>>
>> This is the situation... I have some kind of background jobs that are
>> fired from seaside and they fork their own gem. From this background jobs I
>> can easily watch the log of the gem etc. One example of this is for
>> example, "Code Update". Problem is that a simple Code Update via Metacello
>> brings hundreds of entries in the ObjectLog (each Transcript show: ). Same
>> for my own background jobs. And it's redundant for me to have them in both
>> places, the gem log AND the object log.
>>
>> So..the code is:
>>
>> TranscriptProxy class: show: anObject
>>
>> | proxy |
>> *(ObjectLogEntry transcript: anObject printString object: anObject)
>> addToLog.*
>> (proxy := self proxyTranscript) ~~ nil
>> ifTrue: [ proxy show: anObject ]
>> *ifFalse: [ GsFile gciLogServer: '--transcript--', anObject printString
>> ].*
>>
>> The second line is how the thing gets written in the ObjectLog and fifth
>> line is how in the gem log file.
>>
>> So... is there a way I can hook and say... for this closure execution,
>> bind "Transcript" to this MarianoProxyTranscript (this class would only
>> write to gem log for example).  I could do:
>>
>> *Smalltalk at: #Transcript put: MarianoProxyTranscript.*
>> *[*
>> *self executeCode*
>> *] ensure: [Smalltalk at: #Transcript put: TranscriptProxy.]*
>>
>> But that will affect other users right? (assuming the execureCode would
>> do a commit at some point).
>>
>> Once James said: "Here is one alternative to consider: When a method is
>> compiled you provide a SymbolList that identifies the globals visible to
>> the code being compiled."
>> Could I compile the closure with the binding specified for Transcript?
>>
>> Thanks in advance,
>>
>>
>> --
>> Mariano
>> http://marianopeck.wordpress.com
>>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
>
> _______________________________________________
> Glass mailing listGlass at lists.gemtalksystems.comhttp://lists.gemtalksystems.com/mailman/listinfo/glass
>
>
>
> _______________________________________________
> Glass mailing list
> Glass at lists.gemtalksystems.com
> http://lists.gemtalksystems.com/mailman/listinfo/glass
>
>


-- 
Mariano
http://marianopeck.wordpress.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gemtalksystems.com/mailman/private/glass/attachments/20150810/08e19367/attachment.html>


More information about the Glass mailing list