billbarker 2002/08/20 21:11:56
Modified: src/share/org/apache/tomcat/modules/session
SimpleSessionStore.java
Log:
Support for saving session on Context reloading.
This version maximizes code re-use, at the expense of a some-what dirty lifecycle.
However, since the current implementation notifies lifecycle events from the Facade,
it is still valid from the point of view of the Servlet Spec.
Reported By: Hugh J.L. [EMAIL PROTECTED]
Revision Changes Path
1.20 +100 -38
jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java
Index: SimpleSessionStore.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- SimpleSessionStore.java 3 Apr 2002 00:02:14 -0000 1.19
+++ SimpleSessionStore.java 21 Aug 2002 04:11:56 -0000 1.20
@@ -88,6 +88,7 @@
int maxActiveSessions = -1;
int size=16;
int max=256;
+ static final String SESSIONS_RELOAD = "tomcat.sessions.reload";
public SimpleSessionStore() {
}
@@ -114,56 +115,84 @@
}
- public void reload( Request req, Context ctx ) throws TomcatException {
- ClassLoader newLoader = ctx.getClassLoader();
- SimpleSessionManager sM = getManager( ctx );
+ public void copyContext(Request req, Context oldC, Context newC)
+ throws TomcatException {
+ contextInit(newC);
+ ClassLoader oldLoader = oldC.getClassLoader();
+ SimpleSessionManager sM = getManager( oldC );
+ SimpleSessionManager sMnew = getManager( newC );
// remove all non-serializable objects from session
Enumeration sessionEnum=sM.getSessions();
while( sessionEnum.hasMoreElements() ) {
ServerSession session = (ServerSession)sessionEnum.nextElement();
-
- ClassLoader oldLoader=(ClassLoader)ctx.getContainer().
- getNote("oldLoader");
-
- Hashtable newSession=new Hashtable();
+ ServerSession newS = sMnew.cloneSession(req, newC,
+ session.getId().toString());
Enumeration e = session.getAttributeNames();
- while( e.hasMoreElements() ) {
+ while( e.hasMoreElements() ) {
String key = (String) e.nextElement();
Object value = session.getAttribute(key);
-
- if( value.getClass().getClassLoader() != oldLoader ) {
- // it's loaded by the parent loader, no need to reload
- newSession.put( key, value );
- } else if ( value instanceof Serializable ) {
- Object newValue =
- ObjectSerializer.doSerialization( newLoader,
- value);
- newSession.put( key, newValue );
- }
- }
- // Remove all objects we know how to handle
- e=newSession.keys();
- while( e.hasMoreElements() ) {
- String key = (String) e.nextElement();
- session.removeAttribute(key);
+ newS.setAttribute(key, value);
}
+ }
+ newC.getContainer().setNote(SESSIONS_RELOAD, req);
+ }
- if( debug > 0 ) log("Prepare for reloading, SUSPEND " + session );
- // If anyone can save the rest of the attributes or at least notify
- // the owner...
- session.setState( ServerSession.STATE_SUSPEND, req );
+ private void processSession(ServerSession session,
+ ClassLoader oldCL, ClassLoader newCL)
+ throws TomcatException {
+
+ Hashtable newSession=new Hashtable();
+ Enumeration e = session.getAttributeNames();
+ while( e.hasMoreElements() ) {
+ String key = (String) e.nextElement();
+ Object value = session.getAttribute(key);
+ if( value.getClass().getClassLoader() != oldCL ) {
+ // it's loaded by the parent loader, no need to reload
+ newSession.put( key, value );
+ } else if ( value instanceof Serializable ) {
+ Object newValue =
+ ObjectSerializer.doSerialization( newCL,
+ value);
+ newSession.put( key, newValue );
+ }
+ }
+ // If saving back to the same session.
+ // Remove all objects we know how to handle
+ e=newSession.keys();
+ while( e.hasMoreElements() ) {
+ String key = (String) e.nextElement();
+ session.removeAttribute(key);
+ }
+
+ if( debug > 0 ) log("Prepare for reloading, SUSPEND " + session );
+ // If anyone can save the rest of the attributes or at least notify
+ // the owner...
+ session.setState( ServerSession.STATE_SUSPEND, null );
- if( debug > 0 ) log("After reloading, RESTORED " + session );
- session.setState( ServerSession.STATE_RESTORED, req );
+ if( debug > 0 ) log("After reloading, RESTORED " + session );
+ session.setState( ServerSession.STATE_RESTORED, null );
- /* now put back all attributs */
- e=newSession.keys();
- while(e.hasMoreElements() ) {
- String key = (String) e.nextElement();
- Object value=newSession.get(key );
- session.setAttribute( key, value );
- }
+ /* now put back all attributes */
+ e=newSession.keys();
+ while(e.hasMoreElements() ) {
+ String key = (String) e.nextElement();
+ Object value=newSession.get(key );
+ session.setAttribute( key, value );
+ }
+ }
+
+ public void reload( Request req, Context ctx ) throws TomcatException {
+ ClassLoader newLoader = ctx.getClassLoader();
+ ClassLoader oldLoader=(ClassLoader)ctx.getContainer().
+ getNote("oldLoader");
+ SimpleSessionManager sM = getManager( ctx );
+
+ // remove all non-serializable objects from session
+ Enumeration sessionEnum=sM.getSessions();
+ while( sessionEnum.hasMoreElements() ) {
+ ServerSession session = (ServerSession)sessionEnum.nextElement();
+ processSession(session, oldLoader, newLoader);
}
}
@@ -212,6 +241,13 @@
sm.setModule( this );
ctx.getContainer().setNote( manager_note, sm );
}
+ if(ctx.getContainer().getNote(SESSIONS_RELOAD) != null ) {
+ Request req = (Request)ctx.getContainer().getNote(SESSIONS_RELOAD);
+ reload(req, ctx);
+ // Dump for GC.
+ ctx.getContainer().setNote(SESSIONS_RELOAD,null);
+ }
+
}
/** Notification of context shutdown.
@@ -277,6 +313,7 @@
return sM.findSession( sessionId );
}
+
// -------------------- Internal methods --------------------
@@ -380,6 +417,31 @@
oldS.setState( ServerSession.STATE_EXPIRED );
oldS.recycle();
}
+ sessions.put( newId, session );
+ return (session);
+ }
+ public ServerSession cloneSession(Request req, Context ctx, String oldS) {
+ // Recycle or create a Session instance
+ ServerSession session = (ServerSession)recycled.get();
+ if (session == null) {
+ session = ctx.getContextManager().createServerSession();
+ session.setManager( this );
+ session.setDebug( debug );
+ }
+ session.setContext( ctx );
+
+ session.setState( ServerSession.STATE_NEW, req );
+
+ session.getId().setString(oldS);
+
+ // The id will be set by one of the modules
+ String newId=session.getId().toString();
+
+//XXXXX - the following is a temporary fix only! Underlying problem
+// is: Why is the newId==null?
+
+ newId=(newId==null)?"null":newId;
+
sessions.put( newId, session );
return (session);
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>