[Jboss-cvs] JBossAS SVN: r56405 - 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
Tue Aug 29 11:37:15 EDT 2006
Author: bstansberry at jboss.com
Date: 2006-08-29 11:37:13 -0400 (Tue, 29 Aug 2006)
New Revision: 56405
Modified:
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java
branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java
Log:
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java 2006-08-29 15:35:14 UTC (rev 56404)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java 2006-08-29 15:37:13 UTC (rev 56405)
@@ -32,6 +32,12 @@
public class CacheListener implements TreeCacheListener
{
+ // Element within an FQN that is JSESSION
+ private static final int JSESSION_FQN_INDEX = 0;
+ // Element within an FQN that is the hostname
+ private static final int HOSTNAME_FQN_INDEX = 1;
+ // ELEMENT within an FQN this is the webapp name
+ private static final int WEBAPP_FQN_INDEX = 2;
// Element within an FQN that is the session id
private static final int SESSION_ID_FQN_INDEX = 3;
// Size of an Fqn that points to the root of a session
@@ -47,65 +53,64 @@
// The size of the root of a buddy backup subtree (including owner)
private static final int BUDDY_BACKUP_ROOT_OWNER_SIZE = BUDDY_BACKUP_ROOT_OWNER_INDEX + 1;
// Size of an Fqn that points to the root of a session in the buddy backup region
- private static final int BUDDY_SESSION_FQN_SIZE = BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_FQN_SIZE;
+// private static final int BUDDY_SESSION_FQN_SIZE = BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_FQN_SIZE;
// Size of an Fqn that points to the root of a session in the buddy backup region
- private static final int BUDDY_POJO_KEY_FQN_SIZE = BUDDY_BACKUP_ROOT_OWNER_SIZE + POJO_KEY_FQN_SIZE;
+// private static final int BUDDY_POJO_KEY_FQN_SIZE = BUDDY_BACKUP_ROOT_OWNER_SIZE + POJO_KEY_FQN_SIZE;
- protected static Logger log_ = Logger.getLogger(CacheListener.class);
- protected JBossCacheWrapper cacheWrapper_;
- protected JBossCacheManager manager_;
- protected Fqn subtreeRoot_;
- protected boolean fieldBased_;
+ private static Logger log_ = Logger.getLogger(CacheListener.class);
+ private JBossCacheWrapper cacheWrapper_;
+ private JBossCacheManager manager_;
+ private String webapp_;
+ private String hostname_;
+ private boolean fieldBased_;
+ private boolean sessionBased_;
+// private boolean async_;
+ private boolean disdainLocalActivity_;
- CacheListener(JBossCacheWrapper wrapper, JBossCacheManager manager, Fqn subtreeRoot)
+ CacheListener(JBossCacheWrapper wrapper, JBossCacheManager manager, String hostname, String webapp)
{
cacheWrapper_ = wrapper;
manager_ = manager;
- subtreeRoot_ = subtreeRoot;
- fieldBased_ = manager_.getReplicationGranularity() == WebMetaData.REPLICATION_GRANULARITY_FIELD;
+ hostname_ = hostname;
+ webapp_ = webapp;
+ int granularity = manager_.getReplicationGranularity();
+ fieldBased_ = (granularity == WebMetaData.REPLICATION_GRANULARITY_FIELD);
+ sessionBased_ = (granularity == WebMetaData.REPLICATION_GRANULARITY_SESSION);
+ // TODO decide if disdaining local activity is always good for REPL_ASYNC
+// favorActivity_ = async_ || sessionBased_;
+ disdainLocalActivity_ = sessionBased_; // for now
}
// --------------- TreeCacheListener methods ------------------------------------
public void nodeCreated(Fqn fqn)
{
- // No-op
+ // We don't care about this event
}
public void nodeRemoved(Fqn fqn)
{
- // We only care if there is a chance this is for a session root
- // or a pojo key
- int rawSize = fqn.size();
- if (rawSize != SESSION_FQN_SIZE
- && rawSize != BUDDY_SESSION_FQN_SIZE
- && rawSize != POJO_KEY_FQN_SIZE
- && rawSize != BUDDY_POJO_KEY_FQN_SIZE)
- return;
-
// Ignore our own activity
if (SessionReplicationContext.isLocallyActive())
return;
- // Parse the Fqn so if it has a buddy backup region in it
- // we can just deal with the part below that
- ParsedBuddyFqn pfqn = new ParsedBuddyFqn(fqn);
- fqn = pfqn.noBuddy;
+ boolean isBuddy = isBuddyFqn(fqn);
// Potential removal of a Pojo where we need to unregister as an Observer.
if (fieldBased_
- && fqn.size() == POJO_KEY_FQN_SIZE
- && fqn.isChildOf(subtreeRoot_))
+ && isFqnPojoKeySized(fqn, isBuddy)
+ && isFqnForOurWebapp(fqn, isBuddy))
{
- String sessId = getIdFromFqn(fqn);
- String attrKey = (String) fqn.get(POJO_KEY_FQN_INDEX);
+ String sessId = getIdFromFqn(fqn, isBuddy);
+ String attrKey = getPojoKeyFromFqn(fqn, isBuddy);
manager_.processRemoteAttributeRemoval(sessId, attrKey);
}
- else if(fqn.size() == SESSION_FQN_SIZE && fqn.isChildOf(subtreeRoot_))
+ else if(isFqnSessionRootSized(fqn, isBuddy)
+ && isFqnForOurWebapp(fqn, isBuddy))
{
// A session has been invalidated from another node;
// need to inform manager
- String sessId = getIdFromFqn(fqn);
+ String sessId = getIdFromFqn(fqn, isBuddy);
manager_.processRemoteInvalidation(sessId);
}
}
@@ -116,6 +121,7 @@
*/
public void nodeLoaded(Fqn fqn)
{
+ // We don't care about this event
}
public void nodeModified(Fqn fqn)
@@ -123,40 +129,45 @@
nodeDirty(fqn);
}
- protected void nodeDirty(Fqn fqn)
+ private void nodeDirty(Fqn fqn)
{
+ // If checking for local activity has a higher likelihood of
+ // catching unwanted notifications than checking fqn size,
+ // do it first
+ if (disdainLocalActivity_)
+ {
+ if (SessionReplicationContext.isLocallyActive())
+ return;
+ }
+
+ boolean isBuddy = isBuddyFqn(fqn);
// We only care if there is a chance this is for a session root
- int rawSize = fqn.size();
- if (rawSize != SESSION_FQN_SIZE && rawSize != BUDDY_SESSION_FQN_SIZE)
+ if (!isFqnSessionRootSized(fqn, isBuddy))
return;
- // Ignore local activity
- if (SessionReplicationContext.isLocallyActive())
- return;
+ if (!disdainLocalActivity_)
+ {
+ if (SessionReplicationContext.isLocallyActive())
+ return;
+ }
- // Parse the Fqn so if it has a buddy backup region in it
- // we can just deal with the part below that
- ParsedBuddyFqn pfqn = new ParsedBuddyFqn(fqn);
- Fqn noBuddy = pfqn.noBuddy;
-
- // Check if we need to handle this event. If this is not for my webapp,
- // or not for the root node of a session then I should skip it.
- if(noBuddy.size() != SESSION_FQN_SIZE || !noBuddy.isChildOf(subtreeRoot_))
+ // We only care if this is for our webapp
+ if (!isFqnForOurWebapp(fqn, isBuddy))
return;
// Query if we have version value in the distributed cache.
- // Use the full Fqn, not just the "no buddy" part.
// If we have a version value, compare the version and invalidate if necessary.
Integer version = (Integer)cacheWrapper_.get(fqn, JBossCacheService.VERSION_KEY);
if(version != null)
{
- String realId = getIdFromFqn(noBuddy);
+ String realId = getIdFromFqn(fqn, isBuddy);
ClusteredSession session = manager_.findLocalSession(realId);
if (session == null)
{
+ String owner = isBuddy ? getBuddyOwner(fqn) : null;
// Notify the manager that an unloaded session has been updated
- manager_.unloadedSessionChanged(realId, pfqn.owner);
+ manager_.unloadedSessionChanged(realId, owner);
}
else if (session.isNewData(version.intValue()))
{
@@ -169,7 +180,7 @@
version.intValue());
}
}
- else if (!pfqn.isBuddyTree)
+ else if (!isBuddy)
{
log_.warn("Possible concurrency problem: Replicated version id " +
version + " matches in-memory version for session " + realId);
@@ -190,7 +201,7 @@
public void nodeVisited(Fqn fqn)
{
- // no-op
+ // We don't care about this event
}
public void cacheStarted(TreeCache cache)
@@ -205,42 +216,73 @@
public void viewChange(View new_view)
{
- // We don't care for this event.
+ // We don't care about this event.
}
public void nodeEvicted(Fqn fqn)
{
- // We don't care for this event.
+ // We don't care about this event.
}
+
+ private boolean isFqnForOurWebapp(Fqn fqn, boolean isBuddy)
+ {
+ try
+ {
+ if (webapp_.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + WEBAPP_FQN_INDEX : WEBAPP_FQN_INDEX))
+ && hostname_.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + HOSTNAME_FQN_INDEX : HOSTNAME_FQN_INDEX))
+ && JBossCacheService.SESSION.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + JSESSION_FQN_INDEX : JSESSION_FQN_INDEX)))
+ return true;
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ // can't be ours; too small; just fall through
+ }
- protected String getIdFromFqn(Fqn fqn)
+ return false;
+ }
+
+ private static boolean isFqnSessionRootSized(Fqn fqn, boolean isBuddy)
{
- return (String)fqn.get(SESSION_ID_FQN_INDEX);
+ return fqn.size() == (isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_FQN_SIZE : SESSION_FQN_SIZE);
}
- private static class ParsedBuddyFqn
+ private static boolean isFqnPojoKeySized(Fqn fqn, boolean isBuddy)
{
- Fqn raw;
- Fqn noBuddy;
- String owner;
- boolean isBuddyTree;
-
- ParsedBuddyFqn(Fqn raw)
+ return fqn.size() == (isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + POJO_KEY_FQN_SIZE : POJO_KEY_FQN_SIZE);
+ }
+
+ private static String getIdFromFqn(Fqn fqn, boolean isBuddy)
+ {
+ return (String)fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_ID_FQN_INDEX : SESSION_ID_FQN_INDEX);
+ }
+
+ private static String getPojoKeyFromFqn(Fqn fqn, boolean isBuddy)
+ {
+ return (String) fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + POJO_KEY_FQN_INDEX: POJO_KEY_FQN_INDEX);
+ }
+
+ private static boolean isBuddyFqn(Fqn fqn)
+ {
+ try
{
- this.raw = raw;
- if (raw.isChildOf(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN)
- && raw.size() > BUDDY_BACKUP_ROOT_OWNER_SIZE)
- {
- owner = (String) raw.get(BUDDY_BACKUP_ROOT_OWNER_INDEX);
- noBuddy = raw.getFqnChild(BUDDY_BACKUP_ROOT_OWNER_SIZE, raw.size());
- isBuddyTree = true;
- if (log_.isTraceEnabled())
- log_.trace(raw + " parsed to " + noBuddy + " with owner " + owner);
- }
- else
- {
- noBuddy = raw;
- }
+ return BuddyManager.BUDDY_BACKUP_SUBTREE.equals(fqn.get(0));
}
+ catch (IndexOutOfBoundsException e)
+ {
+ // Can only happen if fqn is ROOT, and we shouldn't get
+ // notifications for ROOT.
+ // If it does, just means it's not a buddy
+ return false;
+ }
}
+
+ /**
+ * Extracts the owner portion of an buddy subtree Fqn.
+ *
+ * @param fqn An Fqn that is a child of the buddy backup root node.
+ */
+ private static String getBuddyOwner(Fqn fqn)
+ {
+ return (String) fqn.get(BUDDY_BACKUP_ROOT_OWNER_INDEX);
+ }
}
Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java 2006-08-29 15:35:14 UTC (rev 56404)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java 2006-08-29 15:37:13 UTC (rev 56405)
@@ -154,14 +154,13 @@
log_.debug("Old and new virtual host name are: " + host + ", " + hostName_);
- // Construct the fqn
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
- Fqn pathFqn = new Fqn( objs );
-
- cacheListener_ = new CacheListener(cacheWrapper_, manager_, pathFqn);
+ // Listen for cache changes
+ cacheListener_ = new CacheListener(cacheWrapper_, manager_, hostName_, webAppPath_);
proxy_.addTreeCacheListener(cacheListener_);
// register the tcl and bring over the state for the webapp
+ Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
+ Fqn pathFqn = new Fqn( objs );
String fqnStr = pathFqn.toString();
try {
if(useTreeCacheMarshalling_)
@@ -515,14 +514,6 @@
*/
public Object setPojo(String realId, String key, Object pojo)
{
- // TODO This actually redundant here -- its already in
- // FieldBasedClusteredSession
- if( !Util.checkPojoType(pojo) )
- {
- throw new RuntimeException("setPojo: pojo is not an instance of Advised. Need to declare it in aop: "
- +pojo.toString());
- }
-
if(log_.isTraceEnabled())
{
log_.trace("setPojo(): session id: " + realId + " key: " + key +
@@ -532,13 +523,13 @@
Fqn fqn = getFieldFqn(realId, key);
try {
// Ignore any cache notifications that our own work generates
- SessionReplicationContext.startLocalActivity();
+ SessionReplicationContext.startCacheActivity();
return proxy_.putObject(fqn, pojo);
} catch (CacheException e) {
throw new RuntimeException("JBossCacheService: exception occurred in cache setPojo ... ", e);
}
finally {
- SessionReplicationContext.finishLocalActivity();
+ SessionReplicationContext.finishCacheActivity();
}
}
@@ -558,13 +549,13 @@
Fqn fqn = getFieldFqn(realId, key);
try {
// Ignore any cache notifications that our own work generates
- SessionReplicationContext.startLocalActivity();
+ SessionReplicationContext.startCacheActivity();
return proxy_.removeObject(fqn);
} catch (CacheException e) {
throw new RuntimeException("JBossCacheService: exception occurred in cache removePojo ... ", e);
}
finally {
- SessionReplicationContext.finishLocalActivity();
+ SessionReplicationContext.finishCacheActivity();
}
}
@@ -584,11 +575,11 @@
Fqn fqn = getAttributeFqn(realId);
try {
// Ignore any cache notifications that our own work generates
- SessionReplicationContext.startLocalActivity();
+ SessionReplicationContext.startCacheActivity();
cacheWrapper_.evictSubtree(fqn);
}
finally {
- SessionReplicationContext.finishLocalActivity();
+ SessionReplicationContext.finishCacheActivity();
}
}
@@ -608,11 +599,11 @@
Fqn fqn = getFieldFqn(realId, key);
try {
// Ignore any cache notifications that our own work generates
- SessionReplicationContext.startLocalActivity();
+ SessionReplicationContext.startCacheActivity();
cacheWrapper_.evictSubtree(fqn);
}
finally {
- SessionReplicationContext.finishLocalActivity();
+ SessionReplicationContext.finishCacheActivity();
}
}
More information about the jboss-cvs-commits
mailing list