[jboss-cvs] JBossAS SVN: r78380 - in trunk: tomcat/src/main/org/jboss/web/tomcat/service/session and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Sep 10 23:20:20 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-09-10 23:20:19 -0400 (Wed, 10 Sep 2008)
New Revision: 78380

Modified:
   trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/SessionCountUnitTestCase.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
Log:
[JBAS-5693] Make clustered web session passivation LRU

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/SessionCountUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/SessionCountUnitTestCase.java	2008-09-11 00:46:02 UTC (rev 78379)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/SessionCountUnitTestCase.java	2008-09-11 03:20:19 UTC (rev 78380)
@@ -375,9 +375,11 @@
       createAndUseSession(jbcm0, "1", true, true);
       
       assertEquals("Session count correct", 1, jbcm0.getActiveSessionCount());
-      assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());      
+      assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());
+      assertEquals("Passivated session count correct", 0, jbcm0.getPassivatedSessionCount());      
       assertEquals("Session count correct", 1, jbcm1.getActiveSessionCount());
       assertEquals("Local session count correct", 0, jbcm1.getLocalActiveSessionCount());
+      assertEquals("Passivated session count correct", 0, jbcm1.getPassivatedSessionCount());
       
       // Should fail to create a 2nd
       createAndUseSession(jbcm1, "2", false, false);      
@@ -392,12 +394,14 @@
       assertEquals("Session count correct", 2, jbcm0.getActiveSessionCount());
       assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());
       assertEquals("Created session count correct", 1, jbcm0.getCreatedSessionCount());
-      assertEquals("Expired session count correct", 0, jbcm0.getExpiredSessionCount());      
+      assertEquals("Expired session count correct", 0, jbcm0.getExpiredSessionCount());  
+      assertEquals("Passivated session count correct", 0, jbcm0.getPassivatedSessionCount());    
        
       assertEquals("Session count correct", 1, jbcm1.getActiveSessionCount());
-      assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());
-      assertEquals("Created session count correct", 1, jbcm0.getCreatedSessionCount());
-      assertEquals("Expired session count correct", 0, jbcm0.getExpiredSessionCount());      
+      assertEquals("Local session count correct", 1, jbcm1.getLocalActiveSessionCount());
+      assertEquals("Created session count correct", 1, jbcm1.getCreatedSessionCount());
+      assertEquals("Expired session count correct", 0, jbcm1.getExpiredSessionCount()); 
+      assertEquals("Passivated session count correct", 1, jbcm1.getPassivatedSessionCount());     
    }
    
    public void testReplicatedMaxSessionsWithMinIdle() throws Exception
@@ -434,9 +438,11 @@
       createAndUseSession(jbcm0, "1", true, true);
       
       assertEquals("Session count correct", 1, jbcm0.getActiveSessionCount());
-      assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());      
+      assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());
+      assertEquals("Passivated session count correct", 0, jbcm0.getPassivatedSessionCount());      
       assertEquals("Session count correct", 1, jbcm1.getActiveSessionCount());
       assertEquals("Local session count correct", 0, jbcm1.getLocalActiveSessionCount());
+      assertEquals("Passivated session count correct", 0, jbcm0.getPassivatedSessionCount());
       
       // Should fail to create a 2nd
       createAndUseSession(jbcm1, "2", false, false);      
@@ -451,12 +457,14 @@
       assertEquals("Session count correct", 2, jbcm0.getActiveSessionCount());
       assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());
       assertEquals("Created session count correct", 1, jbcm0.getCreatedSessionCount());
-      assertEquals("Expired session count correct", 0, jbcm0.getExpiredSessionCount());      
+      assertEquals("Expired session count correct", 0, jbcm0.getExpiredSessionCount());  
+      assertEquals("Passivated session count correct", 0, jbcm0.getPassivatedSessionCount());    
        
       assertEquals("Session count correct", 1, jbcm1.getActiveSessionCount());
-      assertEquals("Local session count correct", 1, jbcm0.getLocalActiveSessionCount());
-      assertEquals("Created session count correct", 1, jbcm0.getCreatedSessionCount());
-      assertEquals("Expired session count correct", 0, jbcm0.getExpiredSessionCount());      
+      assertEquals("Local session count correct", 1, jbcm1.getLocalActiveSessionCount());
+      assertEquals("Created session count correct", 1, jbcm1.getCreatedSessionCount());
+      assertEquals("Expired session count correct", 0, jbcm1.getExpiredSessionCount()); 
+      assertEquals("Passivated session count correct", 1, jbcm1.getPassivatedSessionCount());     
       
    }
    
