[Jboss-cvs] JBossAS SVN: r56320 - 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
Sun Aug 27 23:40:10 EDT 2006


Author: bstansberry at jboss.com
Date: 2006-08-27 23:40:09 -0400 (Sun, 27 Aug 2006)
New Revision: 56320

Modified:
   branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionReplicationContext.java
Log:
Simplify the way we ignore cache notifications from webapp threads; session id isn't relevant
Pass the session itself to the SnapshotManager
Specially track expired sessions

Modified: branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionReplicationContext.java
===================================================================
--- branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionReplicationContext.java	2006-08-28 03:38:59 UTC (rev 56319)
+++ branches/Branch_4_0/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionReplicationContext.java	2006-08-28 03:40:09 UTC (rev 56320)
@@ -1,9 +1,8 @@
 package org.jboss.web.tomcat.tc5.session;
 
 import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Set;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
@@ -14,18 +13,31 @@
    
    private static final ThreadLocal localActivity = new ThreadLocal();
    
-   private static final Set EMPTY;
+   private static final Map EMPTY;
    
    static
    {
-      EMPTY = Collections.unmodifiableSet(new HashSet());
+      EMPTY = Collections.unmodifiableMap(new HashMap());
    }
    
    private int initCount;
-   private final Set replicatableSessions;
+   private final Map replicatableSessions;
+   private Map expiredSessions;
    private Request outerRequest;
    private Response outerResponse;
    
+   /**
+    * Associate a SessionReplicationContext with the current thread, if
+    * there isn't one already.  If there isn't one, associated the 
+    * given request and response with the context.
+    * <p/>
+    * <strong>NOTE:</strong> Nested calls to this method and {@link #clearContext()}
+    * are supported; once a context is established the number of calls to this
+    * method and <code>clearContext()</code> are tracked.
+    * 
+    * @param request
+    * @param response
+    */
    public static void initContext(Request request, Response response)
    {
       SessionReplicationContext ctx = getCurrentContext();
@@ -37,53 +49,64 @@
       ctx.initCount++;
    }
    
-   public static Set clearContext()
+   /**
+    * Remove the SessionReplicationContext from the current thread
+    * and return a Map of all sessions possibly needing replication.
+    * 
+    * @return a Map<ClusteredSession, SnapshotManager>
+    */
+   public static Map clearContext()
    {
-      Set replicatable = EMPTY;
       SessionReplicationContext ctx = getCurrentContext();
       if (ctx != null)
       {
          ctx.initCount--;
          if (ctx.initCount == 0 )
          {
-            replicatable = ctx.replicatableSessions;
+            // We've unwound any nested calls; clear the ThreadLocal
+            // and return the sessions
             replicationContext.set(null);
+            return ctx.replicatableSessions;
          }
       }
-      return replicatable;
       
+      // Just return an empty map
+      return EMPTY;
+      
    }
    
-   public static void bindSession(String realId, SnapshotManager manager)
+   public static void bindSession(ClusteredSession session, SnapshotManager manager)
    {
       SessionReplicationContext ctx = getCurrentContext();
       if (ctx != null)
       {
-         ctx.replicatableSessions.add(new ReplicatableSession(realId, manager));
+         ctx.replicatableSessions.put(session, manager);
       }
       /*else {
          If there is no ctx, it means we are past the part of the request cycle
-         where the session will be invalidated by the app, so no further need 
-         to track binding
+         where we track sessions for replication
       }*/
    }
    
-   public static void unbindSession(String realId, SnapshotManager manager)
+   public static void sessionExpired(ClusteredSession session, String realId, SnapshotManager manager)
    {
       SessionReplicationContext ctx = getCurrentContext();
       if (ctx != null)
       {
-         ctx.replicatableSessions.remove(new ReplicatableSession(realId, manager));
+         Object obj = ctx.replicatableSessions.remove(session);
+         if (obj != null)
+            ctx.addExpiredSession(realId, manager);
+         // else we weren't managing the session; just ignore
       }      
    }
    
-   public static boolean isSessionBound(String realId, SnapshotManager manager)
+   public static boolean isSessionBoundAndExpired(String realId, SnapshotManager manager)
    {
       boolean result = false;
       SessionReplicationContext ctx = getCurrentContext();
       if (ctx != null)
       {
-         result = ctx.replicatableSessions.contains(new ReplicatableSession(realId, manager));
+         result = ctx.isSessionExpired(realId, manager);
       }
       return result;
    }
