[jboss-cvs] JBossAS SVN: r64678 - trunk/tomcat/src/main/org/jboss/web/tomcat/service/session.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Sat Aug 18 11:04:17 EDT 2007
Author: bstansberry at jboss.com
Date: 2007-08-18 11:04:16 -0400 (Sat, 18 Aug 2007)
New Revision: 64678
Added:
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListenerBase.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/PassivationListener.java
Modified:
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListener.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManagerMBean.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheService.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManagerMBean.java
Log:
[JBAS-4613] JBossCacheManager active session count should include backup sessions
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListener.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListener.java 2007-08-18 14:58:08 UTC (rev 64677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListener.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -36,46 +36,21 @@
import org.jboss.logging.Logger;
@org.jboss.cache.notifications.annotation.CacheListener
-public class CacheListener
+public class CacheListener extends CacheListenerBase
{
- // 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
- private static final int SESSION_FQN_SIZE = SESSION_ID_FQN_INDEX + 1;
// Element within an FQN that is the root of a Pojo attribute map
private static final int POJO_ATTRIBUTE_FQN_INDEX = SESSION_ID_FQN_INDEX + 1;
// Element within an FQN that is the root of an individual Pojo attribute
private static final int POJO_KEY_FQN_INDEX = POJO_ATTRIBUTE_FQN_INDEX + 1;
// Size of an Fqn that points to the root of a session
private static final int POJO_KEY_FQN_SIZE = POJO_KEY_FQN_INDEX + 1;
- // The index of the root of a buddy backup subtree
- private static final int BUDDY_BACKUP_ROOT_OWNER_INDEX = BuddyManager.BUDDY_BACKUP_SUBTREE_FQN.size();
- // 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;
-
private static Logger log_ = Logger.getLogger(CacheListener.class);
- private JBossCacheManager manager_;
- private String webapp_;
- private String hostname_;
private boolean fieldBased_;
- // When trying to ignore unwanted notifications, do we check for local activity first?
- private boolean disdainLocalActivity_;
CacheListener(JBossCacheWrapper wrapper, JBossCacheManager manager, String hostname, String webapp)
- {
- manager_ = manager;
- hostname_ = hostname;
- webapp_ = webapp;
- ReplicationGranularity granularity = manager_.getReplicationGranularity();
- fieldBased_ = (granularity == ReplicationGranularity.FIELD);
- // TODO decide if disdaining local activity is always good for REPL_ASYNC
- disdainLocalActivity_ = (granularity == ReplicationGranularity.SESSION);; // for now
+ {
+ super(manager, hostname, webapp);
+ fieldBased_ = (manager_.getReplicationGranularity() == ReplicationGranularity.FIELD);
}
// --------------- TreeCacheListener methods ------------------------------------
@@ -123,34 +98,17 @@
if (pre || isLocal)
return;
-// // 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
if (!isFqnSessionRootSized(fqn, isBuddy))
return;
-// if (!disdainLocalActivity_)
-// {
-// if (SessionReplicationContext.isLocallyActive())
-// return;
-// }
-
// We only care if this is for our webapp
if (!isFqnForOurWebapp(fqn, isBuddy))
return;
// Query if we have version value in the distributed cache.
// If we have a version value, compare the version and invalidate if necessary.
- // TODO get the key from the passed in data map!!
-// Integer version = (Integer)cacheWrapper_.get(fqn, JBossCacheService.VERSION_KEY);
Integer version = (Integer)data.get(JBossCacheService.VERSION_KEY);
if(version != null)
{
@@ -207,65 +165,13 @@
// BES -- 2007/07/03 Not sure what this means
}
- 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
- }
-
- return false;
- }
-
- private static boolean isFqnSessionRootSized(Fqn fqn, boolean isBuddy)
- {
- return fqn.size() == (isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_FQN_SIZE : SESSION_FQN_SIZE);
- }
-
private static boolean isFqnPojoKeySized(Fqn fqn, boolean isBuddy)
{
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
- {
- 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);
- }
}
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListenerBase.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListenerBase.java (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListenerBase.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -0,0 +1,78 @@
+package org.jboss.web.tomcat.service.session;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.buddyreplication.BuddyManager;
+
+public class CacheListenerBase
+{
+
+ private static final int JSESSION_FQN_INDEX = 0;
+ private static final int HOSTNAME_FQN_INDEX = 1;
+ private static final int WEBAPP_FQN_INDEX = 2;
+ protected static final int SESSION_ID_FQN_INDEX = 3;
+ private static final int SESSION_FQN_SIZE = SESSION_ID_FQN_INDEX + 1;
+ private static final int BUDDY_BACKUP_ROOT_OWNER_INDEX = BuddyManager.BUDDY_BACKUP_SUBTREE_FQN.size();
+ protected static final int BUDDY_BACKUP_ROOT_OWNER_SIZE = BUDDY_BACKUP_ROOT_OWNER_INDEX + 1;
+ protected JBossCacheManager manager_;
+ private String webapp_;
+ private String hostname_;
+
+ CacheListenerBase(JBossCacheManager manager, String hostname, String webapp)
+ {
+ manager_ = manager;
+ hostname_ = hostname;
+ webapp_ = webapp;
+ }
+
+ protected 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
+ }
+
+ return false;
+ }
+
+ protected static boolean isFqnSessionRootSized(Fqn fqn, boolean isBuddy)
+ {
+ return fqn.size() == (isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_FQN_SIZE : SESSION_FQN_SIZE);
+ }
+
+ protected 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);
+ }
+
+ protected static boolean isBuddyFqn(Fqn fqn)
+ {
+ try
+ {
+ 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.
+ */
+ protected static String getBuddyOwner(Fqn fqn)
+ {
+ return (String) fqn.get(BUDDY_BACKUP_ROOT_OWNER_INDEX);
+ }
+}
\ No newline at end of file
Property changes on: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/CacheListenerBase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
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 2007-08-18 14:58:08 UTC (rev 64677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -28,8 +28,8 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
@@ -45,6 +45,7 @@
import org.apache.catalina.Valve;
import org.apache.catalina.core.ContainerBase;
import org.jboss.cache.CacheException;
+import org.jboss.cache.pojo.PojoCache;
import org.jboss.metadata.WebMetaData;
import org.jboss.mx.util.MBeanServerLocator;
@@ -82,8 +83,16 @@
/**
* Id/timestamp of sessions in cache that we haven't loaded
*/
- private Map unloadedSessions_ = new ConcurrentHashMap();
-
+ private Map<String, OwnedSessionUpdate> unloadedSessions_ =
+ new ConcurrentHashMap<String, OwnedSessionUpdate>();
+
+ private AtomicInteger passivatedCount_ = new AtomicInteger();
+ private int maxPassivatedCount_;
+
+ private int maxLocalActiveCounter_;
+
+ private PojoCache pojoCache_;
+
/** Our TreeCache's ObjectName */
private String cacheObjectNameString_ = "jboss.cache:service=TomcatClusteringCache";
@@ -131,6 +140,12 @@
{
super();
}
+
+ public JBossCacheManager(PojoCache cache)
+ {
+ super();
+ this.pojoCache_ = cache;
+ }
/**
* Initializes this Manager when running in embedded mode.
@@ -148,7 +163,15 @@
this.replicationFieldBatchMode_ =
webMetaData.getReplicationFieldBatchMode() ? Boolean.TRUE : Boolean.FALSE;
- proxy_ = new JBossCacheService(cacheObjectNameString_);
+ PojoCache pc = getPojoCache();
+ if (pc == null)
+ {
+ proxy_ = new JBossCacheService(cacheObjectNameString_);
+ }
+ else
+ {
+ proxy_ = new JBossCacheService(pc);
+ }
// Confirm our replication granularity is compatible with the cache
// Throws ISE if not
@@ -419,6 +442,49 @@
return sb.toString();
}
+ public long getLocalActiveSessionCount()
+ {
+ return activeCounter_;
+ }
+
+ public long getMaxLocalActiveSessionCount()
+ {
+ return super.getMaxActiveSessionCount();
+ }
+
+ public long getMaxPassivatedSessionCount()
+ {
+ return 0;
+ }
+
+ public long getPassivatedSessionCount()
+ {
+ return passivatedCount_.get();
+// return passivatedSessions_.size();
+ }
+
+ @Override
+ public int getActiveSessions()
+ {
+ return calcActiveSessions();
+ }
+
+ @Override
+ public long getActiveSessionCount()
+ {
+ return calcActiveSessions();
+ }
+
+ public long getPassivationMaxIdleTime()
+ {
+ return passivationMaxIdleTime_;
+ }
+
+ public long getPassivationMinIdleTime()
+ {
+ return passivationMinIdleTime_;
+ }
+
// Manager-methods -------------------------------------
/**
@@ -437,6 +503,8 @@
{
startUnembedded();
}
+
+ log_.debug("JBossCacheManager for " + getContainer().getName() + " started");
}
public void stop() throws LifecycleException
@@ -463,6 +531,12 @@
snapshotManager_.stop();
+ // Clean up maps
+ sessions_.clear();
+ unloadedSessions_.clear();
+
+ passivatedCount_.set(0);
+
started_ = false;
// Notify our interested LifecycleListeners
@@ -483,6 +557,7 @@
*/
protected void clearSessions()
{
+ boolean passivation = isPassivationEnabled();
// First, the sessions we have actively loaded
ClusteredSession[] sessions = findLocalSessions();
for(int i=0; i < sessions.length; i++)
@@ -500,10 +575,9 @@
boolean localOnly = true;
try
{
- if(isPassivationEnabled() && ses.isValid())
- {
-
- processSessionPassivation(ses.getRealId(), this.getContainer().getParent().getName());
+ if(passivation && ses.isValid())
+ {
+ processSessionPassivation(ses.getRealId());
}
else
{
@@ -522,19 +596,28 @@
// ref to the session by clearing its internal state
ses.recycle();
}
- }
-
- if(!isPassivationEnabled())
+ }
+
+ Set<Map.Entry<String, OwnedSessionUpdate>> unloaded =
+ unloadedSessions_.entrySet();
+ for (Iterator<Map.Entry<String, OwnedSessionUpdate>> it = unloaded.iterator(); it.hasNext();)
{
-// Next, the local copy of the distributed cache
- Map unloaded = new HashMap(unloadedSessions_);
- Set keys = unloaded.keySet();
- for (Iterator it = keys.iterator(); it.hasNext(); )
+ Map.Entry<String, OwnedSessionUpdate> entry = it.next();
+ String realId = entry.getKey();
+ if (passivation)
{
- String realId = (String) it.next();
- proxy_.removeSessionLocal(realId);
- unloadedSessions_.remove(realId);
+ OwnedSessionUpdate osu = entry.getValue();
+ // Ignore the marker entries for our passivated sessions
+ if (!osu.passivated)
+ {
+ proxy_.evictSession(realId, osu.owner);
+ }
}
+ else
+ {
+ proxy_.removeSessionLocal(realId);
+ }
+ it.remove();
}
}
@@ -558,36 +641,35 @@
* exceeds the maximum number allowed
*/
public Session createSession(String sessionId)
- {
- if (log_.isTraceEnabled())
- {
- log_.trace("createSession: active sessions = " + activeCounter_ +
- " , session map size = " + sessions_.size() +
- " and max allowed sessions = " + maxActive_);
- }
+ {
+ // First check if we've reached the max allowed sessions,
+ // then try to expire/passivate sessions to free memory
+ // maxActive_ -1 is unlimited
// We check here for maxActive instead of in add(). add() gets called
// when we load an already existing session from the distributed cache
// (e.g. in a failover) and we don't want to fail in that situation.
- // JBCLUSTER-15
- // first check if passivation is enabled and reached the max allowed sessions,
- /// then try to expire/passivate sessions to free memory
- if(maxActive_ != -1 && sessions_.size() >= maxActive_ && isPassivationEnabled())
+ if(maxActive_ != -1 && calcActiveSessions() >= maxActive_)
{
+ if (log_.isTraceEnabled())
+ {
+ log_.trace("createSession(): active sessions = " + calcActiveSessions() +
+ " and max allowed sessions = " + maxActive_);
+ }
processExpires();
+
+ if (calcActiveSessions() >= maxActive_)
+ {
+ // Exceeds limit. We need to reject it.
+ rejectedCounter_++;
+ // Catalina api does not specify what happens
+ // but we will throw a runtime exception for now.
+ String msgEnd = (sessionId == null) ? "" : " id " + sessionId;
+ throw new IllegalStateException("createSession(): number of " +
+ "active sessions exceeds the maximum limit: " +
+ maxActive_ + " when trying to create session" + msgEnd);
+ }
}
- // maxActive_ -1 is unlimited
- if (maxActive_ != -1 && sessions_.size() >= maxActive_)
- {
- // Exceeds limit. We need to reject it.
- rejectedCounter_++;
- // Catalina api does not specify what happens
- // but we will throw a runtime exception for now.
- String msgEnd = (sessionId == null) ? "" : " id " + sessionId;
- throw new IllegalStateException("JBossCacheManager.createSession(): number of " +
- "active sessions exceeds the maximum limit: " +
- maxActive_ + " when trying to create session" + msgEnd);
- }
ClusteredSession session = createEmptyClusteredSession();
@@ -618,10 +700,7 @@
log_.trace("Created a ClusteredSession with id: " + sessionId);
}
- createdCounter_++;
- // JBCLUSTER-15 - if we have created a session it must be handled by this manager
- // therefore we must increment the active counter
- activeCounter_++;
+ createdCounter_++; // the call to add() handles the other counters
// Add this session to the set of those potentially needing replication
SessionReplicationContext.bindSession(session, snapshotManager_);
@@ -718,9 +797,7 @@
storeSession(session);
}
- activeCounter_++;
- if (activeCounter_ > maxActiveCounter_)
- maxActiveCounter_++;
+ calcActiveSessions();
if (log_.isTraceEnabled())
{
@@ -918,7 +995,7 @@
sessions_.remove(realId);
stats_.removeStats(realId);
- activeCounter_--;
+// activeCounter_--;
}
}
}
@@ -962,7 +1039,7 @@
// It's a bit ad-hoc to do it here. But since we currently call
// this when session expires ...
expiredCounter_++;
- activeCounter_--;
+// activeCounter_--;
}
}
}
@@ -994,31 +1071,34 @@
{
// JBCLUSTER-15
// We need to check for maxActive first before attempting to create a new session
- if (log_.isTraceEnabled())
- {
- log_.trace("createSession: active sessions = " + activeCounter_ +
- " , session map size = " + sessions_.size() +
- " and max allowed sessions = " + maxActive_);
- }
- // first check if passivation is enabled and reached the max allowed sessions,
- /// then try to expire/passivate sessions to free memory
- if(maxActive_ != -1 && sessions_.size() >= maxActive_ && isPassivationEnabled())
- {
- processExpires();
- }
- // maxActive_ -1 is unlimited
- if (maxActive_ != -1 && sessions_.size() >= maxActive_)
- {
- // Exceeds limit. We need to reject it.
- rejectedCounter_++;
- // Catalina api does not specify what happens
- // but we will throw a runtime exception for now.
- String msgEnd = (realId == null) ? "" : " id " + realId;
- throw new IllegalStateException("JBossCacheManager.createSession(): number of " +
- "active sessions exceeds the maximum limit: " +
- maxActive_ + " when trying to load session" + msgEnd);
- }
+// if(maxActive_ != -1
+// && isPassivationEnabled()
+// && calcActiveSessions() >= maxActive_)
+// {
+// if (log_.isTraceEnabled())
+// {
+// log_.trace("loadSession(): active sessions = " + calcActiveSessions() +
+// " and max allowed sessions = " + maxActive_);
+// }
+//
+// processExpires();
+// }
+ // BES 2007/08/01 DO NOT REJECT A SESSION HERE -- FAILOVER MUST WORK
+
+// // maxActive_ -1 is unlimited
+// if (maxActive_ != -1 && sessions_.size() >= maxActive_)
+// {
+// // Exceeds limit. We need to reject it.
+// rejectedCounter_++;
+// // Catalina api does not specify what happens
+// // but we will throw a runtime exception for now.
+// String msgEnd = (realId == null) ? "" : " id " + realId;
+// throw new IllegalStateException("JBossCacheManager.createSession(): number of " +
+// "active sessions exceeds the maximum limit: " +
+// maxActive_ + " when trying to load session" + msgEnd);
+// }
+
// This is either the first time we've seen this session on this
// server, or we previously expired it and have since gotten
// a replication message from another server
@@ -1215,17 +1295,29 @@
*/
protected void processExpires()
{
- if (maxInactiveInterval_ < 0)
+ boolean expire = maxInactiveInterval_ >= 0;
+ boolean passivate = isPassivationEnabled();
+ if (!expire && !passivate)
{
return;
}
+
+ long expirationInterval = maxInactiveInterval_ * 1000L;
+ long passivationMax = passivationMaxIdleTime_ * 1000L;
+ long passivationMin = passivationMinIdleTime_ * 1000L;
- if (log_.isTraceEnabled())
- {
- log_.trace("processExpires():max active sessions = " + maxActive_);
- log_.trace("processExpires(): passivation mode = " + isPassivationEnabled());
+ boolean trace = log_.isTraceEnabled();
+ if (trace)
+ {
log_.trace("processExpires(): Looking for sessions that have expired ...");
+ log_.trace("processExpires(): active sessions = " + calcActiveSessions());
+ log_.trace("processExpires(): expired sessions = " + expiredCounter_);
+ if (passivate)
+ {
+ log_.trace("processExpires(): passivated count = " + getPassivatedSessionCount());
+ }
}
+
try
{
// First, handle the sessions we are actively managing
@@ -1241,60 +1333,51 @@
continue;
}
- // JBAS-2403. Check for outdated sessions where we think
- // the local copy has timed out. If found, refresh the
- // session from the cache in case that might change the timeout
- if (session.isOutdated() && !(session.isValid(false)))
+ if (expire)
{
- // JBAS-2792 don't assign the result of loadSession to session
- // just update the object from the cache or fall through if
- // the session has been removed from the cache
- loadSession(session.getRealId());
+ // JBAS-2403. Check for outdated sessions where we think
+ // the local copy has timed out. If found, refresh the
+ // session from the cache in case that might change the timeout
+ if (session.isOutdated() && !(session.isValid(false)))
+ {
+ // JBAS-2792 don't assign the result of loadSession to session
+ // just update the object from the cache or fall through if
+ // the session has been removed from the cache
+ loadSession(session.getRealId());
+ }
+
+ // Do a normal invalidation check that will expire the
+ // session if it has timed out
+ // DON'T SYNCHRONIZE on session here -- isValid() and
+ // expire() are meant to be multi-threaded and synchronize
+ // properly internally; synchronizing externally can lead
+ // to deadlocks!!
+ if (!session.isValid()) continue;
}
-
- // Do a normal invalidation check that will expire any
- // sessions that have timed out
- // DON'T SYNCHRONIZE on session here -- isValid() and
- // expire() are meant to be multi-threaded and synchronize
- // properly internally; synchronizing externally can lead
- // to deadlocks!!
- if (!session.isValid()) continue;
-
// JBCLUSTER-15
- if (log_.isTraceEnabled())
+
+ // we now have a valid session; see if we need to passivate it
+ if (passivate)
{
- log_.trace("processExpires(): Checking passivation for session " + session.getId());
- }
- // now that we have valid session, see if we need to
- // passivate it based on the configurable passivation min and max Idle time
- if (isPassivationEnabled())
- {
long timeNow = System.currentTimeMillis();
- int timeIdle = (int) ((timeNow - session.getLastAccessedTimeInternal()) / 1000L);
+ 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 (passivationMaxIdleTime_ >= 0 && timeIdle > passivationMaxIdleTime_)
+ if (passivationMax >= 0
+ && timeIdle > passivationMax)
{
- if(log_.isTraceEnabled())
- {
- log_.trace("JBossCacheManager.processExpires() passivating session " + session.getRealId());
- }
- processSessionPassivation(session.getRealId(), this.getContainer().getParent().getName());
+ processSessionPassivation(session.getRealId());
}
- // If the session didn't exceed the passivationMaxIdleTime_, See
+ // 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 (maxActive_ > 0 && passivationMinIdleTime_ > 0 && sessions_.size()> maxActive_)
+ else if (maxActive_ > 0
+ && passivationMin > 0
+ && calcActiveSessions() >= maxActive_
+ && timeIdle > passivationMin)
{
- if(timeIdle > passivationMinIdleTime_)
- {
- if(log_.isTraceEnabled())
- {
- log_.trace("JBossCacheManager.processExpires() passivating session " + session.getRealId());
- }
- processSessionPassivation(session.getRealId(), this.getContainer().getParent().getName());
- }
- }
+ processSessionPassivation(session.getRealId());
+ }
}
}
@@ -1314,28 +1397,49 @@
for (Iterator it = entries.iterator(); it.hasNext(); )
{
Map.Entry entry = (Map.Entry) it.next();
+ String realId = (String) entry.getKey();
OwnedSessionUpdate osu = (OwnedSessionUpdate) entry.getValue();
- int elapsed = (int) ((now - osu.updateTime) / 1000L);
- if (elapsed >= maxInactiveInterval_)
+ // Ignore marker entries for our own passivated sessions
+ if (osu.passivated)
+ continue;
+ long elapsed = (now - osu.updateTime);
+ try
{
- String realId = (String) entry.getKey();
- try
+ if (expire && elapsed >= expirationInterval)
{
proxy_.removeSessionLocal(realId, osu.owner);
unloadedSessions_.remove(realId);
}
-
- // JBClUSTER-15
- // we don't need to worry about session passivation here, since the
- // method processSessionPassivation() takes care of unloadedSessions_ map
- // when it receives a notification of passivation event happened in the
- // distributed store from the CacheListener
- catch (Exception ex)
+ else if (passivate)
{
- log_.error("processExpire(): failed removing unloaded session " +
- realId + " with exception: " +
- ex, ex);
+ // if maxIdle time configured, means that we need to passivate sessions that have
+ // exceeded the max allowed idle time
+ if (passivationMax >= 0
+ && elapsed > passivationMax)
+ {
+ processUnloadedSessionPassivation(realId, osu);
+ }
+ // 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 (maxActive_ > 0
+ && passivationMin >= 0
+ && calcActiveSessions() >= maxActive_
+ && elapsed >= passivationMin)
+ {
+ processUnloadedSessionPassivation(realId, osu);
+ }
}
+ }
+ // JBClUSTER-15
+ // we don't need to worry about session passivation here, since the
+ // method processSessionPassivation() takes care of unloadedSessions_ map
+ // when it receives a notification of passivation event happened in the
+ // distributed store from the CacheListener
+ catch (Exception ex)
+ {
+ log_.error("processExpires(): failed removing unloaded session " +
+ realId, ex);
}
}
}
@@ -1343,6 +1447,17 @@
{
log_.error("processExpires: failed with exception: " + ex, ex);
}
+
+ if (trace)
+ {
+ log_.trace("processExpires(): Completed ...");
+ log_.trace("processExpires(): active sessions = " + calcActiveSessions());
+ log_.trace("processExpires(): expired sessions = " + expiredCounter_);
+ if (passivate)
+ {
+ log_.trace("processExpires(): passivated count = " + getPassivatedSessionCount());
+ }
+ }
}
public void processRemoteAttributeRemoval(String realId, String attrKey)
@@ -1420,19 +1535,63 @@
// Remove any stats for this session
stats_.removeStats(realId);
-
- // Update counter.
- activeCounter_--;
}
}
- public void processSessionPassivation(String realId, String dataOwner)
+ private void sessionPassivated()
{
+ int pc = passivatedCount_.incrementAndGet();
+ if (pc > maxPassivatedCount_)
+ maxPassivatedCount_ = pc;
+ }
+
+ public void sessionActivated()
+ {
+ int pc = passivatedCount_.decrementAndGet();
+ // Correct for drift since we don't know the true passivation
+ // count when we started. We can get activations of sessions
+ // we didn't know were passivated.
+ if (pc < 0)
+ {
+ // Just reverse our decrement.
+ passivatedCount_.incrementAndGet();
+ }
+ }
+
+ /**
+ * Calculates the number of active sessions, and updates
+ * the max # of local active sessions and max # of sessions.
+ * <p>
+ * Call this method when a new session is added or when an
+ * accurate count of active sessions is needed.
+ * </p>
+ *
+ * @return the size of the sessions map + the size of the unloaded sessions
+ * map - the count of passivated sessions
+ */
+ private int calcActiveSessions()
+ {
+ activeCounter_ = sessions_.size();
+ if (activeCounter_ > maxLocalActiveCounter_)
+ maxLocalActiveCounter_ = activeCounter_;
+
+ int count = activeCounter_ + unloadedSessions_.size() - passivatedCount_.get();
+ if (count > maxActiveCounter_)
+ maxActiveCounter_ = count;
+ return count;
+ }
+
+ /**
+ * Session passivation logic for an actively managed session.
+ *
+ * @param realId the session id, minus any jvmRoute
+ */
+ private void processSessionPassivation(String realId)
+ {
// get the session from the local map
ClusteredSession session = findLocalSession(realId);
- // only remove actively managed session and add to the unloaded sessions
+ // Remove actively managed session and add to the unloaded sessions
// if it's already unloaded session (session == null) don't do anything,
- // the evict notification will tell the server that has the session to remove it.
if (session != null)
{
synchronized (session)
@@ -1448,13 +1607,16 @@
SessionReplicationContext.startCacheActivity();
session.passivate();
proxy_.evictSession(realId);
+ sessionPassivated();
}
finally {
SessionReplicationContext.finishCacheActivity();
}
-
+
+ // Put the session in the unloadedSessions map. This will
+ // expose the session to regular invalidation.
Object obj = unloadedSessions_.put(realId,
- new OwnedSessionUpdate(dataOwner, session.getLastAccessedTime()));
+ new OwnedSessionUpdate(null, session.getLastAccessedTime(), true));
if (log_.isTraceEnabled())
{
if (obj == null)
@@ -1467,12 +1629,42 @@
}
}
sessions_.remove(realId);
- stats_.removeStats(realId);
+// stats_.removeStats(realId);
}
- activeCounter_--;
+// activeCounter_--;
}
+ else if (log_.isTraceEnabled())
+ {
+ log_.trace("processSessionPassivation(): could not find session " + realId);
+ }
}
+
+ /**
+ * Session passivation logic for sessions only in the distributed store.
+ *
+ * @param realId the session id, minus any jvmRoute
+ */
+ private void processUnloadedSessionPassivation(String realId, OwnedSessionUpdate osu)
+ {
+ if (log_.isTraceEnabled())
+ {
+ log_.trace("Passivating session with id: " + realId);
+ }
+ try {
+ // Tell the proxy to ignore cache notifications we are about
+ // to generate for this session.
+ SessionReplicationContext.startCacheActivity();
+ proxy_.evictSession(realId, osu.owner);
+ osu.passivated = true;
+ sessionPassivated();
+ }
+ finally {
+ SessionReplicationContext.finishCacheActivity();
+ }
+
+ }
+
/**
* Gets the session id with any jvmRoute removed.
*
@@ -1495,12 +1687,13 @@
protected void unloadedSessionChanged(String realId, String dataOwner)
{
Object obj = unloadedSessions_.put(realId,
- new OwnedSessionUpdate(dataOwner, System.currentTimeMillis()));
+ new OwnedSessionUpdate(dataOwner, System.currentTimeMillis(), false));
if (log_.isTraceEnabled())
{
if (obj == null)
{
log_.trace("New session " + realId + " added to unloaded session map");
+ calcActiveSessions();
}
else
{
@@ -1510,15 +1703,16 @@
}
/**
- * Returns true if the passivation mode is set to true in JBoss-web.xml and JBoss Cache passivation
+ * Returns true if the passivation mode is set to true in jboss-web.xml and JBoss Cache passivation
* has been enabled with proper configured cache loader. Otherwise, it returns false
*
* @return
*/
- protected boolean isPassivationEnabled()
+ public boolean isPassivationEnabled()
{
return (passivationMode_ && proxy_.isCachePassivationEnabled());
}
+
// ---------------------------------------------------- Lifecyle Unembedded
/**
@@ -1626,7 +1820,15 @@
// Create the JBossCacheService
try
{
- proxy_ = new JBossCacheService(cacheObjectNameString_);
+ PojoCache pc = getPojoCache();
+ if (pc == null)
+ {
+ proxy_ = new JBossCacheService(cacheObjectNameString_);
+ }
+ else
+ {
+ proxy_ = new JBossCacheService(pc);
+ }
// Confirm our replication granularity is compatible with the cache
// Throws ISE if not
@@ -1763,15 +1965,23 @@
*/
private void initializeUnloadedSessions() throws CacheException
{
- Map sessions = proxy_.getSessionIds();
+ Map<String, String> sessions = proxy_.getSessionIds();
if (sessions != null)
{
+ boolean passivateExcess = isPassivationEnabled()
+ && maxActive_ > 0
+ && passivationMinIdleTime_ >= 0;
long now = System.currentTimeMillis();
- for (Iterator it = sessions.entrySet().iterator(); it.hasNext(); )
+ for (Iterator<Map.Entry<String, String>> it = sessions.entrySet().iterator(); it.hasNext(); )
{
- Map.Entry entry = (Entry) it.next();
- unloadedSessions_.put(entry.getKey(),
- new OwnedSessionUpdate((String) entry.getValue(), now));
+ Map.Entry<String, String> entry = it.next();
+ String realId = entry.getKey();
+ OwnedSessionUpdate osu = new OwnedSessionUpdate(entry.getValue(), now, false);
+ unloadedSessions_.put(realId, osu);
+ if (passivateExcess && calcActiveSessions() > maxActive_)
+ {
+ processUnloadedSessionPassivation(realId, osu);
+ }
}
}
}
@@ -1909,17 +2119,24 @@
return null;
}
}
+
+ public PojoCache getPojoCache()
+ {
+ return pojoCache_;
+ }
private class OwnedSessionUpdate
{
String owner;
long updateTime;
+ boolean passivated;
- OwnedSessionUpdate(String owner, long updateTime)
+ OwnedSessionUpdate(String owner, long updateTime, boolean passivated)
{
this.owner = owner;
this.updateTime = updateTime;
+ this.passivated = passivated;
}
}
}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManagerMBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManagerMBean.java 2007-08-18 14:58:08 UTC (rev 64677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManagerMBean.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -125,4 +125,57 @@
* @return a comma-separated list of session ids
*/
String listLocalSessionIds();
+
+ /**
+ * Gets the count of sessions known to this manager, excluding those
+ * in the distributed stored that have not been accessed on this node.
+ */
+ long getLocalActiveSessionCount();
+
+ /**
+ * Gets the highest value seen for {@link #getLocalSessionCount()}
+ */
+ long getMaxLocalActiveSessionCount();
+
+ /**
+ * Gets whether passivation was enabled in jboss-web.xml and in the
+ * underlying cache.
+ *
+ * @return <code>true</code> if passivation is enabled in both
+ * jboss-web.xml and in the cache; <code>false</code> otherwise
+ */
+ boolean isPassivationEnabled();
+
+ /**
+ * Gets the number of passivated sessions
+ *
+ * @return
+ */
+ long getPassivatedSessionCount();
+
+ /**
+ * Gets the highest number of passivated sessions seen.
+ *
+ * @return
+ */
+ long getMaxPassivatedSessionCount();
+
+ /**
+ * Elapsed time after which an inactive session will be passivated
+ * to persistent storage if {@link #isPassivationEnabled() passivation is
+ * enabled}.
+ *
+ * @return
+ */
+ long getPassivationMaxIdleTime();
+
+ /**
+ * Elapsed time after which an inactive session will be passivated
+ * to persistent storage if {@link #isPassivationEnabled() passivation is
+ * enabled} and the manager needs to passivate sessions early in order to
+ * comply with a {@link JBossManagerMBean#getMaxActiveAllowed()} setting.
+ *
+ * @return
+ */
+ long getPassivationMinIdleTime();
}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheService.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheService.java 2007-08-18 14:58:08 UTC (rev 64677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheService.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -40,7 +40,7 @@
import javax.management.ObjectName;
import javax.transaction.TransactionManager;
-import org.apache.catalina.Context;
+import org.apache.catalina.Container;
import org.jboss.aspects.patterns.observable.Observer;
import org.jboss.aspects.patterns.observable.Subject;
import org.jboss.cache.Cache;
@@ -99,8 +99,22 @@
// the TreeCache do it?
private boolean useTreeCacheMarshalling_ = false;
+ // Are we configured for passivation?
+ private boolean usePassivation_ = false;
private WeakHashMap typeMap = new WeakHashMap();
+ public JBossCacheService(PojoCache cache)
+ {
+ if (cache == null)
+ {
+ throw new IllegalArgumentException("cache cannot be null");
+ }
+
+ pojoCache_ = cache;
+
+ init();
+ }
+
public JBossCacheService(String treeCacheObjectName) throws ClusteringNotSupportedException
{
// Find JBossCacheService
@@ -134,17 +148,27 @@
throw new ClusteringNotSupportedException(str);
}
+ init();
+ }
+
+ private void init()
+ {
plainCache_ = pojoCache_.getCache();
cacheWrapper_ = new JBossCacheWrapper(pojoCache_);
-
+
useTreeCacheMarshalling_ = plainCache_.getConfiguration().isUseRegionBasedMarshalling();
+ CacheLoaderConfig clc = plainCache_.getConfiguration().getCacheLoaderConfig();
+ if(clc != null)
+ {
+ usePassivation_ = (clc.isPassivation() && !clc.isShared());
+ }
}
public void start(ClassLoader tcl, JBossCacheManager manager)
{
manager_ = manager;
- Context webapp = (Context) manager_.getContainer();
+ Container webapp = manager_.getContainer();
String path = webapp.getName();
if( path.length() == 0 || path.equals("/")) {
// If this is root.
@@ -172,23 +196,25 @@
// Listen for cache changes
cacheListener_ = new CacheListener(cacheWrapper_, manager_, hostName_, webAppPath_);
plainCache_.addCacheListener(cacheListener_);
-
- // register the tcl and bring over the state for the webapp
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
- Fqn pathFqn = new Fqn( objs );
- try {
- if(useTreeCacheMarshalling_)
+
+ if(useTreeCacheMarshalling_)
+ {
+ // register the tcl and bring over the state for the webapp
+ try
{
+ Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
+ Fqn pathFqn = new Fqn( objs );
log_.debug("UseMarshalling is true. We will register the fqn: " +
pathFqn + " with class loader" +tcl +
" and activate the webapp's Region");
Region region = plainCache_.getRegion(pathFqn, true);
region.registerContextClassLoader(tcl);
- region.activate();
+ region.activate();
}
- } catch (Exception ex)
- {
- throw new RuntimeException("Can't register class loader", ex);
+ catch (Exception ex)
+ {
+ throw new RuntimeException("Can't register class loader", ex);
+ }
}
// We require the cache tm to be BatchModeTransactionManager now.
@@ -199,13 +225,15 @@
" Please check the jboss-web-cluster-service.xml TransactionManagerClassLookup field.");
}
- if(isCachePassivationEnabled())
+ if(manager_.isPassivationEnabled())
{
- log_.debug("JBossCache passivation is enabled");
+ log_.debug("Passivation is enabled");
+ PassivationListener pl = new PassivationListener(manager_, hostName_, webAppPath_);
+ plainCache_.addCacheListener(pl);
}
else
{
- log_.debug("JBossCache passivation is disabled");
+ log_.debug("Passivation is disabled");
}
}
@@ -238,7 +266,11 @@
}
// remove session data
- cacheWrapper_.removeLocalSubtree(pathFqn);
+ // BES 2207/08/18 Can't do this as it will
+ // 1) blow away passivated sessions
+ // 2) leave the cache in an inconsistent state if the war
+ // is restarted
+// cacheWrapper_.removeLocalSubtree(pathFqn);
}
/**
@@ -383,18 +415,21 @@
}
cacheWrapper_.removeLocalSubtree(fqn);
}
- }
-
+ }
public void evictSession(String realId)
{
- Fqn fqn = getSessionFqn(realId);
+ evictSession(realId, null);
+ }
+
+ public void evictSession(String realId, String dataOwner)
+ {
+ Fqn fqn = dataOwner == null ? getSessionFqn(realId) : getSessionFqn(realId, dataOwner);
if(log_.isTraceEnabled())
{
log_.trace("evictSession(): evicting session from my distributed store. Fqn: " + fqn);
}
- cacheWrapper_.evictSubtree(fqn);
-
+ cacheWrapper_.evictSubtree(fqn);
}
public boolean exists(String realId)
@@ -513,9 +548,9 @@
* the session as value (or a <code>null</code> value if buddy
* replication is not enabled.) Will not return <code>null</code>.
*/
- public Map getSessionIds() throws CacheException
+ public Map<String, String> getSessionIds() throws CacheException
{
- Map result = new HashMap();
+ Map<String, String> result = new HashMap<String, String>();
Node bbRoot = plainCache_.getRoot().getChild(BUDDY_BACKUP_FQN);
if (bbRoot != null)
@@ -945,15 +980,7 @@
public boolean isCachePassivationEnabled()
{
- CacheLoaderConfig clc = plainCache_.getConfiguration().getCacheLoaderConfig();
- if(clc != null)
- {
- return (clc.isPassivation() && !clc.isShared());
- }
- else
- {
- return false;
- }
+ return usePassivation_;
}
private Fqn getFieldFqn(String id, String key)
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java 2007-08-18 14:58:08 UTC (rev 64677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -92,15 +92,16 @@
protected boolean passivationMode_ = false;
/**
- * Min time (seconds) the session must be idle since lastAccesstime before it's eligable for passivation
- * This overrides maxActive_, to prevent thrashing if the there are lots of active sessions.
- * Setting to -1 means it's ignored
+ * Min time (milliseconds) the session must be idle since lastAccesstime before
+ * it's eligible for passivation if passivation is enabled and more
+ * than maxActive_ sessions are in memory.
+ * Setting to -1 means it's ignored.
*/
protected int passivationMinIdleTime_ = -1;
/**
- * Max time (seconds) the session must be idle since lastAccesstime before it's eligable for passivation
- * This overrides maxActive_, to prevent thrashing if the there are lots of active sessions.
+ * Max time (milliseconds) the session must be idle since lastAccesstime before
+ * it will be passivated if passivation is enabled.
* Setting to -1 means session should not be forced out.
*/
protected int passivationMaxIdleTime_ = -1;
@@ -142,14 +143,14 @@
*/
protected int sessionIdLength_ = 16;
- // Maximum of ative sessions allowed. -1 is unlimited.
+ // Maximum of active sessions allowed. -1 is unlimited.
protected int maxActive_ = -1;
// Number of sessions created by this manager
protected int createdCounter_ = 0;
// number of rejected sessions because the number active sessions exceeds maxActive
- protected int rejectedCounter_ = 0;
+ protected volatile int rejectedCounter_ = 0;
// Number of active sessions
protected int activeCounter_ = 0;
@@ -158,7 +159,7 @@
protected int maxActiveCounter_ = 0;
// number of expired session ids. Not sure what exactly does it mean in our clustered case.
- protected int expiredCounter_ = 0;
+ protected volatile int expiredCounter_ = 0;
protected long timeSinceLastReset_ = 0;
@@ -687,7 +688,6 @@
public void setContainer(Container container)
{
-
// De-register from the old Container (if any)
if ((this.container_ != null) && (this.container_ instanceof Context))
this.container_.removePropertyChangeListener(this);
@@ -858,7 +858,6 @@
throw new RuntimeException("JBossManager.load(): Method not implemented.");
}
-
public void backgroundProcess()
{
// Called from Catalina StandardEngine for every 60 seconds.
@@ -875,60 +874,8 @@
/**
* Go through all sessions and look if they have expired
*/
- protected void processExpires()
- {
- // What's the time?
-// long timeNow = System.currentTimeMillis();
+ protected abstract void processExpires();
- // Get all sessions
- Session sessions[] = findSessions();
- if (log_.isTraceEnabled())
- {
- log_.trace("Looking for sessions that have expired ...");
- }
-
- for (int i = 0; i < sessions.length; ++i)
- {
- ClusteredSession session = (ClusteredSession) sessions[i];
-
- // We only look at valid sessions. This will remove session if not valid already.
- if (!session.isValid())
- {
- continue;
- }
-
- /* I don't think it is right to check idle time based on lastAccessedTime since it may
- // remove some request that is currently in progress!!!
- // How long are they allowed to be idle?
- int maxInactiveInterval = session.getMaxInactiveInterval();
-
- // Negative values = never expire
- if( maxInactiveInterval < 0 )
- {
- continue;
- }
-
- // How long has this session been idle?
- int timeIdle =
- (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
-
- // Too long?
- if( timeIdle >= maxInactiveInterval )
- {
- try
- {
- log_.debug("Session with id = " + session.getId() + " has expired on local node");
- remove(session);
- }
- catch(Throwable t)
- {
- log_.error("Problems while expiring session with id = " + session.getId(), t);
- }
- }
- */
- }
- }
-
public void propertyChange(PropertyChangeEvent evt)
{
// TODO Need to handle it here.
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManagerMBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManagerMBean.java 2007-08-18 14:58:08 UTC (rev 64677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManagerMBean.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -53,7 +53,7 @@
long timeInSecondsSinceLastReset();
/**
- * Gets the number of sessions active on this node. Does not include
+ * Gets the number of sessions active on this node. This includes
* replicated sessions that have not been accessed on this node.
*/
long getActiveSessionCount();
@@ -79,28 +79,26 @@
/**
* Gets the highest number of sessions concurrently active on this node.
- * Does not include replicated sessions that have not been accessed on
+ * This includes replicated sessions that have not been accessed on
* this node.
*/
long getMaxActiveSessionCount();
/**
- * Gets the maximum number of active sessions that will concurrently be
- * allowed on this node. Does not include replicated sessions that have
- * not been accessed on this node.
+ * Gets the maximum number of {@link #getActiveSessionCount() active sessions}
+ * that will concurrently be allowed on this node. This includes replicated
+ * sessions that have not been accessed on this node.
*/
int getMaxActiveAllowed();
/**
* Sets the maximum number of active sessions that will concurrently be
- * allowed on this node. Does not include replicated sessions that have
- * not been accessed on this node.
+ * allowed on this node, excluding any sessions that have been passivated.
+ * This includes replicated sessions that have not been accessed on this
+ * node. If the {@link #getActiveSessionCount() active session count}
+ * exceeds this value and an attempt to create a new session is made,
+ * session creation will fail with an {@link IllegalStateException}.
*
- * <p>
- * Note that if sessions fail over to this node from other nodes, the max
- * number of active sessions may exceed this value.
- * </p>
- *
* @param max the max number of sessions, or <code>-1</code> if there is
* no limit.
*/
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/PassivationListener.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/PassivationListener.java (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/PassivationListener.java 2007-08-18 15:04:16 UTC (rev 64678)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.web.tomcat.service.session;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.notifications.annotation.NodeActivated;
+import org.jboss.cache.notifications.event.NodeActivatedEvent;
+
+/**
+ * Listener for JBoss Cache activation events. Triggers updates of
+ * the passivation counter.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision$
+ */
+ at org.jboss.cache.notifications.annotation.CacheListener
+public class PassivationListener extends CacheListenerBase
+{
+
+ PassivationListener(JBossCacheManager manager, String hostname, String webapp)
+ {
+ super(manager, hostname, webapp);
+ }
+
+ // NOTE: Don't track passivation from here -- we know in JBossCacheManager
+ // when we trigger a passivation. Avoid spurious listener callbacks to
+ // webapps that aren't interested.
+
+// @NodePassivated
+// public void nodePassivated(NodePassivatedEvent event)
+// {
+// Fqn fqn = event.getFqn();
+// if (isFqnForOurWebapp(fqn, isBuddyFqn(fqn)))
+// {
+// manager_.sessionPassivated();
+// }
+// }
+
+ // We do want activation callbacks, as JBossCacheManager can't readily
+ // track whether a cache read is going to result in an activation
+
+ @NodeActivated
+ public void nodeActivated(NodeActivatedEvent event)
+ {
+ Fqn fqn = event.getFqn();
+ boolean isBuddy = isBuddyFqn(fqn);
+ if (isFqnSessionRootSized(fqn, isBuddy)
+ && isFqnForOurWebapp(fqn, isBuddy))
+ {
+ manager_.sessionActivated();
+ }
+
+ }
+
+}
Property changes on: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/PassivationListener.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
More information about the jboss-cvs-commits
mailing list