@@ -821,7 +829,8 @@
       assertEquals("Passivated session count correct", 0, jbcm.getPassivatedSessionCount());
       // jbcm1 only has 2 active since it passivated one when it created 3rd 
       assertEquals("Session count correct", 2, jbcm1.getActiveSessionCount());
-      assertEquals("Local session count correct", 1, jbcm1.getLocalActiveSessionCount());
+      // Both active sessions are local, as the remote session is oldest so we passivate it first 
+      assertEquals("Local session count correct", 2, jbcm1.getLocalActiveSessionCount());
       assertEquals("Created session count correct", 2, jbcm1.getCreatedSessionCount());
       assertEquals("Expired session count correct", 0, jbcm1.getExpiredSessionCount());
       assertEquals("Passivated session count correct", 1, jbcm1.getPassivatedSessionCount());
@@ -869,7 +878,7 @@
       if (!fullRestart)
       {
          assertEquals("Session count correct", 2, jbcm1.getActiveSessionCount());
-         assertEquals("Local session count correct", 1, jbcm1.getLocalActiveSessionCount());
+         assertEquals("Local session count correct", 2, jbcm1.getLocalActiveSessionCount());
          assertEquals("Created session count correct", 2, jbcm1.getCreatedSessionCount());
          assertEquals("Expired session count correct", 0, jbcm1.getExpiredSessionCount());
          assertEquals("Passivated session count correct", 1, jbcm1.getPassivatedSessionCount());

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java	2008-09-11 00:46:02 UTC (rev 78379)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java	2008-09-11 03:20:19 UTC (rev 78380)
@@ -27,6 +27,7 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -1204,6 +1205,10 @@
          }
       }
       
+      // Holder for sessions or OwnedSessionUpdates that survive expiration,
+      // sorted by last acccessed time
+      TreeSet<PassivationCheck> passivationChecks = new TreeSet<PassivationCheck>();
+      
       try
       {
          // First, handle the sessions we are actively managing
@@ -1241,28 +1246,11 @@
                   if (!session.isValid()) continue;
                }
                 
-               // we now have a valid session; see if we need to passivate it
+               // we now have a valid session; store it so we can check later
+               // if we need to passivate it
                if (passivate)
                {
-                  long timeNow = System.currentTimeMillis();
-                  long timeIdle = timeNow - session.getLastAccessedTimeInternal();
-                  // if maxIdle time configured, means that we need to passivate sessions that have
-                  // exceeded the max allowed idle time
-                  if (passivationMax >= 0 
-                        && timeIdle > passivationMax)
-                  {
-                     processSessionPassivation(session.getRealId());
-                  }
-                  // If the session didn't exceed the passivationMaxIdleTime_, see   
-                  // if the number of sessions managed by this manager greater than the max allowed 
-                  // active sessions, passivate the session if it exceed passivationMinIdleTime_ 
-                  else if (maxActiveAllowed_ > 0 
-                              && passivationMin > 0 
-                              && calcActiveSessions() >= maxActiveAllowed_ 
-                              && timeIdle > passivationMin)
-                  {
-                     processSessionPassivation(session.getRealId());
-                  }                  
+                  passivationChecks.add(new PassivationCheck(session));
                }
                
             }
@@ -1290,45 +1278,79 @@
             String realId = entry.getKey();
             OwnedSessionUpdate osu = entry.getValue();
             