@@ -93,29 +116,22 @@
     * If the thread has already been so marked, increases a counter
     * so a subsequent call to finishLocalActivity does not remove
     * the association (allowing nested calls).
-    * 
-    * @param   sessionId. Can be <code>null</code>.
     */
-   public static void startLocalActivity(String sessionId)
+   public static void startLocalActivity()
    {
       LocalSessionActivity ctx = getCurrentActivity();
       if (ctx == null)
       {
-         ctx = new LocalSessionActivity(sessionId);
+         ctx = new LocalSessionActivity();
          localActivity.set(ctx);
       }
-      else if (!sessionId.equals(ctx.sessionId))
-      {
-         throw new IllegalStateException("Conflicting active sessions " + 
-               ctx.sessionId + " and " + sessionId);
-      }
       
       ctx.count++;
    }
    
    /**
     * Marks the completion of activity on a given session.  Should be called
-    * once for each invocation of {@link #startLocalActivity(String)}.
+    * once for each invocation of {@link #startLocalActivity()}.
     */
    public static void finishLocalActivity()
    {
@@ -130,15 +146,9 @@
       }
    }
    
-   public static boolean isLocallyActive(String sessionId)
+   public static boolean isLocallyActive()
    {
-      boolean result = false;
-      LocalSessionActivity ctx = getCurrentActivity();
-      if (ctx != null)
-      {
-         result = sessionId.equals(ctx.sessionId);
-      }
-      return result;
+      return getCurrentActivity() != null;
    }
    
    public static Request getOriginalRequest()
@@ -167,88 +177,36 @@
    {
       this.outerRequest = request;
       this.outerResponse = response;
-      this.replicatableSessions = new LinkedHashSet();
+      this.replicatableSessions = new HashMap();
    }
    
-   private static class LocalSessionActivity
+   private void addExpiredSession(String realId, SnapshotManager manager)
    {
-      int count;
-      final String sessionId;
-      
-      private LocalSessionActivity(String sessionId)
+      if (this.expiredSessions == null)
       {
-         if (sessionId == null)
-            throw new IllegalArgumentException("sessionId cannot be null");
-         
-         this.sessionId = sessionId;
+         expiredSessions = new HashMap();
       }
+      expiredSessions.put(manager, realId);      
    }
    
-   
-   public static class ReplicatableSession
+   private boolean isSessionExpired(String realId, SnapshotManager manager)
    {
-      private String sessionId;
-      private SnapshotManager snapshot;
-      
-      // Prevent external instantiation
-      private ReplicatableSession(String sessionId, SnapshotManager manager) 
+      boolean result = false;
+      if (expiredSessions != null)
       {
-         this.sessionId = sessionId;
-         this.snapshot = manager;
-      }
-
-      public SnapshotManager getSnapshot()
-      {
-         return snapshot;
-      }
-
-      public String getSessionId()
-      {
-         return sessionId;
-      }
-
-      public boolean equals(Object obj)
-      {
-         if (this == obj)
-            return true;
-         
-         if (obj instanceof ReplicatableSession)
-         {
-            ReplicatableSession other = (ReplicatableSession) obj;
-            // Test the snapshot first as it is more likely to be unique
-            // and it's a simple object identity test
-            return (this.snapshot.equals(other.snapshot) 
-                    && this.sessionId.equals(other.sessionId));
-         }
-         
-         return false;
-      }
-
-      /**
-       * Returns the {@link #getSnapshot snapshot}'s hashcode, as it should be sufficient 
-       * to minimize bucket collisions; for the same request there shouldn't be more 
-       * than one session per snapshot.
-       */
-      public int hashCode()
-      {
-         return snapshot.hashCode();
-      }
-
-      public String toString()
-      {
-         StringBuffer sb = new StringBuffer(getClass().getName());
-         sb.append("{sessionid=");
-         sb.append(sessionId);
-         sb.append("snapshot=");
-         sb.append(snapshot);
-         sb.append("}");
-         return sb.toString();
-      }
-      
+         result = realId.equals(expiredSessions.get(manager));
+      }      
+      return result;
    }
    
+   // Static Member Classes
    
+   /**
+    * A mutable integer
+    */
+   private static class LocalSessionActivity
+   {
+      int count;
+   }
    
-   
-   
 }




More information about the jboss-cvs-commits mailing list