[Jboss-cvs] JBossAS SVN: r55057 - branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Aug 2 18:46:03 EDT 2006
Author: bstansberry at jboss.com
Date: 2006-08-02 18:46:02 -0400 (Wed, 02 Aug 2006)
New Revision: 55057
Modified:
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java
Log:
[JBAS-3318] Replicate all sessions affected by a cross-context call
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java 2006-08-02 22:44:10 UTC (rev 55056)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java 2006-08-02 22:46:02 UTC (rev 55057)
@@ -22,7 +22,6 @@
package org.jboss.web.tomcat.tc5.session;
import java.io.IOException;
-import javax.servlet.http.HttpSession;
import javax.servlet.ServletException;
import org.apache.catalina.*;
@@ -39,6 +38,7 @@
* Lifecycle interface.
*
* @author Thomas Peuss <jboss at peuss.de>
+ * @author Brian Stansberry
* @version $Revision$
*/
public class ClusteredSessionValve extends ValveBase implements Lifecycle
@@ -46,28 +46,15 @@
// The info string for this Valve
private static final String info = "ClusteredSessionValve/1.0";
- // The SnapshotManager that is associated with this Valve
- protected SnapshotManager snapshot;
-
// Valve-lifecycle_ helper object
protected LifecycleSupport support = new LifecycleSupport(this);
- // store the request and response object for parts of the clustering code that
- // have no direct access to this objects
- protected static final ThreadLocal requestThreadLocal = new ThreadLocal();
- protected static final ThreadLocal responseThreadLocal = new ThreadLocal();
- // Manager may store a ref to session id's it has handled here
- protected static final ThreadLocal sessionIdThreadLocal = new ThreadLocal();
-
/**
* Create a new Valve.
- *
- * @param snapshot The SnapshotManager associated with this Valve
*/
- public ClusteredSessionValve(SnapshotManager snapshot)
+ public ClusteredSessionValve()
{
super();
- this.snapshot = snapshot;
}
/**
@@ -90,29 +77,28 @@
{
// Store the request and response object for the clustering code that has no direct access to
// this objects
- requestThreadLocal.set(request);
- responseThreadLocal.set(response);
-
- // let the servlet invocation go through
- getNext().invoke(request, response);
-
- // --> We are now after the servlet invocation
-
- // Get the session
- HttpSession session = request.getSession(false);
-
- if (session != null && session.getId() != null)
- {
- // tell the snapshot manager that this session was modified
- snapshot.snapshot(session.getId());
- }
-
- // don't leak references to the request and response objects
- requestThreadLocal.set(null);
- responseThreadLocal.set(null);
+ SessionReplicationContext.initContext(request, response);
- // If JBossCacheManager stored a ref to a session id, we need to clear it
- sessionIdThreadLocal.set(null);
+ try
+ {
+
+
+ // let the servlet invocation go through
+ getNext().invoke(request, response);
+
+ // --> We are now after the servlet invocation
+
+ SessionReplicationContext[] sessions = SessionReplicationContext.getActiveSessions();
+
+ for (int i = 0; i < sessions.length; i++)
+ {
+ sessions[i].getSnapshot().snapshot(sessions[i].getSessionId());
+ }
+ }
+ finally
+ {
+ SessionReplicationContext.clearContext();
+ }
}
// Lifecylce-interface
@@ -133,14 +119,12 @@
public void start() throws LifecycleException
{
- snapshot.start();
support.fireLifecycleEvent(START_EVENT, this);
}
public void stop() throws LifecycleException
{
support.fireLifecycleEvent(STOP_EVENT, this);
- snapshot.stop();
}
}
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java 2006-08-02 22:44:10 UTC (rev 55056)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java 2006-08-02 22:46:02 UTC (rev 55057)
@@ -22,19 +22,17 @@
package org.jboss.web.tomcat.tc5.session;
import org.apache.catalina.Session;
-import org.jboss.logging.Logger;
/**
* A concrete implementation of the snapshot manager interface
* that does instant replication of a modified session
*
* @author Thomas Peuss <jboss at peuss.de>
+ * @author Brian Stansberry
* @version $Revision$
*/
public class InstantSnapshotManager extends SnapshotManager
{
- static Logger log = Logger.getLogger(InstantSnapshotManager.class);
-
public InstantSnapshotManager(AbstractJBossManager manager, String path)
{
super(manager, path);
@@ -48,12 +46,14 @@
try
{
// find the session that has been modified
- Session session = manager.findSession(id);
- manager.storeSession(session);
+ AbstractJBossManager mgr = getManager();
+ Session session = mgr.findSession(id);
+ if (session != null)
+ mgr.storeSession(session);
}
catch (Exception e)
{
- log.warn("Failed to replicate sessionID:" + id, e);
+ getLog().warn("Failed to replicate sessionID:" + id, e);
}
}
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java 2006-08-02 22:44:10 UTC (rev 55056)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java 2006-08-02 22:46:02 UTC (rev 55057)
@@ -21,10 +21,9 @@
*/
package org.jboss.web.tomcat.tc5.session;
-import java.util.HashMap;
-import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
-import org.apache.catalina.Context;
import org.apache.catalina.Session;
import org.jboss.logging.Logger;
@@ -33,6 +32,7 @@
* period of time and distributes them en bloc.
*
* @author Thomas Peuss <jboss at peuss.de>
+ * @author Brian Stansberry
* @version $Revision$
*/
public class IntervalSnapshotManager extends SnapshotManager implements Runnable
@@ -43,7 +43,7 @@
protected int interval = 1000;
// the modified sessions
- protected HashMap sessions = new HashMap();
+ protected Set sessions = new LinkedHashSet();
// the distribute thread
protected Thread thread = null;
@@ -68,11 +68,10 @@
public void snapshot(String id)
{
try
- {
- Session session = (Session) manager.findSession(id);
+ {
synchronized (sessions)
{
- sessions.put(id, session);
+ sessions.add(id);
}
}
catch (Exception e)
@@ -86,22 +85,28 @@
*/
protected void processSessions()
{
- HashMap copy = new HashMap(sessions.size());
-
+ String[] ids = null;
synchronized (sessions)
{
- copy.putAll(sessions);
+ ids = new String[sessions.size()];
+ ids = (String[]) sessions.toArray(ids);
sessions.clear();
}
- Iterator iter = copy.values().iterator();
- // distribute all modified sessions using default replication type
- while (iter.hasNext())
+ AbstractJBossManager mgr = getManager();
+ for (int i = 0; i < ids.length; i++)
{
- Session session = (Session) iter.next();
- manager.storeSession(session);
+ try
+ {
+ Session session = mgr.findSession(ids[i]);
+ if (session != null)
+ mgr.storeSession(session);
+ }
+ catch (Exception e)
+ {
+ getLog().error("Caught exception processing session " + ids[i], e);
+ }
}
- copy.clear();
}
/**
@@ -134,9 +139,9 @@
return;
}
- thread = new Thread(this, "ClusteredSessionDistributor[" + contextPath + "]");
+ thread = new Thread(this, "ClusteredSessionDistributor[" + getContextPath() + "]");
thread.setDaemon(true);
- thread.setContextClassLoader(manager.getContainer().getLoader().getClassLoader());
+ thread.setContextClassLoader(getManager().getContainer().getLoader().getClassLoader());
threadDone = false;
thread.start();
}
@@ -163,28 +168,26 @@
}
/**
- * Little Thread - sleep awhile...
- */
- protected void threadSleep()
- {
- try
- {
- Thread.sleep(interval);
- }
- catch (InterruptedException e)
- {
- }
- }
-
- /**
* Thread-loop
*/
public void run()
{
while (!threadDone)
{
- threadSleep();
- processSessions();
+ try
+ {
+ Thread.sleep(interval);
+ processSessions();
+ }
+ catch (InterruptedException ie)
+ {
+ if (!threadDone)
+ getLog().error("Caught exception processing sessions", ie);
+ }
+ catch (Exception e)
+ {
+ getLog().error("Caught exception processing sessions", e);
+ }
}
}
}
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java 2006-08-02 22:44:10 UTC (rev 55056)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java 2006-08-02 22:46:02 UTC (rev 55057)
@@ -121,6 +121,11 @@
/** Class loader for this web app. */
private ClassLoader tcl_;
+
+ /**
+ * The snapshot manager we are using.
+ */
+ private SnapshotManager snapshotManager_;
// ---------------------------------------------------------- Constructors
@@ -180,7 +185,7 @@
{
return cacheObjectNameString_;
}
-
+
/**
* Sets the JMX <code>ObjectName</code> under which our
* <code>TreeCache</code> is registered.
@@ -483,6 +488,8 @@
proxy_.stop();
tm = null;
+ snapshotManager_.stop();
+
started_ = false;
// Notify our interested LifecycleListeners
@@ -611,6 +618,12 @@
}
createdCounter_++;
+
+ // Add this session to the set of those potentially needing replication
+ // We use the realId here
+ String realId = getRealId(sessionId);
+ SessionReplicationContext.addActiveSession(realId, snapshotManager_);
+
return session;
}
@@ -770,7 +783,7 @@
// session from the other nodes to be gravitated, thus resuscitating
// the session.
if (session == null
- && !realId.equals(ClusteredSessionValve.sessionIdThreadLocal.get()))
+ && !SessionReplicationContext.isSessionActive(realId, snapshotManager_))
{
session = loadSession(realId);
if (session != null)
@@ -787,7 +800,10 @@
}
if (session != null)
- ClusteredSessionValve.sessionIdThreadLocal.set(realId);
+ {
+ // Add this session to the set of those potentially needing replication
+ SessionReplicationContext.addActiveSession(realId, snapshotManager_);
+ }
return session;
}
@@ -1243,9 +1259,9 @@
// Ensure the correct TCL is in place
ClassLoader prevTcl = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(tcl_);
try
{
+ Thread.currentThread().setContextClassLoader(tcl_);
synchronized (session)
{
session.removeAttributeInternal(attrKey, localCall, localOnly, notify);
@@ -1369,7 +1385,10 @@
try
{
initializeUnloadedSessions();
-
+
+ // Setup our SnapshotManager
+ initSnapshotManager();
+
// Add SnapshotValve and, if needed, JvmRouteValve and batch repl valve
installValves();
@@ -1483,7 +1502,7 @@
try
{
initializeUnloadedSessions();
-
+
// Add SnapshotValve and, if needed, JvmRouteValve and batch repl valve
installValves();
@@ -1616,7 +1635,7 @@
*
*/
private void installValves()
- {
+ {
if (useJK_)
{
log_.info("We are using mod_jk(2) for load-balancing. " +
@@ -1624,8 +1643,10 @@
installContextValve(new JvmRouteValve(this));
}
-
+
// Add batch replication valve if needed.
+ // TODO -- should we add this even if not FIELD in case a cross-context
+ // call traverses a field-based webapp?
if (replicationGranularity_ == WebMetaData.REPLICATION_GRANULARITY_FIELD &&
Boolean.TRUE.equals(replicationFieldBatchMode_))
{
@@ -1633,29 +1654,35 @@
log_.debug("Adding BatchReplicationClusteredSessionValve for batch replication.");
installContextValve(batchValve);
}
-
- // Choose the snapshot manager
+
+ // Add clustered session valve
+ ClusteredSessionValve valve = new ClusteredSessionValve();
+ installContextValve(valve);
+ }
+
+ /**
+ * Create and start a snapshot manager.
+ */
+ private void initSnapshotManager()
+ {
String ctxPath = ((Context) container_).getPath();
- SnapshotManager snap = null;
if ("instant".equals(snapshotMode_) || replicationGranularity_
== WebMetaData.REPLICATION_GRANULARITY_FIELD)
{
- snap = new InstantSnapshotManager(this, ctxPath);
+ snapshotManager_ = new InstantSnapshotManager(this, ctxPath);
}
else if ("interval".equals(snapshotMode_))
{
- snap = new IntervalSnapshotManager(this, ctxPath, snapshotInterval_);
+ snapshotManager_ = new IntervalSnapshotManager(this, ctxPath, snapshotInterval_);
}
else
{
log_.error("Snapshot mode must be 'instant' or 'interval' - " +
"using 'instant'");
- snap = new InstantSnapshotManager(this, ctxPath);
+ snapshotManager_ = new InstantSnapshotManager(this, ctxPath);
}
-
- // Add the session snapshot valve to the Context
- ClusteredSessionValve valve = new ClusteredSessionValve(snap);
- installContextValve(valve);
+
+ snapshotManager_.start();
}
private void installContextValve(Valve valve)
@@ -1714,7 +1741,7 @@
{
throw new ClusteringNotSupportedException("replication-granularity value is set to " +
"'FIELD' but is not supported by the cache service configuration. " +
- "Must set 'UseMarshalling' to 'true' in the tc5-cluster-service.xml");
+ "Must set 'UseRegionBasedMarshalling' to 'true' in the tc6-cluster.sar jboss-service.xml");
}
}
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java 2006-08-02 22:44:10 UTC (rev 55056)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java 2006-08-02 22:46:02 UTC (rev 55057)
@@ -249,7 +249,7 @@
*/
public void setSessionCookie(String sessionId)
{
- HttpServletResponse response = (HttpServletResponse) ClusteredSessionValve.responseThreadLocal.get();
+ HttpServletResponse response = SessionReplicationContext.getOriginalResponse();
setNewSessionCookie(sessionId, response);
}
@@ -259,7 +259,6 @@
{
Context context = (Context) container_;
Connector connector = ((Response)response).getConnector();
-
if (context.getCookies())
{
// set a new session cookie
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java 2006-08-02 22:44:10 UTC (rev 55056)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java 2006-08-02 22:46:02 UTC (rev 55057)
@@ -22,6 +22,7 @@
package org.jboss.web.tomcat.tc5.session;
import org.apache.catalina.Context;
+import org.jboss.logging.Logger;
/**
* Abstract base class for a session snapshot manager.
@@ -36,11 +37,18 @@
// The context-path
protected String contextPath;
+
+ private Logger log;
public SnapshotManager(AbstractJBossManager manager, String path)
{
this.manager = manager;
contextPath = path;
+
+ String suffix = path;
+ if (suffix == null || "".equals(suffix))
+ suffix = "ROOT";
+ log = Logger.getLogger(getClass().getName() + "." + suffix);
}
/**
@@ -58,4 +66,21 @@
* Stop the snapshot manager
*/
public abstract void stop();
+
+ protected String getContextPath()
+ {
+ return contextPath;
+ }
+
+ protected Logger getLog()
+ {
+ return log;
+ }
+
+ protected AbstractJBossManager getManager()
+ {
+ return manager;
+ }
+
+
}
More information about the jboss-cvs-commits
mailing list