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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

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

GLASS mailing list
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,


--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Can I plug a custom transcript proxy for one closure execution?

GLASS mailing list
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?
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. 




On Thu, Aug 6, 2015 at 5:30 PM, Mariano Martinez Peck <[hidden email]> 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,


--



--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Can I plug a custom transcript proxy for one closure execution?

GLASS mailing list
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.

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

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

Dale




On Thu, Aug 6, 2015 at 5:30 PM, Mariano Martinez Peck <[hidden email]> 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,


--



--


_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass


_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Can I plug a custom transcript proxy for one closure execution?

GLASS mailing list

On Fri, Aug 7, 2015 at 5:50 PM, Dale Henrichs via Glass <[hidden email]> 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 <[hidden email]> 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,


--



--


_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass


_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass




--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Can I plug a custom transcript proxy for one closure execution?

GLASS mailing list


On 08/10/2015 05:23 AM, Mariano Martinez Peck wrote:

On Fri, Aug 7, 2015 at 5:50 PM, Dale Henrichs via Glass <[hidden email]> 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.


Sounds good...

Dale

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: Can I plug a custom transcript proxy for one closure execution?

GLASS mailing list

On Mon, Aug 10, 2015 at 1:46 PM, Dale Henrichs <[hidden email]> wrote:


On 08/10/2015 05:23 AM, Mariano Martinez Peck wrote:

On Fri, Aug 7, 2015 at 5:50 PM, Dale Henrichs via Glass <[hidden email]> 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.


Sounds good...

Dale



--

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass