geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Wilkins <gr...@mortbay.com>
Subject Session API, was: heads up: initial contribution of a client API to session state management for OpenEJB, ServiceMix, Lingo and Tuscany
Date Thu, 02 Mar 2006 07:54:50 GMT
Dain Sundstrom wrote:
> Wow, this is a lot to digest.  I'll attempt, but we may want to deal 
> with these one by one...

Sorry about the length, but I'll try narrow this response....




>>   + Does session ID x exist for context y
> 
> In this case, I would say you lookup the session "x" and then see if  it
> has an entry for context "y"

This may work and is what I meant by "deep structure", but I 
have concerns about passivation and different types of session (see below).


>>   + passivate ALL sessions (suspending node)
>  
> That would happen under the covers of the session API (i.e., 
> implementation specific)

So if web container wants to undeploy a single context
how does it passivate just one context in the map of maps?
or how does the implementation know that it should passivate
that?

I guess the implementation could not passivate anything
until all contexts are undeployed.  But I'm still not sure
how the web container tells the implementation that is undeploying
sessions, but wants the contents saved for a later redeploy?

I'm not overly concerned about this as (un)deployment is
something that is going to involve more than just the 
session manager - but I still think a standard API for
it would be good.


>> Now the above could be modelled with deep structure for the
>> state associated with an ID, but not if all state for an ID
>> has to be in one location.
> 
> Having all of the state for a single session located on a single 
> machine is a design assumption.  We felt that if you wanted to let  the
> data be divided across several machines it was not a single  session
> session.

But it is a common deployment to have the EJB on a different
server to the web contexts ( I know it is not optimal )

If the session beans are going to be keyed under the same
session id, then the one location does not work.

If that's not a concern having the session ID map to
a map of context to session is good for the web
tier (aside from passivation concern).





>> Session Management
>> ==================
>> There is nothing in the API to help with session management.
>> Specifically:
>>
>>  + last access time
>>  + access session (without actually modify state)
>>  + invalidate session
>>  + session timeouts
>>  + session events (eg session invalidation, passivation etc.)
> 
> 
> Other than last access time, I would classify this as implementation 
> specific.  The goal was to create a very very simply API that  OpenEJB,
> ServiceMix, Lingo, Tuscany and web containers could use  without haveing
> to know the internal details of the implementation.   Does you code
> specifically need this or it is a nice to have?  If it  is the former,
> can you be a lot more specic on what the terms above  mean (I'm not a
> web expert) :)

These are all MUSTs as they are part of the servlet spec.

Traditionally when clustering http sessions, it is the last access
time that is the big PITA.  It is updated on every request even if
it does not ask for the session object.   I guess the access time could
be updated by a call to getSessionLocation, but that could make
management difficult.   Note that you don't want to put 
access time in with the other state, else you end up replicating
the whole session state on every request.


The spec also requires that a session timeout be set in the
web.xml and via the HttpSession API for an individual session.
So my session manager will need a way to pass that to the 
implementation.


Finally if the impl decides to passivate a session (for 
any number of reasons) then HttpSessionActivationListeners must
be notified.

So if I'm to write a SessionManager that just uses this
API, then it needs something for all of the above.





>> Locking
>> =======
>> I'm also not sure about the semantics of release().   If I'm
>> writing a session manager, I'm not sure if I should be making
>> the decision of when to release - that is very much implementation
>> dependent.  Some will replicate/sync on a setState, others will
>> do it at the end of every request, other will do it every n seconds
>> others will do it when the session is idle (has no requests).
>>
>> Instead of commanding "release", perhaps the API should allow
>> the concept of a thread entering and existing a session scope:
>>
>>   runInSessionScope(Runnable doSomething
>>
>> or
>>
>>   enterSessionScope()
>>   leaveSessionScope()
>>
>> individual implementations can decide what locking they
>> implement behind the scenes.
> 
> 
> That is exactly how the API works.  When you start using a session  you
> need to acquire it using the Locator and when you are done using  it,
> you release it.  This is reference counting, and when the count  reaches
> zero we are in a stable state and can replicate.  Here is a  test case
> that shows normal usage:
> 
> http://svn.apache.org/repos/asf/geronimo/trunk/modules/session/src/
> test/org/apache/geronimo/session/SessionTest.java

OK - but when does the reference get incremented?   getSessionLocation,
getSession or add/remove/get state?

As a servlet request will update state (access time) simply by
having the session ID, I think it would be good to have an explicit
call to take the lock (or the runnable style).



I've thought of something else related to this - I see that
the API allows a value to be mutable after a call to 
addState or getState

ie if the value is changed after the call to addState, but before 
the release, is the new value the one persisted/replicated/etc.

This is mostly good - except that it will make it very
difficult to have an efficient implementation.  Many
current web clustering solutions work with the convention
that unless setAttribute is called, then state is not
persisted/replicated/etc.  They effectively make setAttribute
pass by value.

The reason for this is that most seasons are read mostly
and most requests will just do the equivalent of:

        SessionLocation location = locator.getSessionLocation(id);
        Session session = location.getSession();
        Map state = (Map) session.getState("web:/context");
        Object value=state.get(name);
        session.release();

But the session impl will not know if any modification has
been done between the getState and the session.release(). So
on every release, the entire session must be compared to a saved
version of it's previous value and if differences are found then
the session is persisted/replicated/etc.

So this API cannot support the conventional solution of
using HttpSession.setAttribute to signal a modificaton.

If the API had an acquire(boolean forUpdate) method, then
this signalling could be done.

Also, it will be difficult to implement an incremental 
implementation that just persists/replicates the one attribute 
that has been changed, as the deep structure hides access to
individual attributes.





>> Policy
>> ======

I'll answer policy in a separate email.


>> positive suggestions is if I try to use the jetty6 module to
>> implement a session manager based on this API and then make changes
>> to make it work.
> 
> I would prefer that we discuss the API changes first.  There are many 
> uses for this API and I want to keep them simple and avoid making  them
> to servlet centric.  

Sure - I'm just saying that instead of trying to design perfection
in a vacuum, I'll start writing a session manager that uses the API
and that will help find problems and try alternate solutions.

The API is close enough that the core functionality of web sessions is
going to work, so it is worth starting using it I think.


cheers




Mime
View raw message