-            // Ignore marker entries for our own passivated sessions
-            // Also skip if the session isn't configured to expire
-            if (osu.passivated || osu.maxInactive < 1)
-               continue;
-            
             long now = System.currentTimeMillis();
             long elapsed = (now - osu.updateTime);
             try
             {
-               if (expire && elapsed >= (osu.maxInactive + maxUnrep) * 1000L)
+               if (expire && osu.maxInactive >= 1 && elapsed >= (osu.maxInactive + maxUnrep) * 1000L)
                {
-                  proxy_.removeSessionLocal(realId, osu.owner);
-                  unloadedSessions_.remove(realId);
+                  if (osu.passivated)
+                  {
+                     // Passivated session needs to be expired. A call to 
+                     // findSession will bring it out of passivation
+                     Session session = findSession(realId);
+                     session.isValid(); // will expire
+                  }
+                  else
+                  {
+                     proxy_.removeSessionLocal(realId, osu.owner);
+                     unloadedSessions_.remove(realId);
+                  }
                }
-               else if (passivate)
+               else if (passivate && !osu.passivated)
+               {  
+                  // we now have a valid session; store it so we can check later
+                  // if we need to passivate it
+                  passivationChecks.add(new PassivationCheck(realId, osu));
+               }
+            } 
+            catch (Exception ex)
+            {
+               log_.error("processExpirationPassivation(): failed handling unloaded session " + 
+                       realId, ex);
+            }
+         }
+         
+         // Now, passivations
+         if (passivate)
+         {
+            // Iterate through sessions, earliest lastAccessedTime to latest
+            for (PassivationCheck passivationCheck : passivationChecks)
+            {               
+               try
                {
+                  long timeNow = System.currentTimeMillis();
+                  long timeIdle = timeNow - passivationCheck.getLastUpdate();
                   // if maxIdle time configured, means that we need to passivate sessions that have
                   // exceeded the max allowed idle time
                   if (passivationMax >= 0 
-                        && elapsed > passivationMax)
+                        && timeIdle > passivationMax)
                   {
-                     processUnloadedSessionPassivation(realId, osu);
+                     passivationCheck.passivate();
                   }
                   // If the session didn't exceed the passivationMaxIdleTime_, see   
-                  // if the number of sessions managed by this manager is greater than the max allowed 
-                  // active sessions; passivate the session if it exceed passivationMinIdleTime_ 
+                  // if the number of sessions managed by this manager greater than the max allowed 
+                  // active sessions, passivate the session if it exceed passivationMinIdleTime_ 
                   else if (maxActiveAllowed_ > 0 
-                              && passivationMin >= 0 
-                              && elapsed >= passivationMin
-                              && calcActiveSessions() >= maxActiveAllowed_)
+                              && passivationMin > 0 
+                              && calcActiveSessions() >= maxActiveAllowed_ 
+                              && timeIdle > passivationMin)
                   {
-                     processUnloadedSessionPassivation(realId, osu);
-                  }               
+                     passivationCheck.passivate();
+                  }
+                  else
+                  {
+                     // the entries are ordered by lastAccessed, so once
+                     // we don't passivate one, we won't passivate any
+                     break;
+                  }
                }
-            } 
-            catch (Exception ex)
-            {
-               log_.error("processExpirationPassivation(): failed handling unloaded session " + 
-                       realId, ex);
+               catch (Exception e)
+               {
+                  String unloadMark = passivationCheck.isUnloaded() ? "unloaded " : "";
+                  log_.error("processExpirationPassivation(): failed passivating " + unloadMark + "session " + 
+                        passivationCheck.getRealId(), e);
+               }                  
             }
          }
       }
@@ -2149,4 +2171,67 @@
          this.passivated = passivated;
       }
    }
+   
+   private class PassivationCheck implements Comparable<PassivationCheck>
+   {
+      private final String realId;
+      private final OwnedSessionUpdate osu;
+      private final ClusteredSession session;
+      
+      private PassivationCheck(String realId, OwnedSessionUpdate osu)
+      {
+         assert osu != null : "osu is null";
+         assert realId != null : "realId is null";
+         
+         this.realId = realId;
+         this.osu = osu;
+         this.session = null;
+      }
+      
+      private PassivationCheck(ClusteredSession session)
+      {
+         assert session != null : "session is null";
+         
+         this.realId = session.getRealId();
+         this.session = session;
+         this.osu = null;
+      }
+      
+      private long getLastUpdate()
+      {
+         return osu == null ? session.getLastAccessedTimeInternal() : osu.updateTime;
+      }
+      
+      private void passivate()
+      {
+         if (osu == null)
+         {
+            JBossCacheManager.this.processSessionPassivation(realId);
+         }
+         else
+         {
+            JBossCacheManager.this.processUnloadedSessionPassivation(realId, osu);
+         }
+      }
+      
+      private String getRealId()
+      {
+         return realId;
+      }
+      
+      private boolean isUnloaded()
+      {
+         return osu != null;
+      }
+
+      // This is what causes sorting based on lastAccessed
+      public int compareTo(PassivationCheck o)
+      {
+         long thisVal = getLastUpdate();
+         long anotherVal = o.getLastUpdate();
+         return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
+      }
+      
+      
+   }
 }




More information about the jboss-cvs-commits mailing list