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
