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