geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dain Sundstrom <d...@iq80.com>
Subject Re: Session API, was: heads up: initial contribution of a client API to session state management for OpenEJB, ServiceMix, Lingo and Tuscany
Date Fri, 03 Mar 2006 02:17:39 GMT
On Mar 1, 2006, at 11:54 PM, Greg Wilkins wrote:

> Dain Sundstrom wrote:
>>>   + 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.

This is a tradeoff decision.  If we (the community), really thinks  
having the ability to handle this undeploy situation is wroth the  
complexity in the API then we add it.

My personal opinion is we don't need this and I think it would be  
super complex to implement.  I think it would require all servers  
deciding to remove an application at once.

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

I think these are two different sessions.  To me a session is a  
bucket of data for a single client, and that bucket can't be split.   
You do bring up a good point though.  We need a way to make sure that  
when you are in a session on one server and pass invoke an ejb on  
another server that we do not use the same ID for the sessions.

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

That is how I was thinking it would be done.

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

Sounds good.  Can you propose some specific APIs?  Also a little spec  
on what the apis are supposed to do would really help.  I know this  
stuff can quickly go into the "gray area" :)

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

getSession

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

The getSession call is what grabs the lock.  As long as you have a  
Session object you are considered to be working with it.

Not sure what you want changed.  Can you be more specific?

> 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();

If you want to replication individual session entries (like most  
clusters do).  You will have to keep your entries at the flat level  
like this:

         SessionLocation location = locator.getSessionLocation(id);
         Session session = location.getSession();
         Object value = session.getState("web:/context-" + name);
         mutate(value);
         session.getState("web:/context-" + name, value);
         session.release();

This should be natural to users of the API that are have used the  
http session api.  One of the goals was to keep the learning curve low.

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

<See above>

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

I agree, I just want to discuss the changes first as this API will be  
core to several projects, I think it is critical that we review and  
then commit.

-dain

Mime
View raw message