WebSessionManager>>activeSessions

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

WebSessionManager>>activeSessions

Rob Rothwell
Can anyone explain activeSessions to me?  I mean, it seems like that would be, well, the active sessions connected?  But when I close all my browsers and tell the WebSessionManager to removeAllSessions, the activeSessions remain, and yet nothing is connected...?

It SEEMS like if you really wanted to clean up at night, you could remove these [activeSessions] as well?

Is this because I can't release the object created in the SwazooAida>>demoStart?

Just trying to understand the resources created and used a little better...

Rob

_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Rob Rothwell
On Fri, Jun 6, 2008 at 7:39 PM, Rob Rothwell <[hidden email]> wrote:
Can anyone explain activeSessions to me?  I mean, it seems like that would be, well, the active sessions connected?  But when I close all my browsers and tell the WebSessionManager to removeAllSessions, the activeSessions remain, and yet nothing is connected...?

It SEEMS like if you really wanted to clean up at night, you could remove these [activeSessions] as well?

Is this because I can't release the object created in the SwazooAida>>demoStart?

Just trying to understand the resources created and used a little better...


Well, something as simple as the following allows me to garbage collect on demand:

WebSessionManager allInstancesDo: [:eachManager |
    eachManager activeSessions copy keys do: [:key |
        eachManager activeSessions removeKey: key]].

This frees up session resources and allows me to garbage collect as expected.  All that happens is that the user needs to actually log on the next time they try to navigate to the site, so I don't see any harm doing this during a nightly routine of some kind, and it is quite useful during development since I keep testing lots of pages and their associated resources!

I'm sure there is more about sessions I should learn, but this gets me back on track for now...

Take care,

Rob


_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Stefan Schmiedl
On Sat, 7 Jun 2008 06:21:23 -0400
"Rob Rothwell" <[hidden email]> wrote:

> WebSessionManager allInstancesDo: [:eachManager |
>     eachManager activeSessions copy keys do: [:key |
>         eachManager activeSessions removeKey: key]].
>

Out of curiosity: Why do you use

        activeSessions copy keys

instead of

        activeSessions keys copy

or even just
       
        activeSessions keys ?

I'd expect the latter to be cheaper, since you're only duplicating
the keys (if at all) and not the sessions.

s.
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Janko Mivšek
In reply to this post by Rob Rothwell
Rob Rothwell wrote:
> Can anyone explain activeSessions to me?  I mean, it seems like that
> would be, well, the active sessions connected?  But when I close all my
> browsers and tell the WebSessionManager to removeAllSessions, the
> activeSessions remain, and yet nothing is connected...?

Active sessions are those active last hour. You can ask every session
with a method #isActive which will check the timestamp of last request.
But remember that this is only a test and nothing more, inactive
sessions are not cleaned or removed in any way!

WebSessionManager holds a dictionary of active sessions, but those are
currently just all sessions, active and inactive. This can actually be
considered now as a bug and we need to correct it.

It is a relict of the past, when Aida run on Gemstone/S (but on the
client side) and replicating session state to the database was
expensive. Active sessions were therefore the only ones replicated to
the memory while inactive ones stayed in database.

>
> It SEEMS like if you really wanted to clean up at night, you could
> remove these [activeSessions] as well?

Yes, removeAllSessions shoud remove active ones too. I just corrected
that in my image:

WebSession removeAllSessions
   self initActiveSessions


> Is this because I can't release the object created in the
> SwazooAida>>demoStart?
>
> Just trying to understand the resources created and used a little better...

And you are uncovering many things it should be cleared off many years
ago ;)

Janko

--
Janko Mivšek
AIDA/Web
Smalltalk Web Application Server
http://www.aidaweb.si
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Janko Mivšek
In reply to this post by Rob Rothwell
Rob Rothwell wrote:

> Well, something as simple as the following allows me to garbage collect
> on demand:
>
> WebSessionManager allInstancesDo: [:eachManager |
>     eachManager activeSessions copy keys do: [:key |
>         eachManager activeSessions removeKey: key]].

Even simpler would be just to call #initActiveSessions :)

> This frees up session resources and allows me to garbage collect as
> expected.  All that happens is that the user needs to actually log on
> the next time they try to navigate to the site, so I don't see any harm
> doing this during a nightly routine of some kind, and it is quite useful
> during development since I keep testing lots of pages and their
> associated resources!

But removing all sessions is not very user friendly practice because (as
you said) you logoff users too. It is better (and just good enough) to
remove only anonymous (guest) sessions but on the other hand cleanup all
presentation state by removing all Apps. And we just achieved that in a
separate mail :)

Best regards
Janko


--
Janko Mivšek
AIDA/Web
Smalltalk Web Application Server
http://www.aidaweb.si
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Rob Rothwell
In reply to this post by Stefan Schmiedl
On Sat, Jun 7, 2008 at 7:02 AM, Stefan Schmiedl <[hidden email]> wrote:
Out of curiosity: Why do you use

       activeSessions copy keys

instead of

       activeSessions keys copy

or even just

       activeSessions keys ?

I'd expect the latter to be cheaper, since you're only duplicating
the keys (if at all) and not the sessions.

Because I am new  to Smalltalk and trying desperately to make sure I don't leave anything behind!  I have had trouble learning to remove objects from collections while iterating through them and removing them at the same time...!

What you mention above is the sort of thing I WAS doing and expected to work, but I just need to learn how all these Collections work a little better.

Thank you,

Rob
 


_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Stefan Schmiedl
On Sat, 7 Jun 2008 10:04:11 -0400
"Rob Rothwell" <[hidden email]> wrote:

> On Sat, Jun 7, 2008 at 7:02 AM, Stefan Schmiedl <[hidden email]> wrote:
>
> > Out of curiosity: Why do you use
> >
> >        activeSessions copy keys
> >
> > instead of
> >
> >        activeSessions keys copy
> >
> > or even just
> >
> >        activeSessions keys ?
> >
> > I'd expect the latter to be cheaper, since you're only duplicating
> > the keys (if at all) and not the sessions.
>
>
> Because I am new  to Smalltalk and trying desperately to make sure I don't
> leave anything behind!  I have had trouble learning to remove objects from
> collections while iterating through them and removing them at the same
> time...!

Depending on what activeSessions is and how it or its method keys is
implemented, the first snippet above might even be in this category.

A "normal" shallow copy of an object allocates a new memory block
with enough room for the object's local storage, i.e. instance
variables. These are then copied over to the new place.

As instance variables typically are just references to other objects,
you end up copying references, not objects.

Time for a little experiment:

Object subclass: #Registry
        instanceVariables: 'dict'

Registry>>initialize
        dict := Dictionary new

Object subclass: #RegistryUser
        instanceVariables: 'reg'

RegistryUser>>initialize
        reg := Registry new

RegistryUser>>registry
        ^ reg

user1 := RegistryUser new reg.
user2 := RegistryUser new reg.
user3 := user1 copy.

With this setup, guess and print the results of:

        user1 = user2
        user2 = user3
        user1 = user3
        user1 == user3
        user1 registry = user2 registry
        user1 registry = user3 registry
        user1 registry == user3 registry

> What you mention above is the sort of thing I WAS doing and expected to
> work, but I just need to learn how all these Collections work a little
> better.

FWIW, I think the second snippet is the safest for removing elements
from the dictionary. Even if keys returned the "live" key sequence
instead of a copy, copying this sequence decouples it from the
dictionary. The key values themselves are probably still shared, but
since you don't modify them, it's nothing to worry about.

If in doubt, walk through questionable code with the debugger.

Have fun,
s.
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Rob Rothwell
In reply to this post by Janko Mivšek
On Sat, Jun 7, 2008 at 7:35 AM, Janko Mivšek <[hidden email]> wrote:
Even simpler would be just to call #initActiveSessions :)

Not again!!!

One of these days, I tell you, I will actually learn how to READ Smalltalk as well as write it!
 
But removing all sessions is not very user friendly practice because (as you said) you logoff users too. It is better (and just good enough) to remove only anonymous (guest) sessions but on the other hand cleanup all presentation state by removing all Apps. And we just achieved that in a separate mail :)

Thanks again for all of your help with this.  It was kind of important when using Aida as a dynamic front end data collection tool!

Rob

_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Rob Rothwell
In reply to this post by Stefan Schmiedl
On Sat, Jun 7, 2008 at 2:49 PM, Stefan Schmiedl <[hidden email]> wrote:
Depending on what activeSessions is and how it or its method keys is
implemented, the first snippet above might even be in this category.

A "normal" shallow copy of an object allocates a new memory block
with enough room for the object's local storage, i.e. instance
variables. These are then copied over to the new place.

As instance variables typically are just references to other objects,
you end up copying references, not objects.

Time for a little experiment:

Object subclass: #Registry
       instanceVariables: 'dict'

Registry>>initialize
       dict := Dictionary new

Object subclass: #RegistryUser
       instanceVariables: 'reg'

RegistryUser>>initialize
       reg := Registry new

RegistryUser>>registry
       ^ reg

user1 := RegistryUser new reg.
user2 := RegistryUser new reg.
user3 := user1 copy.

With this setup, guess and print the results of:

       user1 = user2
       user2 = user3
       user1 = user3
       user1 == user3
       user1 registry = user2 registry
       user1 registry = user3 registry
       user1 registry == user3 registry

Did you mean

user1 := RegistryUser new.  (you never defined RegistryUser>>reg; if you meant "registry", this would return a Registry)
user2 := RegistryUser new.
user3 := user1 copy.

user1 = user2.
user2 = user3.
user1 = user3.
user1 == user3.
user1 registry = user2 registry.
user1 registry = user3 registry.
user1 registry == user3 registry.

If this above is right, I would have expected user1 = user3, but I get false (hmm...).  However, user1 registry = user3 registry (which I would have expected), and user1 registry == user3 registry, which I did not expect (?)!

Rob


_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Stefan Schmiedl
On Mon, 9 Jun 2008 07:35:21 -0400
"Rob Rothwell" <[hidden email]> wrote:

> Did you mean

Sorry for not being clear and typing garbage. I wrote that mail
before I had coffee...

>
> user1 := RegistryUser new.  (you never defined RegistryUser>>reg; if you
> meant "registry", this would return a Registry)
> user2 := RegistryUser new.
> user3 := user1 copy.
>
> user1 = user2.
> user2 = user3.
> user1 = user3.
> user1 == user3.
> user1 registry = user2 registry.
> user1 registry = user3 registry.
> user1 registry == user3 registry.
>
> If this above is right, I would have expected user1 = user3, but I get false
> (hmm...).  However, user1 registry = user3 registry (which I would have
> expected), and user1 registry == user3 registry, which I did not expect (?)!

The "would have" and "did not expect" are my point.

I'd guess in your Smalltalk

  RegistryUser>>= anObject
    ^ self == anObject

and since user1 and user3 are not the same object (only
referencing the same target), they are considered not =.
And the identity of the registries follows from that.

I remember having a slight epiphany a while ago, when I realised
that "variables" in Smalltalk do *not* contain anything, but
*only* point towards objects piled up in the heap.

With this "finger pointing" in mind, my setup comes down to the
following narrative: user1 references an instance of
RegistryUser containing a reference to an instance of Registry
containing a reference to an instance of Dictionary.
In short:

user1 -> [registryUser#1](
           reg -> [registry#1](
                    dict -> [dictionary#1]
                   )
           )

user2 is basically the same, only with a complete new set of
objects:
     
user2 -> [registryUser#2](
           reg -> [registry#2](
                    dict -> [dictionary#2]
                   )
           )

Now, copy enters the stage. As shallow copy, it creates a new
instance of its receiver's class, which in turn gets initialized
with the instance variables *references* of the original:

user3 -> [registryUser#3](
           reg -> [registry#1](
                    dict -> [dictionary#1]
                   )
           )

so:     user1 = user3 not,
because [registryUser#1] == [registryUser#3] not.
However since for both users, reg -> [registry#1],
the identity user1 registry == user3 registry is explained.

If you omit "immediate" values (like sufficiently small
integers), objects are just containers for references to other
objects, hence a shallow operation like copy only copies the
structure, not the content.

Time for a small test: Explain to yourself (or to the world at
large), why I suggested "dict keys copy" instead of "dict copy
keys" in your original mail.

HTH,
s.

>
> Rob


--
Stefan Schmiedl
EDV-Beratung Schmiedl, Berghangstr. 5, D-93413 Cham
im Büro: 09971 9966 989, am Handy: 0160 9981 6278
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida
Reply | Threaded
Open this post in threaded view
|

Re: WebSessionManager>>activeSessions

Rob Rothwell
I really am reading this.  And playing with it.  Several times.  I think this is important, and I will, indeed, explain at large when I get it, which I think I will.

From this maybe I will be able to go on and finally understand deepCopy and veryDeepCopy!

Rob


On Mon, Jun 9, 2008 at 11:45 AM, Stefan Schmiedl <[hidden email]> wrote:
On Mon, 9 Jun 2008 07:35:21 -0400
"Rob Rothwell" <[hidden email]> wrote:

> Did you mean

Sorry for not being clear and typing garbage. I wrote that mail
before I had coffee...

>
> user1 := RegistryUser new.  (you never defined RegistryUser>>reg; if you
> meant "registry", this would return a Registry)
> user2 := RegistryUser new.
> user3 := user1 copy.
>
> user1 = user2.
> user2 = user3.
> user1 = user3.
> user1 == user3.
> user1 registry = user2 registry.
> user1 registry = user3 registry.
> user1 registry == user3 registry.
>
> If this above is right, I would have expected user1 = user3, but I get false
> (hmm...).  However, user1 registry = user3 registry (which I would have
> expected), and user1 registry == user3 registry, which I did not expect (?)!

The "would have" and "did not expect" are my point.

I'd guess in your Smalltalk

 RegistryUser>>= anObject
   ^ self == anObject

and since user1 and user3 are not the same object (only
referencing the same target), they are considered not =.
And the identity of the registries follows from that.

I remember having a slight epiphany a while ago, when I realised
that "variables" in Smalltalk do *not* contain anything, but
*only* point towards objects piled up in the heap.

With this "finger pointing" in mind, my setup comes down to the
following narrative: user1 references an instance of
RegistryUser containing a reference to an instance of Registry
containing a reference to an instance of Dictionary.
In short:

user1 -> [registryUser#1](
          reg -> [registry#1](
                   dict -> [dictionary#1]
                  )
          )

user2 is basically the same, only with a complete new set of
objects:

user2 -> [registryUser#2](
          reg -> [registry#2](
                   dict -> [dictionary#2]
                  )
          )

Now, copy enters the stage. As shallow copy, it creates a new
instance of its receiver's class, which in turn gets initialized
with the instance variables *references* of the original:

user3 -> [registryUser#3](
          reg -> [registry#1](
                   dict -> [dictionary#1]
                  )
          )

so:     user1 = user3 not,
because [registryUser#1] == [registryUser#3] not.
However since for both users, reg -> [registry#1],
the identity user1 registry == user3 registry is explained.

If you omit "immediate" values (like sufficiently small
integers), objects are just containers for references to other
objects, hence a shallow operation like copy only copies the
structure, not the content.

Time for a small test: Explain to yourself (or to the world at
large), why I suggested "dict keys copy" instead of "dict copy
keys" in your original mail.

HTH,
s.

>
> Rob


--
Stefan Schmiedl
EDV-Beratung Schmiedl, Berghangstr. 5, D-93413 Cham
im Büro: 09971 9966 989, am Handy: 0160 9981 6278
_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida


_______________________________________________
Aida mailing list
[hidden email]
http://lists.aidaweb.si/mailman/listinfo/aida