[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