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 <b>Manager</b> interface that
provides @@ -83,7 +83,7 @@ *
<code> * <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] + * <li><b>serialize</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; i<Sessions.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
{ + Stream.close(); + }
catch (Exception e) { + ; + } + }
catch (Exception e) { + System.out.println(e); } + } + } /** @@ -414,6 +462,7 @@ // Stop the background
reaper thread threadStop(); + if
(!ctx.getSerialize()) { // Expire all active
sessions HttpSession sessions[]
= findSessions(); for (int i = 0; i <
sessions.length; i++) { @@ -423,7 +472,31 @@ session.expire(); } + }
else { + HttpSession
Sessions[] = findSessions(); + if(Sessions.length
> 0) { + ctx.log("Storing
" + findSessions().length + " Sessions to: " + getFileName()); + if
(ctx.getDebug() > 10) printSessions(); + try
{ + FileOutputStream
Stream = new FileOutputStream(getFileName()); + ObjectOutputStream
ObjStream = new ObjectOutputStream(Stream); + + //
Serialize to file all active session and expire them + for
(int i = 0; i < Sessions.length; i++) { + StandardSession
session = (StandardSession) Sessions[i]; + if
(!session.isValid()) + continue; + ObjStream.writeObject(session); + session.expire(); + } + ObjStream.flush(); + Stream.close(); + }
catch (Exception e) { + System.out.println(e); + } } + } + } //
-------------------------------------------------------- Package Methods /** @@ -551,4 +624,23 @@ } +
private String getFileName() { + return
System.getProperty("tomcat.home") + "/bin/Sessions" +
cleanupFileName(ctx.getPath()) + ".ses"; +
} + +
private String cleanupFileName(String fn) { + String
f = fn; + f
= f.replace('/','_'); + f
= f.replace('\\','_'); + + return
f; + } + + private
void printSessions() { + HttpSession
Sessions[] = findSessions(); + ctx.log(ctx.toString()
+ " Sessions: " + Sessions.length); + for(int
i=0; i<Sessions.length; i++) { + ctx.log(" " + i + ": " +
Sessions[i].getId()); + } + } } Index:
src/share/org/apache/tomcat/session/StandardSessionInterceptor.java =================================================================== RCS file: /home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/session/Attic/StandardSessionInterceptor.java,v retrieving revision 1.5.2.3 diff -w -u -r1.5.2.3 StandardSessionInterceptor.java ---
src/share/org/apache/tomcat/session/StandardSessionInterceptor.java 2000/11/18 01:33:59 1.5.2.3 +++ src/share/org/apache/tomcat/session/StandardSessionInterceptor.java 2000/12/18 07:11:10 @@ -207,7 +207,7 @@ StandardManager sm=
getManager( ctx ); if( sm == null ) { - sm=new StandardManager(); + sm=new
StandardManager(ctx); setManager(ctx, sm); } --Shai -----Original Message----- Hi all, I’m 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:
I’m 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 I’m getting into
implementing this. Please let me know what you think. ________________________ Shai Fultheim Chief Technology Officer E-Mail: [EMAIL PROTECTED] Mobile: 972-53-866-459 Office: 972-2-5891-459 |