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

Reply via email to