[Pharo-project] Global session object?
I wanna have this: SmalltalkImage>>snapshot: save andQuit: quit ... resuming ifTrue: [ session := self newSession ]. ... (where session is additional instance variable of SmalltalkImage). SmalltalkImage>>newSession "Just answer unique object, which never can be identical to any previous session object, this is all what we need for detecting session change. A session object don't needs to carry any state (we have plenty of other objects in image which can do this for us). it just needs to be unique" ^ Object new. SmalltalkImage>>session ^ session then, i can write in own code: Smalltalk session == mySession ifFalse: [ self initForNewSession. mySession := Smalltalk session ] So, basically, this little addition allows you to detect whether session changed or not between two different calls to your code (given that you remembered the previous session somewhere). Currently we don't have such feature, and looking how some existing code deals with session management, i see how it can be simplified. If you want to do something similar today, you will need to register in startup list.. which IMO stinks ;) i don't like using startup lists, since you never know , what is the right order of resource initialization, and what inter-dependencies they may form, and changing dependencies over time will require changing startup order, again and again. Not fun. This technique allows you to lazily re-initialize any of your object(s) due to session change, once the control flow hits your code, but not before. (so you don't have to do all accounting at image startup time, you doing it only when it required/requested, which means shorter image startup time). The notion of session is highly important for external resource management. I using it in NativeBoost from very beginning, and wanna propose to use it globally. -- Best regards, Igor Stasenko.
Hello, Yes, this sounds good. Marcus On Oct 8, 2012, at 5:11 AM, Igor Stasenko <siguctua@gmail.com> wrote:
I wanna have this:
SmalltalkImage>>snapshot: save andQuit: quit ... resuming ifTrue: [ session := self newSession ]. ...
(where session is additional instance variable of SmalltalkImage).
SmalltalkImage>>newSession "Just answer unique object, which never can be identical to any previous session object, this is all what we need for detecting session change. A session object don't needs to carry any state (we have plenty of other objects in image which can do this for us). it just needs to be unique"
^ Object new.
SmalltalkImage>>session ^ session
then, i can write in own code:
Smalltalk session == mySession ifFalse: [ self initForNewSession. mySession := Smalltalk session ]
So, basically, this little addition allows you to detect whether session changed or not between two different calls to your code (given that you remembered the previous session somewhere). Currently we don't have such feature, and looking how some existing code deals with session management, i see how it can be simplified. If you want to do something similar today, you will need to register in startup list.. which IMO stinks ;)
i don't like using startup lists, since you never know , what is the right order of resource initialization, and what inter-dependencies they may form, and changing dependencies over time will require changing startup order, again and again. Not fun. This technique allows you to lazily re-initialize any of your object(s) due to session change, once the control flow hits your code, but not before. (so you don't have to do all accounting at image startup time, you doing it only when it required/requested, which means shorter image startup time).
The notion of session is highly important for external resource management.
I using it in NativeBoost from very beginning, and wanna propose to use it globally.
-- Best regards, Igor Stasenko.
-- Marcus Denker -- http://marcusdenker.de
I like your idea, but just so this does not get overlooked: See also [Stack]Interpreter>>getThisSessionID which is used in e.g. OSProcessPlugin>>primitiveGetSession for external resource management. You could move the primitive into the interpreter if you wanted to make it mandatory. This is the same session identifier that is used in the file and socket plugins, so it might have some advantages over using a newly allocated object that would not get allocated until after the plugins are already initialized. But it does need VM support, so your Object new approach is better in that respect. Dave On Mon, Oct 08, 2012 at 05:11:34AM +0200, Igor Stasenko wrote:
I wanna have this:
SmalltalkImage>>snapshot: save andQuit: quit ... resuming ifTrue: [ session := self newSession ]. ...
(where session is additional instance variable of SmalltalkImage).
SmalltalkImage>>newSession "Just answer unique object, which never can be identical to any previous session object, this is all what we need for detecting session change. A session object don't needs to carry any state (we have plenty of other objects in image which can do this for us). it just needs to be unique"
^ Object new.
SmalltalkImage>>session ^ session
then, i can write in own code:
Smalltalk session == mySession ifFalse: [ self initForNewSession. mySession := Smalltalk session ]
So, basically, this little addition allows you to detect whether session changed or not between two different calls to your code (given that you remembered the previous session somewhere). Currently we don't have such feature, and looking how some existing code deals with session management, i see how it can be simplified. If you want to do something similar today, you will need to register in startup list.. which IMO stinks ;)
i don't like using startup lists, since you never know , what is the right order of resource initialization, and what inter-dependencies they may form, and changing dependencies over time will require changing startup order, again and again. Not fun. This technique allows you to lazily re-initialize any of your object(s) due to session change, once the control flow hits your code, but not before. (so you don't have to do all accounting at image startup time, you doing it only when it required/requested, which means shorter image startup time).
The notion of session is highly important for external resource management.
I using it in NativeBoost from very beginning, and wanna propose to use it globally.
-- Best regards, Igor Stasenko.
On 8 October 2012 13:39, David T. Lewis <lewis@mail.msen.com> wrote:
I like your idea, but just so this does not get overlooked:
See also [Stack]Interpreter>>getThisSessionID which is used in e.g. OSProcessPlugin>>primitiveGetSession for external resource management. You could move the primitive into the interpreter if you wanted to make it mandatory.
This is the same session identifier that is used in the file and socket plugins, so it might have some advantages over using a newly allocated object that would not get allocated until after the plugins are already initialized. But it does need VM support, so your Object new approach is better in that respect.
yes, i saw that. The issue with sessionID, generated by VM, that there is a chance of collision: globalSessionID := 0. [globalSessionID = 0] whileTrue: [globalSessionID := self cCode: 'time(NULL) + ioMSecs()' inSmalltalk: [(Random new next * SmallInteger maxVal) asInteger]]. while 'Object new' can never collide, no matter what happens :) Also, according to VM sources, this thing is obsolete, or at least not used as it supposedly should be used, like in primitive literal: Interpreter>>primitiveExternalCall "Call an external primitive. The external primitive methods contain as first literal an array consisting of: * The module name (String | Symbol) * The function name (String | Symbol) * The session ID (SmallInteger) [OBSOLETE] * The function index (Integer) in the externalPrimitiveTable (i don't remember where, i also seen more code, when hacking HydraVM, with commented sections of code which dealt with session id, but then turned into NOP). Another question, why session id was not exposed to language by VM (your primitive in OSProcess plugin does that, but since plugin is optional, the question remains the same). The proposed change is trivial to introduce and use, but what important, it don't requires altering VM. Altering VM in order to fix/improve session management, will immediately bring new issue: how to play nicely when running images which expect such feature to be present, while users (for no good reason, of course ;) using old/obsolete VMs to run image. This is yet another thing which demonstrates that the less code you put in VM, the less you have to maintain and care less about compatibility issues. That's why i think that VM should be stupid, contain no complex logic and excessive features, only ones which having good reason to stay there (either no way how to do same thing in language, or gives a nice performance advantage).
Dave
-- Best regards, Igor Stasenko.
On Mon, Oct 08, 2012 at 04:12:13PM +0200, Igor Stasenko wrote:
Another question, why session id was not exposed to language by VM (your primitive in OSProcess plugin does that, but since plugin is optional, the question remains the same).
I don't know. Maybe nobody other than me ever wanted to use it ;) The session identifier is exposed through the InterpreterProxy, so it is part of the defined interface that is available to plugins. FilePlugin (and SocketPlugin IIRC) uses this identifier in its data structure to represent a file, so it provides a check to ensure that a file reference was created in the current session. I used this in OSPP because I wanted a separate plugin (not an extension of FilePlugin or SocketPlugin) that could interact with those same data structures. I did it that way because I wanted OSPP to be separate from the VM and the standard plugins, so anybody could build it without help from a VM guru. And I added the primitive so that I could do as much of the work in the image as possible. I guess we think alike in that regard ;)
The proposed change is trivial to introduce and use, but what important, it don't requires altering VM. Altering VM in order to fix/improve session management, will immediately bring new issue: how to play nicely when running images which expect such feature to be present, while users (for no good reason, of course ;) using old/obsolete VMs to run image.
This is yet another thing which demonstrates that the less code you put in VM, the less you have to maintain and care less about compatibility issues.
I agree. Dave
On Oct 8, 2012, at 4:12 PM, Igor Stasenko wrote:
On 8 October 2012 13:39, David T. Lewis <lewis@mail.msen.com> wrote:
I like your idea, but just so this does not get overlooked:
See also [Stack]Interpreter>>getThisSessionID which is used in e.g. OSProcessPlugin>>primitiveGetSession for external resource management. You could move the primitive into the interpreter if you wanted to make it mandatory.
This is the same session identifier that is used in the file and socket plugins, so it might have some advantages over using a newly allocated object that would not get allocated until after the plugins are already initialized. But it does need VM support, so your Object new approach is better in that respect.
yes, i saw that. The issue with sessionID, generated by VM, that there is a chance of collision:
globalSessionID := 0. [globalSessionID = 0] whileTrue: [globalSessionID := self cCode: 'time(NULL) + ioMSecs()' inSmalltalk: [(Random new next * SmallInteger maxVal) asInteger]].
how can they collide? I do not see it and it should be obvious. I want to learn :)
while 'Object new' can never collide, no matter what happens :)
Also, according to VM sources, this thing is obsolete, or at least not used as it supposedly should be used, like in primitive literal:
Interpreter>>primitiveExternalCall "Call an external primitive. The external primitive methods contain as first literal an array consisting of: * The module name (String | Symbol) * The function name (String | Symbol) * The session ID (SmallInteger) [OBSOLETE] * The function index (Integer) in the externalPrimitiveTable
(i don't remember where, i also seen more code, when hacking HydraVM, with commented sections of code which dealt with session id, but then turned into NOP).
Another question, why session id was not exposed to language by VM (your primitive in OSProcess plugin does that, but since plugin is optional, the question remains the same).
The proposed change is trivial to introduce and use, but what important, it don't requires altering VM. Altering VM in order to fix/improve session management, will immediately bring new issue: how to play nicely when running images which expect such feature to be present, while users (for no good reason, of course ;) using old/obsolete VMs to run image.
Go for it igor. But put a nice comment explaining the Object new
This is yet another thing which demonstrates that the less code you put in VM, the less you have to maintain and care less about compatibility issues. That's why i think that VM should be stupid, contain no complex logic and excessive features, only ones which having good reason to stay there (either no way how to do same thing in language, or gives a nice performance advantage).
Dave
-- Best regards, Igor Stasenko.
On 8 October 2012 21:39, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
On Oct 8, 2012, at 4:12 PM, Igor Stasenko wrote:
On 8 October 2012 13:39, David T. Lewis <lewis@mail.msen.com> wrote:
I like your idea, but just so this does not get overlooked:
See also [Stack]Interpreter>>getThisSessionID which is used in e.g. OSProcessPlugin>>primitiveGetSession for external resource management. You could move the primitive into the interpreter if you wanted to make it mandatory.
This is the same session identifier that is used in the file and socket plugins, so it might have some advantages over using a newly allocated object that would not get allocated until after the plugins are already initialized. But it does need VM support, so your Object new approach is better in that respect.
yes, i saw that. The issue with sessionID, generated by VM, that there is a chance of collision:
globalSessionID := 0. [globalSessionID = 0] whileTrue: [globalSessionID := self cCode: 'time(NULL) + ioMSecs()' inSmalltalk: [(Random new next * SmallInteger maxVal) asInteger]].
how can they collide? I do not see it and it should be obvious. I want to learn :)
They will collide eventually because id is 32-bit number. So, the max what you can have is 2^32 unique ids , after that you collide with existing ids inevitably. But given that 'time(NULL) + ioMSecs()' is far from having good random distribution, the collision probability is far more probable than 1/(2^32). When such collision happens, some objects in your system (which retain previously generated session id) will think that session is not changed, and all bad consequences will come shortly after that :) Still, those objects usually do not live long enough to have collision. And so, existing approach actually is good enough. But still, that's only a probability, while 'Object new' is certainty that you can never collide, and so it is simply better.
while 'Object new' can never collide, no matter what happens :)
Also, according to VM sources, this thing is obsolete, or at least not used as it supposedly should be used, like in primitive literal:
Interpreter>>primitiveExternalCall "Call an external primitive. The external primitive methods contain as first literal an array consisting of: * The module name (String | Symbol) * The function name (String | Symbol) * The session ID (SmallInteger) [OBSOLETE] * The function index (Integer) in the externalPrimitiveTable
(i don't remember where, i also seen more code, when hacking HydraVM, with commented sections of code which dealt with session id, but then turned into NOP).
Another question, why session id was not exposed to language by VM (your primitive in OSProcess plugin does that, but since plugin is optional, the question remains the same).
The proposed change is trivial to introduce and use, but what important, it don't requires altering VM. Altering VM in order to fix/improve session management, will immediately bring new issue: how to play nicely when running images which expect such feature to be present, while users (for no good reason, of course ;) using old/obsolete VMs to run image.
Go for it igor. But put a nice comment explaining the Object new
This is yet another thing which demonstrates that the less code you put in VM, the less you have to maintain and care less about compatibility issues. That's why i think that VM should be stupid, contain no complex logic and excessive features, only ones which having good reason to stay there (either no way how to do same thing in language, or gives a nice performance advantage).
Dave
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
participants (4)
-
David T. Lewis -
Igor Stasenko -
Marcus Denker -
Stéphane Ducasse