RE: Session Serialize code
Thanks. I'll love to see this. I'm rewriting the session serialize code as a plug-in module (that was your offer), so I need sterilization support for ServerSession. Please take care of that as fast as you can. --Shai -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Friday, December 29, 2000 06:17 To: [EMAIL PROTECTED] Subject: RE: Session Serialize code I'll check in the fix tommorow - the HttpSessionBindingEvent and session reloading should go into the facade22 module. I was thinking about this - does it make sense to keep the session code in the core ? It seems to me that maintaining an object store is orthogonal to the http functionality - all that's needed in core is management of the session IDs ( create, encode in cookies/urls, etc ) - while the actual store shouldn't be part of the core. I'll try to find a way to decouple that even more than it is today, probably that would help anyone who is working on advanced session management as it'll make it independent of tomcat ( or server container ). Costin I can't see ServerSession.writeObject (and readObject) there. You must have code which is ServerSession aware, since SeverSession member ssm (point to its manager) is not serializeable. Here is jon's original code (3.2.1): This must be fixed to be 3.3 compatible. I can do that (it's really easy), but I don't know how to handle the HttpSessionBindingEvent (in writeObject) below (It seems that ServerSession can't cast to HttpSession). Please let me know if you think this is un-needed. /** * Read a serialized version of this session object from the specified * object input stream. * p * bIMPLEMENTATION NOTE/b: The reference to the owning Manager * is not restored by this method, and must be set explicitly. * * @param stream The input stream to read from * * @exception ClassNotFoundException if an unknown class is specified * @exception IOException if an input/output error occurs */ private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException { // Deserialize the scalar instance variables (except Manager) creationTime = ((Long) stream.readObject()).longValue(); id = (String) stream.readObject(); lastAccessedTime = ((Long) stream.readObject()).longValue(); thisAccessedTime = ((Long) stream.readObject()).longValue(); maxInactiveInterval = ((Integer) stream.readObject()).intValue(); isNew = ((Boolean) stream.readObject()).booleanValue(); isValid = ((Boolean) stream.readObject()).booleanValue(); attributes = (Hashtable) stream.readObject(); } /** * Write a serialized version of this session object to the specified * object output stream. * p * bIMPLEMENTATION NOTE/b: The owning Manager will not be stored * in the serialized representation of this Session. After calling * codereadObject()/code, you must set the associated Manager * explicitly. * p * bIMPLEMENTATION NOTE/b: Any attribute that is not Serializable * will be silently ignored. If you do not want any such attributes, * be sure the codedistributable/code property of our associated * Manager is set to codetrue/code. * p * bIMPLEMENTATION NOTE/b: If we can't serialize the object stored in * the session, then check to see if it implements * HttpSessionBindingListener and then call its * valueUnbound method, allowing it to save its state * correctly instead of just being lost into the etherworld * * @param stream The output stream to write to * * @exception IOException if an input/output error occurs */ private void writeObject(ObjectOutputStream stream) throws IOException { // Write the scalar instance variables (except Manager) stream.writeObject(new Long(creationTime)); stream.writeObject(id); stream.writeObject(new Long(lastAccessedTime)); stream.writeObject(new Long(thisAccessedTime)); stream.writeObject(new Integer(maxInactiveInterval)); stream.writeObject(new Boolean(isNew)); stream.writeObject(new Boolean(isValid)); if (attributes.size() 0) { // Accumulate the names of serializable attributes Hashtable results = new Hashtable(attributes.size()); for (Enumeration e = attributes.keys(); e.hasMoreElements() ; ) { String key = (String) e.nextElement(); Object value = attributes.get(key); if (value instanceof Serializable) { results.put
Session Serialize code
Hi Costin, As discussed a week ago, someone took out Jon's code to serialize session from 3.3. That code was part of 3.2 but does not exist in 3.3. Could you please add it back into ServerSession?? As proposed by you I'm working on "SerializableSession" module, and I need that piece of code to serialize sessions. (Functions: writeObject, readObject) Thx. ____ Shai Fultheim Chief Technology Officer BRM Group E-Mail: [EMAIL PROTECTED] Mobile: 972-53-866-459 Office: 972-2-5891-459
RE: [RFC] Distributed sessions in Catalina
HI, Totally agree. I'm planning to implement session replication (for tomcat 3.3) in the following steps: 1. Having persistent session store. Letting tomcat store its session information to file and read it while coming up. Saving session will happen as soon as request will be finished. - This will let us restart tomcat without loosing sessions. 2. Let Tomcat send session information (for every request) to all other tomcat in a cluster. This will let apache (using mod_jk) to forward requests to other tomcats after finding out that the original tomcat (by jvmRoute) is not answering). - This will let us have redundancy into tomcat. Still we will need apache (mod_jk) in the picture. 3. Letting tomcat forward requests to another tomcat based on jvmRoute. - This will let us having Tomcat without Apache around. The tomcat will be load balanced using external system (Local Director?), and forward requests to the relevant instance. I have start working on that for 3.3. Do you want to combine efforts? --Shai -Original Message- From: Kief Morris [mailto:[EMAIL PROTECTED]] Sent: Sunday, December 24, 2000 22:12 To: [EMAIL PROTECTED] Subject: [RFC] Distributed sessions in Catalina Ok I'm going to share some ideas I've been mulling on this topic since it's been coming up a lot lately. Other people seem to be interested in having Tomcat natively do load balancing itself, by redirecting requests between instances in a server farm. What I'm actually more interested in getting Tomcat to work with an external load balancing mechanism, sitting in front of a farm of Tomcat instances. What I'm thinking about is a session distribution system which meets the following design objectives: DESIGN OBJECTIVES - Compliant with servlet 2.3 specification - Implement on Catalina (Tomcat 4.0) - Work with different request distribution mechanisms - Allow the implementation of different session sharing schemes It should also be noted that the objective of using a distribution scheme (a Tomcat farm) is one or both of improving performance by distributing load, and improving fault tolerance by redundancy. ASSUMPTIONS ABOUT REQUEST DISTRIBUTION MECHANISM: Working with different request distribution mechanisms means that some arbitrary system is used to distribute requests between different instances of Tomcat running on different JVMs, and potentially different systems. This may be a connector in the HTTP server, or it may be a router which is directing requests to Tomcat's HTTP port, or it may be some service built into Tomcat which forces redirects between instances. The distributed session mechanism should support any and all of these without being aware of what it is or how it works. The request distributor will not necessarily distribute all requests from a particular client to a particular Tomcat instance. If it does so consistently, session distribution isn't really needed, the standard session handling behavior of Catalina, or any servlet container, is sufficient. However, some request distributors will direct each request to an arbitrary (from our point of view) instance of Tomcat, and even those which attempt to consistently direct a particular client to the same instance may need to switch it to a different instance if the first one becomes unavailable. Therefore, the distributed session mechanism should assume that different requests in a session will be directed to arbitrary instances of Tomcat. Any instance of Tomcat should be able to handle a request itself, whether or not a session object has been created on the same or a different instance. ASSUMPTIONS ABOUT SESSION DISTRIBUTION I'm proposing a modification to Catalina to enable the implementation of different session distribution mechanisms. These session distributors may work in radically different ways. The main situations they will have to deal with are the following use cases: 1) New Session: Application requests a session, no session has been created for the current client on any Catalina instance in the farm. 2) Unknown Session: Application requests a session, a session has been created for the current client on a Catalina instance other than the one handling the current request. 3) Fresh Known Session: Application requests a session, a session has been created for the current client, and the current Catalina instance handled the previous request. 4) Stale Known Session: Application requests a session, a session has been created and handled by the current Catalina instance, but another Catalina instance has handled a request from the client in the meantime. 5) Session Invalidated: Application code calls the HttpSession.invalidate() method 6) Session Times Out: The inactivity timeout period has elapsed without a request from the client to any Catalina instance. What others are there? I haven't though fully on the consequences of calling various methods of HttpSession
[PATCH] Tomcat session replicator - Pathces for phase I
Hi, These patches will allow you to add serialize="true" to you context and having your context saved to disk. Index: src/share/org/apache/tomcat/core/Context.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java ,v retrieving revision 1.129 diff -w -u -r1.129 Context.java --- src/share/org/apache/tomcat/core/Context.java 2000/12/13 19:58:01 1.129 +++ src/share/org/apache/tomcat/core/Context.java 2000/12/24 21:20:34 @@ -81,6 +81,9 @@ * You need to set at least "path" and "base" before adding a * context to a server. You can also set any other properties. * + * Setting context's serialize attribute to true will cause it dump its + * session information to file on request end, startup and shutdown. + * * At addContext() stage log and paths will be "fixed" based on * context manager settings. * @@ -94,6 +97,7 @@ * @author Harish Prabandham * @author [EMAIL PROTECTED] * @author Gal Shachor [EMAIL PROTECTED] + * @author Shai Fultheim [[EMAIL PROTECTED]] */ public final class Context implements LogAware { // Constants @@ -172,6 +176,9 @@ // enable reloading private boolean reloadable=true; + // enable serialization + private boolean serialize = false; + // XXX Use a better repository private Hashtable attributes = new Hashtable(); @@ -558,6 +565,16 @@ return reloadable; } + public void setSerialize( boolean b ) { + serialize=b; + } + + /** Should we serialize sessions ? +*/ + public boolean getSerialize() { + return serialize; + } + // API level /** The servlet API variant that will be used for requests in this @@ -1075,4 +1092,15 @@ defaultContainer.addInterceptor(ri); } + public final String getFileName() { + return System.getProperty("tomcat.home") + "/bin/Sessions" + cleanupFileName(getPath()) + ".ses"; + } + + private String cleanupFileName(String fn) { + String f = fn; + f = f.replace('/','_'); + f = f.replace('\\','_'); + + return f; + } } Index: src/share/org/apache/tomcat/core/ContextManager.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManag er.java,v retrieving revision 1.157 diff -w -u -r1.157 ContextManager.java --- src/share/org/apache/tomcat/core/ContextManager.java2000/12/08 23:18:431.157 +++ src/share/org/apache/tomcat/core/ContextManager.java2000/12/24 21:20:37 @@ -62,6 +62,7 @@ import org.apache.tomcat.util.*; import org.apache.tomcat.util.log.*; +import org.apache.tomcat.session.ServerSession; import java.io.*; import java.net.*; import java.util.*; @@ -180,6 +181,7 @@ @author Harish Prabandham @author [EMAIL PROTECTED] @author Hans Bergsten [[EMAIL PROTECTED]] + @author Shai Fultheim [[EMAIL PROTECTED]] */ public final class ContextManager implements LogAware{ /** Official name and version @@ -713,6 +715,23 @@ for( int i=0; i reqI.length; i++ ) { reqI[i].postRequest( req, res ); } + + if ((req.getSession(false) != null) req.getContext().getSerialize()) { + Context ctx = req.getContext(); + + ServerSession ses = req.getSession(false); + + if (debug 0 ) { + log("Serializing session " + ses.getId() + + ", lasted " + (ses.getTimeStamp().getLastAccessedTime() - + ses.getTimeStamp().getCreationTime())/1000 + + " Secs."); + } + + File f = new File(ctx.getFileName()); + ses.getSessionManager().serializeSessions(f); + } + req.recycle(); res.recycle(); } Index: src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/S impleSessionStore.java,v retrieving revision 1.4 diff -w -u -r1.4 SimpleSessionStore.java --- src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java 2000/11/30 06:17:12 1.4 +++ src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java 2000/12/24 21:20:39 @@ -249,6 +249,16 @@ } sm.setMaxActiveSessions( maxActiveSessions ); + if (ctx.getSerialize()) { + String fileName = ctx.getFil
FW: [PATCH] Tomcat session replicator - Pathces for phase I
Again, with patches as attachment. --Shai -Original Message- From: Shai Fultheim (BRM IL) Sent: Sunday, December 24, 2000 23:27 To: [EMAIL PROTECTED] Subject: [PATCH] Tomcat session replicator - Pathces for phase I Hi, These patches will allow you to add serialize="true" to you context and having your context saved to disk. Index: src/share/org/apache/tomcat/core/Context.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java ,v retrieving revision 1.129 diff -w -u -r1.129 Context.java --- src/share/org/apache/tomcat/core/Context.java 2000/12/13 19:58:01 1.129 +++ src/share/org/apache/tomcat/core/Context.java 2000/12/24 21:20:34 @@ -81,6 +81,9 @@ * You need to set at least "path" and "base" before adding a * context to a server. You can also set any other properties. * + * Setting context's serialize attribute to true will cause it dump its + * session information to file on request end, startup and shutdown. + * * At addContext() stage log and paths will be "fixed" based on * context manager settings. * @@ -94,6 +97,7 @@ * @author Harish Prabandham * @author [EMAIL PROTECTED] * @author Gal Shachor [EMAIL PROTECTED] + * @author Shai Fultheim [[EMAIL PROTECTED]] */ public final class Context implements LogAware { // Constants @@ -172,6 +176,9 @@ // enable reloading private boolean reloadable=true; + // enable serialization + private boolean serialize = false; + // XXX Use a better repository private Hashtable attributes = new Hashtable(); @@ -558,6 +565,16 @@ return reloadable; } + public void setSerialize( boolean b ) { + serialize=b; + } + + /** Should we serialize sessions ? +*/ + public boolean getSerialize() { + return serialize; + } + // API level /** The servlet API variant that will be used for requests in this @@ -1075,4 +1092,15 @@ defaultContainer.addInterceptor(ri); } + public final String getFileName() { + return System.getProperty("tomcat.home") + "/bin/Sessions" + cleanupFileName(getPath()) + ".ses"; + } + + private String cleanupFileName(String fn) { + String f = fn; + f = f.replace('/','_'); + f = f.replace('\\','_'); + + return f; + } } Index: src/share/org/apache/tomcat/core/ContextManager.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManag er.java,v retrieving revision 1.157 diff -w -u -r1.157 ContextManager.java --- src/share/org/apache/tomcat/core/ContextManager.java2000/12/08 23:18:431.157 +++ src/share/org/apache/tomcat/core/ContextManager.java2000/12/24 21:20:37 @@ -62,6 +62,7 @@ import org.apache.tomcat.util.*; import org.apache.tomcat.util.log.*; +import org.apache.tomcat.session.ServerSession; import java.io.*; import java.net.*; import java.util.*; @@ -180,6 +181,7 @@ @author Harish Prabandham @author [EMAIL PROTECTED] @author Hans Bergsten [[EMAIL PROTECTED]] + @author Shai Fultheim [[EMAIL PROTECTED]] */ public final class ContextManager implements LogAware{ /** Official name and version @@ -713,6 +715,23 @@ for( int i=0; i reqI.length; i++ ) { reqI[i].postRequest( req, res ); } + + if ((req.getSession(false) != null) req.getContext().getSerialize()) { + Context ctx = req.getContext(); + + ServerSession ses = req.getSession(false); + + if (debug 0 ) { + log("Serializing session " + ses.getId() + + ", lasted " + (ses.getTimeStamp().getLastAccessedTime() - + ses.getTimeStamp().getCreationTime())/1000 + + " Secs."); + } + + File f = new File(ctx.getFileName()); + ses.getSessionManager().serializeSessions(f); + } + req.recycle(); res.recycle(); } Index: src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/S impleSessionStore.java,v retrieving revision 1.4 diff -w -u -r1.4 SimpleSessionStore.java --- src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java 2000/11/30 06:17:12 1.4 +++ src/share/org/apache/tomcat/modules/session/Simple
RE: [PATCH] Tomcat session replicator - Pathces for phase I
Where is the piece of code you have written for jserv??? --Shai -Original Message- From: Jon Stevens [mailto:[EMAIL PROTECTED]] Sent: Monday, December 25, 2000 00:47 To: [EMAIL PROTECTED] Subject: Re: [PATCH] Tomcat session replicator - Pathces for phase I on 12/24/2000 1:26 PM, "[EMAIL PROTECTED]" [EMAIL PROTECTED] wrote: + while (ids.hasMoreElements()) { +session = findSession(ids.nextElement().toString()); +if (!session.getTimeStamp().isValid()) + continue; +oStream.writeObject(session); + } + oStream.flush(); + fStream.close(); + } catch (Exception e) { + System.out.println(e); + } + } One more thing about this that you need to consider...if the object implements HttpSessionBindingListerWayToLongInterfaceName, then you should consider calling its valueUnbound() methods before doing the serialization otherwise you are not giving the object you are serializing a chance to do what it needs to do. Also, I already wrote all of this code for JServ and Tomcat 3.x and you aren't even re-using it. Sigh. love, -jon
RE: [PATCH] Tomcat session replicator - Pathces for phase I
Ahh... The patches I have sent were written originally to 3.2. Jon's code was part of 3.2 (and I have used it) but is not included in 3.3. Thanks to Jon having my attention to that. I'll fix that soon. --Shai -Original Message- From: Jon Stevens [mailto:[EMAIL PROTECTED]] Sent: Monday, December 25, 2000 01:38 To: [EMAIL PROTECTED] Subject: Re: [PATCH] Tomcat session replicator - Pathces for phase I on 12/24/2000 3:31 PM, "[EMAIL PROTECTED]" [EMAIL PROTECTED] wrote: Where is the piece of code you have written for jserv??? --Shai Now that is a really funny question. Think about it for a second. -jon
RE: [PATCH] Tomcat session replicator - Pathces for phase I
Hi, I'm not sure about that. Jon wants to override session's read/write object. He has the right code in jserv to do that. The code you are pointing to still use default read/writeobject for session which is exactly what I did. M I right? This is the right read/write object by Jon (I just ported it 5 min ago). I still have problems with HttpSessionBindingEvent constructor. Any clues will be welcome. I'll post complete patch in hours. private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException { // Read the session identifier id = (MessageBytes) stream.readObject(); // Read the other scalar instance variables ts = (TimeStamp)stream.readObject(); } private synchronized void writeObject(ObjectOutputStream stream) throws IOException { // Write the session identifier stream.writeObject(id); // Write the other scalar instance variables stream.writeObject(ts); if (attributes.size() 0) { // write out the user session data that is Serializable Hashtable saveData = new Hashtable(attributes .size()); String key = null; Object value = null; Enumeration keys = attributes .keys(); while(keys.hasMoreElements()) { key = (String) keys.nextElement(); value = attributes .get(key); if (value instanceof Serializable) { saveData.put(key, value); } // if we can't serialize the object stored in // the session, then check to see if it implements // HttpSessionBindingListener and then call its // valueUnbound method, allowing it to save its state // correctly instead of just being lost into the etherworld else if (value instanceof HttpSessionBindingListener ) { try { HttpSessionBindingListener event = (HttpSessionBindingListener) attributes .get(key); event.valueUnbound(new HttpSessionBindingEvent(this, key)); } catch (Exception e) { System .out.println(e); } } } stream.writeObject(saveData); } else { stream.writeObject(new Hashtable()); } } --Shai -Original Message- From: Nacho [mailto:[EMAIL PROTECTED]] Sent: Monday, December 25, 2000 02:07 To: '[EMAIL PROTECTED]' Subject: RE: [PATCH] Tomcat session replicator - Pathces for phase I Hola Shai: for 3.3, The code Jon points it's at org.apache.tomcat.util.ObjectSerializer and it's only used inside org.apache.tomcat.modules.session.SimpleSessionStore, reload hook. Saludos , Ignacio J. Ortega -Mensaje original- De: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Enviado el: lunes 25 de diciembre de 2000 0:32 Para: [EMAIL PROTECTED] Asunto: RE: [PATCH] Tomcat session replicator - Pathces for phase I Where is the piece of code you have written for jserv??? --Shai -Original Message- From: Jon Stevens [mailto:[EMAIL PROTECTED]] Sent: Monday, December 25, 2000 00:47 To: [EMAIL PROTECTED] Subject: Re: [PATCH] Tomcat session replicator - Pathces for phase I on 12/24/2000 1:26 PM, "[EMAIL PROTECTED]" [EMAIL PROTECTED] wrote: + while (ids.hasMoreElements()) { +session = findSession(ids.nextElement().toString()); +if (!session.getTimeStamp().isValid()) + continue; +oStream.writeObject(session); + } + oStream.flush(); + fStream.close(); + } catch (Exception e) { + System.out.println(e); + } + } One more thing about this that you need to consider...if the object implements HttpSessionBindingListerWayToLongInterfaceName, then you should consider calling its valueUnbound() methods before doing the serialization otherwise you are not giving the object you are serializing a chance to do what it needs to do. Also, I already wrote all of this code for JServ and Tomcat 3.x and you aren't even re-using it. Sigh. love, -jon
RE: [MY_OPINION] Tomcat 3.x
Hi Craig, Reading you comment below, I do agree with you that it seems there are not enough committers. I would like to offer myself as a committer (for 3.x). I have sent 2 patches till now. Theses patches deals with redundancy/load-balancing and keeping sessions after tomcat restart. Right now I'm working on a patch to send session between tomcat instances (basically give you redundancy, so in case tomcat will go down, the session will be stored in the other tomcat. Mod_jk will know to redirect requests to either tomcat instances). I'm going to have alpha version soon. I would like to help tomcat (3.0 again) to be more 'enterprise/production' league. Shai Fultheim Chief Technology Officer BRM Seed E-Mail: [EMAIL PROTECTED] Mobile: 972-53-866-459 Office: 972-2-5891-459 -Original Message- From: Craig R. McClanahan [mailto:[EMAIL PROTECTED]] Sent: Tuesday, December 19, 2000 04:01 To: [EMAIL PROTECTED] Subject: Re: [MY_OPINION] Tomcat 3.x Of course, these problems are fixable if we had more committers ... especially ones interested in applying bug fixes to the current production release to keep it stable and appropriate for production deployments. (NOTE: Anyone who receives committer status gets commit access on all branches of all the project's CVS repositories.)
RE: [PATCH] Saving sessions across tomcat instances (#1)
Agree. How do I configure wincvs to give me file with differences. How do I configure wincvs to do diff -u ? (default is -w) ? --Shai -Original Message- From: Nacho [mailto:[EMAIL PROTECTED]] Sent: Monday, December 18, 2000 16:48 To: 'tomcat-dev' Subject: RE: [PATCH] Saving sessions across tomcat instances (#1) Hola Shai: IMHO your patch very interesting, i want use it on my own ( prior to commit it after a review by people ).. In mean time, please send patches as attached files, not embedded in a message, and another silly advice, please please dont send messages in HTML, for the people that have big screens ( as i ) sending html results on a lot of glass to add to my glasses :-) Saludos , Ignacio J. Ortega -Mensaje original- De: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Enviado el: lunes 18 de diciembre de 2000 10:28 Para: [EMAIL PROTECTED] Asunto: [PATCH] Saving sessions across tomcat instances (#1) Hi all, As discussed, attached first patch to allow tomcat share session information across processes. This patch enable context to specify (by adding serialize="true") that it want to save/reload session information while restarting and going down. The session information will be stored and reloaded for temp files located at bin directory. Index: src/share/org/apache/tomcat/core/Context.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/Context. java,v retrieving revision 1.100.2.4 diff -w -u -r1.100.2.4 Context.java --- src/share/org/apache/tomcat/core/Context.java 2000/11/18 00:09:42 1.100.2.4 +++ src/share/org/apache/tomcat/core/Context.java 2000/12/18 07:11:01 @@ -97,6 +97,7 @@ * @author [EMAIL PROTECTED] * @author Gal Shachor [EMAIL PROTECTED] * @author Arieh Markel [[EMAIL PROTECTED]] + * @author Shai Fultheim [[EMAIL PROTECTED]] */ public class Context { private static StringManager sm =StringManager.getManager("org.apache.tomcat.core"); @@ -114,6 +115,7 @@ private boolean crossContext = true; private ServletLoader servletL; boolean reloadable=true; // XXX change default to false after testing + private boolean serialize = false; // Don't save session info across run. private Hashtable attributes = new Hashtable(); @@ -281,6 +283,19 @@ return reloadable; } + // -- Serializeable ? -- + public void setSerialize( String s ) { + serialize=new Boolean( s ).booleanValue(); + } + + public void setSerialize( boolean b ) { + serialize=b; + } + + public boolean getSerialize() { + return serialize; + } + // Web.xml properties public Enumeration getWelcomeFiles() { Index: src/share/org/apache/tomcat/session/StandardManager.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/session/Attic /StandardManager.java,v retrieving revision 1.11.2.1 diff -w -u -r1.11.2.1 StandardManager.java --- src/share/org/apache/tomcat/session/StandardManager.java 2000/11/18 01:33:59 1.11.2.1 +++ src/share/org/apache/tomcat/session/StandardManager.java 2000/12/18 07:11:09 @@ -64,14 +64,14 @@ package org.apache.tomcat.session; -import java.io.IOException; +import java.io.*; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.servlet.http.Cookie; import javax.servlet.http.HttpSession; import org.apache.tomcat.util.*; -import org.apache.tomcat.core.Request; +import org.apache.tomcat.core.*; /** * Standard implementation of the bManager/b interface that provides @@ -83,7 +83,7 @@ * code * lt;Manager className="org.apache.tomcat.session.StandardManager" * checkInterval="60" maxActiveSessions="-1" - * maxInactiveInterval="-1" / + * maxInactiveInterval="-1" serialize="true"/ * /code * where you can adjust the following parameters, with default values * in square brackets: @@ -97,6 +97,8 @@ * a session, or -1 for no limit. This value should be overridden from * the default session timeout specified in the web application deployment * descriptor, if any. [-1] + * libserialize/b - Allow tomcat save and reload session information + * from file over system startup. [false] * /ul * * @author Craig R. McClanahan @@ -162,9 +164,15 @@ */ private String threadName = "StandardManager"; + /** + * Contain owner's context object + */ + private Context ctx = null; + // - Constructor - public StandardManager() { + public StandardManager(Context ctx) { + this.ctx = ctx; } // - Properties @@ -378,6 +386,14 @@ session.setMaxInactiveInterval(this.maxInactiveInterval); session.setId(SessionUtil.generateSessionId(jsIdent)); + if (ctx.getDebug() 10) { + HttpSession Sessions[] =
[PATCH] Saving sessions across tomcat instances (#1)
Hi all, As discussed, attached first patch to allow tomcat share session information across processes. This patch enable context to specify (by adding serialize=true) that it want to save/reload session information while restarting and going down. The session information will be stored and reloaded for temp files located at bin directory. Index: src/share/org/apache/tomcat/core/Context.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v retrieving revision 1.100.2.4 diff -w -u -r1.100.2.4 Context.java --- src/share/org/apache/tomcat/core/Context.java 2000/11/18 00:09:42 1.100.2.4 +++ src/share/org/apache/tomcat/core/Context.java 2000/12/18 07:11:01 @@ -97,6 +97,7 @@ * @author [EMAIL PROTECTED] * @author Gal Shachor [EMAIL PROTECTED] * @author Arieh Markel [[EMAIL PROTECTED]] + * @author Shai Fultheim [[EMAIL PROTECTED]] */ public class Context { private static StringManager sm =StringManager.getManager(org.apache.tomcat.core); @@ -114,6 +115,7 @@ private boolean crossContext = true; private ServletLoader servletL; boolean reloadable=true; // XXX change default to false after testing + private boolean serialize = false; // Don't save session info across run. private Hashtable attributes = new Hashtable(); @@ -281,6 +283,19 @@ return reloadable; } + // -- Serializeable ? -- + public void setSerialize( String s ) { + serialize=new Boolean( s ).booleanValue(); + } + + public void setSerialize( boolean b ) { + serialize=b; + } + + public boolean getSerialize() { + return serialize; + } + // Web.xml properties public Enumeration getWelcomeFiles() { Index: src/share/org/apache/tomcat/session/StandardManager.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/session/Attic/StandardManager.java,v retrieving revision 1.11.2.1 diff -w -u -r1.11.2.1 StandardManager.java --- src/share/org/apache/tomcat/session/StandardManager.java 2000/11/18 01:33:59 1.11.2.1 +++ src/share/org/apache/tomcat/session/StandardManager.java 2000/12/18 07:11:09 @@ -64,14 +64,14 @@ package org.apache.tomcat.session; -import java.io.IOException; +import java.io.*; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.servlet.http.Cookie; import javax.servlet.http.HttpSession; import org.apache.tomcat.util.*; -import org.apache.tomcat.core.Request; +import org.apache.tomcat.core.*; /** * Standard implementation of the bManager/b interface that provides @@ -83,7 +83,7 @@ * code * lt;Manager className=org.apache.tomcat.session.StandardManager * checkInterval=60 maxActiveSessions=-1 - * maxInactiveInterval=-1 / + * maxInactiveInterval=-1 serialize=true/ * /code * where you can adjust the following parameters, with default values * in square brackets: @@ -97,6 +97,8 @@ * a session, or -1 for no limit. This value should be overridden from * the default session timeout specified in the web application deployment * descriptor, if any. [-1] + * libserialize/b - Allow tomcat save and reload session information + * from file over system startup. [false] * /ul * * @author Craig R. McClanahan @@ -162,9 +164,15 @@ */ private String threadName = StandardManager; + /** + * Contain owner's context object + */ + private Context ctx = null; + // - Constructor - public StandardManager() { + public StandardManager(Context ctx) { + this.ctx = ctx; } // - Properties @@ -378,6 +386,14 @@ session.setMaxInactiveInterval(this.maxInactiveInterval); session.setId(SessionUtil.generateSessionId(jsIdent)); + if (ctx.getDebug() 10) { + HttpSession Sessions[] = findSessions(); + ctx.log(ctx.toString() + Sessions: + Sessions.length); + for(int i=0; iSessions.length; i++) { + ctx.log( + i + : + Sessions[i].getId()); + } + } + return (session); } @@ -398,7 +414,39 @@ public void start() { // Start the background reaper thread threadStart(); + + if (ctx.getSerialize()) { + FileInputStream Stream = null; + try { + Stream = new FileInputStream(getFileName()); + ObjectInputStream ObjStream = new ObjectInputStream(Stream); + + + StandardSession session = null; + do { + session = (StandardSession)ObjStream.readObject(); + if (session != null) + add(session); + } while (session != null); + + } catch (java.io.FileNotFoundException f) { + ; + } catch (java.io.EOFException eof) { + if (findSessions().length 0) { + ctx.log(Reloaded + findSessions().length + Sessions from: + getFileName()); + if (ctx.getDebug() 10) printSessions(); + } + + try
Saving sessions across tomcat instances
Hi all, Im wondering whether tomcat can store session information in different tomcat instance? IMHO the answer is NO. Therefore I would like to share my thought on: Saving sessions across tomcat instances. A month ago I have posted patch to allow tomcat load balancing when working with no cookies. This patch is the basic block to my thoughts on creating infrastructure to allow moving the session object between tomcat instances. The patch I posted added the tomcat name (jvmRoute) to the sessionID, so if you are working with load balancing configuration you should see the tomcat name appear at the end of the seesionID. Mod_jk (and jserv) use this trail to forward the request to the right tomcat instance. Allowing tomcat to replicate its session to another tomcat will allow real Tomcat redundancy and high-availability. My thoughts are to build the system in the following steps: SessionManager to support dump and restore. SessionManager will dump its session into file while taking tomcat down. (Finalize ?? or SessionSerializer) Arrange SessionManager to restore its sessions while coming up. (Constructor ?? or SessionSerializer) SessionManager to support merge. Allow SessionManager to merge its sessions store with another store got from outside. This will allow one SessionManager to send its sessions to another SessionManager periodically. This will be done by extending the cleanup process to send all sessions to the other Tomcat. Periodic run intervals will come from configuration file. Sending only new session to other tomcat The periodic process will send to other tomcat only session created/touched from last run. This will be done for session that access time is newer than the last cleanup run, and older than request processing period, lets say 3 seconds (to make sure the servlet is not changing the object now). Time variables will come from configuration file. Read replication configuration from configuration file. Allow to define which tomcat sends session information to which tomcat. Configure mod_jk to send requests to second tomcat if first one is not responding. Im going to implement this against tomcat 3.3 (checking out Jakarta-tomcat, not tomcat_32 from CVS. Am I right? Or there is tag for 33?) I would like to get you thoughts whether this is required or not, any implementation hints, or any other requests before Im getting into implementing this. Please let me know what you think. Shai Fultheim Chief Technology Officer BRM Seed E-Mail: [EMAIL PROTECTED] Mobile: 972-53-866-459 Office: 972-2-5891-459
Servlet Engine performance comparison
Hi all, Im looking for a paper comparing different servlet engine from various perspective, especially performance. (I would like 2 c tomcat there). Does anyone know something I should look on? How is tomcat performance compared to other leading open-source or commercial servlet engines (what about robustness, platform support?). Any resource will be welcome. Shai Fultheim Chief Technology Officer BRM Seed E-Mail: [EMAIL PROTECTED] Mobile: 972-53-866-459 Office: 972-2-5891-459
sessionID within URL and loadbalance (was: WAP and sessionIDs)
Hi all, The patch below fix a bug that didnt let tomcat to run in loadbalance configuration, while having the session managed only in URL. The mail problem with load balancing is that the jvmRoute param (which is the tomcat name as known from apache side) must be added to the session (ie. Assuming the sessionid was xxx it have to be changed to xxx.t1 assuming that t1 is the name of that tomcat instance). Now, tomcat handle jvmRoute at his side by adding that parameter to the jsessionid cookie. THIS IS A BUG, since encode URL still use the original sessionID (without the .jvmRoute). In order to fix that sessionID must be changed so it contains jvmRoute (assuming we have it). Please see the code fix below. Please approve this (and merge with the code ASAP), since cellular phones, which use WAP (and does not support cookies) cant work with loadbalnce configuration of apache+tomcat. Thanks in advance. --Shai Fultheim. Shai Fultheim Chief Technology Officer BRM Seed E-Mail: [EMAIL PROTECTED] Mobile: 972-53-866-459 Office: 972-2-5891-459 Index: tomcat/request/SessionInterceptor.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/request/SessionInterceptor.java,v retrieving revision 1.24.2.2 diff -u -w -r1.24.2.2 SessionInterceptor.java --- tomcat/request/SessionInterceptor.java 2000/11/11 02:07:02 1.24.2.2 +++ tomcat/request/SessionInterceptor.java 2000/11/15 22:44:05 @@ -75,6 +75,7 @@ * This implementation only handles Cookies sessions, please extend or * add new interceptors for other methods. * + * @author Shai Fultheim [[EMAIL PROTECTED]] Session contains jsIdent */ public class SessionInterceptor extends BaseInterceptor { @@ -112,8 +113,6 @@ if ((foundAt=uri.indexOf(sig))!=-1){ sessionId=uri.substring(foundAt+sig.length()); - // I hope the optimizer does it's job:-) - sessionId = fixSessionId( request, sessionId ); // rewrite URL, do I need to do anything more? request.setRequestURI(uri.substring(0, foundAt)); @@ -126,24 +125,6 @@ return 0; } - /** Fix the session id. If the session is not valid return null. - * It will also clean up the session from load-balancing strings. - * @return sessionId, or null if not valid - */ - private String fixSessionId(Request request, String sessionId){ - // GS, We piggyback the JVM id on top of the session cookie - // Separate them ... - - if( debug0 ) cm.log( Orig sessionId + sessionId ); - if (null != sessionId) { - int idex = sessionId.lastIndexOf(SESSIONID_ROUTE_SEP); - if(idex 0) { - sessionId = sessionId.substring(0, idex); - } - } - return sessionId; - } - public int beforeBody( Request rrequest, Response response ) { String reqSessionId = response.getSessionId(); if( debug0 ) cm.log(Before Body + reqSessionId ); @@ -159,11 +140,6 @@ sessionPath = /; } - // GS, piggyback the jvm route on the session id. - String jvmRoute = rrequest.getJvmRoute(); - if(null != jvmRoute) { - reqSessionId = reqSessionId + SESSIONID_ROUTE_SEP + jvmRoute; - } Cookie cookie = new Cookie(JSESSIONID, reqSessionId); Index: tomcat/session/StandardManager.java === RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/session/Attic/StandardManager.java,v retrieving revision 1.11 diff -u -w -r1.11 StandardManager.java --- tomcat/session/StandardManager.java 2000/06/18 20:14:13 1.11 +++ tomcat/session/StandardManager.java 2000/11/15 22:44:06 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/session/Attic/StandardManager.java,v 1.11 2000/06/18 20:14:13 jon Exp $ + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/session/Attic/StandardManager.java,v 1.11 2000/06/18 20:14:13 jon Exp $ * $Revision: 1.11 $ * $Date: 2000/06/18 20:14:13 $ * @@ -102,6 +102,7 @@ * @author Craig R. McClanahan * @author [EMAIL PROTECTED] * @author a href=mailto:[EMAIL PROTECTED]Jon S. Stevens/a + * @author Shai Fultheim [[EMAIL PROTECTED]] Get jsIdent * @version $Revision: 1.11 $ $Date: 2000/06/18 20:14:13 $ */ public final class StandardManager implements Runnable { @@ -351,7 +352,7 @@ * @exception IllegalStateException if a new session cannot be * instantiated for any reason */ - public HttpSession getNewSession() { + public HttpSession getNewSession(String jsIdent) { if ((maxActiveSessions = 0) (sessions.size() = maxActiveSessions)) @@ -375,7 +376,7 @@ session.setValid(true); session.setCreationTime(System.currentTimeMillis()); session.setMaxInactiveInterval(this.maxInactiveInterval); - session.setId(SessionUtil.generateSessionId()); + session.setId(SessionUtil.generateSessionId(jsIdent)); return (session); } Index: tomcat/session/StandardSessionInterceptor.java
RE: Ready for 3.2b7?
Hi, I have posted bug fix to TC load balancing when using URL-only sessionID (both mod_jk and mod_jserv). I have received no answer. The fix is for 3.2b6. R u going to include this? This fix bug #328, and let tomcat to serve applications that can't use cookies (like cellular phones - WAP). My original mail attached below. --Shai -Original Message- From: Craig R. McClanahan [mailto:[EMAIL PROTECTED]] Sent: Friday, November 10, 2000 19:51 To: [EMAIL PROTECTED] Subject: Ready for 3.2b7? It's been a week now, and I've committed 20 patches to the 3.2 tree, ranging from simple tweaks to security problems to spec compliance bugs. I believe that I've gotten all of the critical bug reports submitted on the mailing lists or via BugRat. Does anyone know of any I've missed (see below for one issue I know is outstanding)? What I'd like to do is build a "beta 7" release this afternoon and post it. That will give people a chance to pound on it. Any critical bugs we find will need to be fixed, but we need to hold off on changing non-essential stuff so we can get a final 3.2 release out the door. NOTE: One issue that's been discussed in the last couple of days is problems supporting the "load balancing" feature for root webapps. I haven't seen a proposed patch for this, but understand from the comments of people that have tried kludges to work around it -- and it seems unreasonable to risk destabilizing things at this late date. I suggest that any work on fixing this problem be deferred to a post-3.2-final maintenance cycle. Craig McClanahan PS: Thanks to everyone for all the bug reports, and to Larry and Nacho for chipping in on the commits! PPS: When the 3.2 final release is completed, my personal focus is going to return to the Tomcat 4.0 code base (which does not suffer from any of the bugs patched in 3.2, although I did find one 4.0 bug along the way :-). If and when bugs show up in 3.2 final, I will be happy to commit patches that people supply -- but any big debugging effort or major new work on the 3.x track will need to be done by someone else. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] Hi all, While developing Tomcat based application for mobile phone, I have found out that the lack of cookies support in WAP phones, will not let me run my servlets on Tomcat load balance configuration. In order to point Apache to two tomcats, I needed the apache to use the jvmRoute section in the cookie to route the requests back to the original Tomcat (using mod_jk). Since the urls in the wml has written using the encodeurl function that does not support adding the '.jvmRoute' to the url, the followed requests come from the user without specifying the origin Tomcat (since there are no cookies). In order to fix that I have written RequestInterceptor to allow URL session support to work with multiple Tomcat configuration. To use that you must REPLACE the SessionInterceptor with the new interceptor. Here is that part of server.xml: !-- Commented out by Shai Fultheim to enable url session interceptor. RequestInterceptor className="org.apache.tomcat.request.SessionInterceptor" / -- RequestInterceptor className="org.apache.tomcat.session.URLSessionInterceptor" debug="1" / The interceptor is part of session package in order to use the (StandartSession.)encodeUrl. The interceptor source file attached. Source Code below: /* * * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *notice, this list of conditions and the following disclaimer in *the documentation and/or other materials provided with the *distribution. * * 3. The end-user documentation included with the redistribution, if *any, must include the following acknowlegement: * "This product includes software developed by the *Apache Software Foundation (http://www.apache.org/)." *Alternately, this acknowlegement may appear in the software itself, *if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software *Foundation" must not be used to endorse or promote products derived *from this software without prior written pe
Tomcat and WAP phones
Hi all, While developing Tomcat based application for mobile phone, I have found out that the lack of cookies support in WAP phones, will not let me run my servlets on Tomcat load balance configuration. In order to point Apache to two tomcats, I needed the apache to use the jvmRoute section in the cookie to route the requests back to the original Tomcat (using mod_jk). Since the urls in the wml has written using the encodeurl function that does not support adding the .jvmRoute to the url, the followed requests come from the user without specifying the origin Tomcat (since there are no cookies). In order to fix that I have written RequestInterceptor to allow URL session support to work with multiple Tomcat configuration. To use that you must REPLACE the SessionInterceptor with the new interceptor. Here is that part of server.xml: !-- Commented out by Shai Fultheim to enable url session interceptor. RequestInterceptor className=org.apache.tomcat.request.SessionInterceptor / -- RequestInterceptor className=org.apache.tomcat.session.URLSessionInterceptor debug=1 / The interceptor is part of session package in order to use the (StandartSession.)encodeUrl. The interceptor source file attached. Source Code below: /* * * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * This product includes software developed by the * Apache Software Foundation (http://www.apache.org/). * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names The Jakarta Project, Tomcat, and Apache Software * Foundation must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called Apache * nor may Apache appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * http://www.apache.org/. * * [Additional notices, if required by prior licensing conditions] * */ /* * This Interceptor written by Shai Fultheim, [EMAIL PROTECTED] * * Being used to rewrite the sessionID to include JVM ID(jvmRoute). * This will allow (Response.)encodeUrl to work in multi tomcats * configuration. * * The class is part of session package in order to use the * (StandartSession.)encodeUrl. * * All changes to: Shai Fultheim, [EMAIL PROTECTED] */ package org.apache.tomcat.session; import org.apache.tomcat.core.*; public class URLSessionInterceptor extends BaseInterceptor { // Separates the session id from the jvm route static final char SESSIONID_ROUTE_SEP = '.'; ContextManager cm; int manager_note; public URLSessionInterceptor() { } // Called on init. Takes the context manager (used for logging) and // the standardManager address. public void engineInit( ContextManager cm ) throws TomcatException { this.cm = cm; // set-up a per/container note for StandardManager manager_note = cm.getNoteId(ContextManager.CONTAINER_NOTE, tomcat.standardManager); if ( debug 0 ) cm.log