[jboss-cvs] JBossAS SVN: r63637 - branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Jun 25 18:58:27 EDT 2007
Author: vivekl at redhat.com
Date: 2007-06-25 18:58:27 -0400 (Mon, 25 Jun 2007)
New Revision: 63637
Modified:
branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/LRUStatefulContextCachePolicy.java
branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceCache.java
Log:
- ASPATCH-229: JBAS-1563 - Clustered stateful session bean removal of expired
passivated instances causes deadlock
Modified: branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/LRUStatefulContextCachePolicy.java
===================================================================
--- branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/LRUStatefulContextCachePolicy.java 2007-06-25 22:21:06 UTC (rev 63636)
+++ branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/LRUStatefulContextCachePolicy.java 2007-06-25 22:58:27 UTC (rev 63637)
@@ -16,95 +16,107 @@
/**
* Least Recently Used cache policy for StatefulSessionEnterpriseContexts.
- *
* @author <a href="mailto:simone.bordet at compaq.com">Simone Bordet</a>
+ * @author Scott.Stark at jboss.org
* @version $Revision$
*/
public class LRUStatefulContextCachePolicy extends LRUEnterpriseContextCachePolicy
{
- // Constants -----------------------------------------------------
+ // Constants -----------------------------------------------------
- // Attributes ----------------------------------------------------
- /* The age after which a bean is automatically removed */
- private long m_maxBeanLife;
- /* The remover timer task */
- private TimerTask m_remover;
- /* The period of the remover's runs */
- private long m_removerPeriod;
- /* The stateful cache */
- private StatefulSessionInstanceCache m_cache;
+ // Attributes ----------------------------------------------------
+ /* The age after which a bean is automatically removed */
+ private long m_maxBeanLife;
+ /* The remover timer task */
+ private TimerTask m_remover;
+ /* The period of the remover's runs */
+ private long m_removerPeriod;
+ /**
+ * The typed stateful cache
+ */
+ private StatefulSessionInstanceCache ssiCache;
- // Static --------------------------------------------------------
+ // Static --------------------------------------------------------
- // Constructors --------------------------------------------------
- /**
- * Creates a LRU cache policy object given the instance cache that use
- * this policy object.
- */
- public LRUStatefulContextCachePolicy(AbstractInstanceCache eic)
- {
- super(eic);
- m_cache = (StatefulSessionInstanceCache)eic;
- }
+ // Constructors --------------------------------------------------
+ /**
+ * Creates a LRU cache policy object given the instance cache that use this
+ * policy object.
+ */
+ public LRUStatefulContextCachePolicy(AbstractInstanceCache eic)
+ {
+ super(eic);
+ ssiCache = (StatefulSessionInstanceCache) eic;
+ }
- // Public --------------------------------------------------------
+ // Public --------------------------------------------------------
- // Monitorable implementation ------------------------------------
+ // Monitorable implementation ------------------------------------
- // Z implementation ----------------------------------------------
- public void start()
- {
- super.start();
- if (m_maxBeanLife > 0)
- {
- m_remover = new RemoverTask(m_removerPeriod);
+ // Z implementation ----------------------------------------------
+ public void start()
+ {
+ super.start();
+ if (m_maxBeanLife > 0)
+ {
+ m_remover = new RemoverTask(m_removerPeriod);
long delay = (long) (Math.random() * m_removerPeriod);
tasksTimer.schedule(m_remover, delay, m_removerPeriod);
- }
- }
+ }
+ }
- public void stop()
- {
- if (m_remover != null) {m_remover.cancel();}
- super.stop();
- }
- /**
- * Reads from the configuration the parameters for this cache policy, that are
- * all optionals.
- */
- public void importXml(Element element) throws DeploymentException
- {
- super.importXml(element);
+ public void stop()
+ {
+ if (m_remover != null)
+ {
+ m_remover.cancel();
+ }
+ super.stop();
+ }
- String rp = MetaData.getElementContent(MetaData.getOptionalChild(element, "remover-period"));
- String ml = MetaData.getElementContent(MetaData.getOptionalChild(element, "max-bean-life"));
- try
- {
- if (rp != null)
- {
- int p = Integer.parseInt(rp);
- if (p <= 0) {throw new DeploymentException("Remover period can't be <= 0");}
- m_removerPeriod = p * 1000;
- }
- if (ml != null)
- {
- int a = Integer.parseInt(ml);
- if (a <= 0) {throw new DeploymentException("Max bean life can't be <= 0");}
- m_maxBeanLife = a * 1000;
- }
- }
- catch (NumberFormatException x)
- {
- throw new DeploymentException("Can't parse policy configuration", x);
- }
- }
+ /**
+ * Reads from the configuration the parameters for this cache policy, that
+ * are all optionals.
+ */
+ public void importXml(Element element) throws DeploymentException
+ {
+ super.importXml(element);
- // Y overrides ---------------------------------------------------
+ String rp = MetaData.getElementContent(MetaData.getOptionalChild(element, "remover-period"));
+ String ml = MetaData.getElementContent(MetaData.getOptionalChild(element, "max-bean-life"));
+ try
+ {
+ if (rp != null)
+ {
+ int p = Integer.parseInt(rp);
+ if (p <= 0)
+ {
+ throw new DeploymentException("Remover period can't be <= 0");
+ }
+ m_removerPeriod = p * 1000;
+ }
+ if (ml != null)
+ {
+ int a = Integer.parseInt(ml);
+ if (a <= 0)
+ {
+ throw new DeploymentException("Max bean life can't be <= 0");
+ }
+ m_maxBeanLife = a * 1000;
+ }
+ }
+ catch (NumberFormatException x)
+ {
+ throw new DeploymentException("Can't parse policy configuration", x);
+ }
+ }
- // Package protected ---------------------------------------------
+ // Y overrides ---------------------------------------------------
- // Protected -----------------------------------------------------
+ // Package protected ---------------------------------------------
+ // Protected -----------------------------------------------------
+
protected void appendProperties(StringBuffer buffer)
{
super.appendProperties(buffer);
@@ -112,39 +124,59 @@
buffer.append(" max-bean-life=").append(m_maxBeanLife);
}
- // Private -------------------------------------------------------
+ // Private -------------------------------------------------------
- // Inner classes -------------------------------------------------
- /**
- * This TimerTask removes beans that have not been called for a while.
- */
- protected class RemoverTask extends OveragerTask
- {
- protected RemoverTask(long period)
- {
- super(period);
- }
- protected String getTaskLogMessage() {return "Removing from cache bean";}
- protected String getJMSTaskType() {return "REMOVER";}
- protected void kickOut(LRUCacheEntry entry) {remove(entry.m_key);}
- protected long getMaxAge() {return m_maxBeanLife;}
+ // Inner classes -------------------------------------------------
+ /**
+ * This TimerTask removes beans that have not been called for a while.
+ */
+ protected class RemoverTask extends OveragerTask
+ {
+ protected RemoverTask(long period)
+ {
+ super(period);
+ }
- public void run()
- {
- if( m_cache == null )
+ protected String getTaskLogMessage()
+ {
+ return "Removing from cache bean";
+ }
+
+ protected void kickOut(LRUCacheEntry entry)
+ {
+ remove(entry.m_key);
+ }
+
+ protected long getMaxAge()
+ {
+ return m_maxBeanLife;
+ }
+
+ public void run()
+ {
+ if (ssiCache == null)
{
cancel();
return;
}
- synchronized (m_cache.getCacheLock())
- {
- // Remove beans from cache, if present
- super.run();
-
- // Now remove passivated beans
- m_cache.removePassivated(getMaxAge() - super.getMaxAge());
- }
- }
- }
+ synchronized (ssiCache.getCacheLock())
+ {
+ log.debug("Running RemoverTask");
+ // Remove beans from cache and passivate them
+ super.run();
+ log.debug("RemoverTask, PassivatedCount=" + ssiCache.getPassivatedCount());
+ }
+ try
+ {
+ // Throw away any passivated beans that have expired
+ ssiCache.removePassivated(getMaxAge() - super.getMaxAge());
+ log.debug("RemoverTask, done");
+ }
+ catch (Throwable e)
+ {
+ log.debug("Error during removals", e);
+ }
+ }
+ }
}
Modified: branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceCache.java
===================================================================
--- branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceCache.java 2007-06-25 22:21:06 UTC (rev 63636)
+++ branches/JBoss_3_2_6_CP/server/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceCache.java 2007-06-25 22:58:27 UTC (rev 63637)
@@ -9,11 +9,8 @@
import java.util.HashSet;
import java.util.Map;
-import java.util.HashMap;
import java.util.Iterator;
-
import java.rmi.RemoteException;
-
import javax.transaction.Status;
import javax.transaction.SystemException;
@@ -22,6 +19,7 @@
import org.jboss.ejb.EnterpriseContext;
import org.jboss.ejb.StatefulSessionEnterpriseContext;
import org.jboss.ejb.StatefulSessionPersistenceManager;
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
/**
* Cache for stateful session beans.
@@ -39,14 +37,16 @@
/* The container */
private StatefulSessionContainer m_container;
- /* The map that holds passivated beans that will be removed */
- private HashMap m_passivated = new HashMap();
-
+ /** The map<id, Long> that holds passivated bean ids that have been removed
+ * from the cache and passivated to the pm along with the time of passivation
+ */
+ private ConcurrentReaderHashMap passivatedIDs = new ConcurrentReaderHashMap();
+
/* Ids that are currently being activated */
private HashSet activating = new HashSet();
/* Used for logging */
- private StringBuffer m_buffer = new StringBuffer();
+ private StringBuffer buffer = new StringBuffer();
// Static --------------------------------------------------------
@@ -60,7 +60,7 @@
*/
public long getPassivatedCount()
{
- return m_passivated.size();
+ return passivatedIDs.size();
}
/* From ContainerPlugin interface */
@@ -75,7 +75,7 @@
{
this.m_container = null;
}
- m_passivated.clear();
+ passivatedIDs.clear();
super.destroy();
}
@@ -91,18 +91,17 @@
protected void passivate(EnterpriseContext ctx) throws RemoteException
{
m_container.getPersistenceManager().passivateSession((StatefulSessionEnterpriseContext) ctx);
- m_passivated.put(ctx.getId(), new Long(System.currentTimeMillis()));
+ passivatedIDs.put(ctx.getId(), new Long(System.currentTimeMillis()));
}
protected void activate(EnterpriseContext ctx) throws RemoteException
{
m_container.getPersistenceManager().activateSession((StatefulSessionEnterpriseContext) ctx);
- m_passivated.remove(ctx.getId());
+ passivatedIDs.remove(ctx.getId());
}
protected boolean doActivate(EnterpriseContext ctx) throws RemoteException
{
- StatefulSessionEnterpriseContext sctx = (StatefulSessionEnterpriseContext) ctx;
Object id = ctx.getId();
synchronized (activating)
{
@@ -181,7 +180,8 @@
{
StatefulSessionPersistenceManager store = m_container.getPersistenceManager();
long now = System.currentTimeMillis();
- Iterator entries = m_passivated.entrySet().iterator();
+ log.debug("removePassivated, now="+now+", maxLifeAfterPassivation="+maxLifeAfterPassivation);
+ Iterator entries = passivatedIDs.entrySet().iterator();
while (entries.hasNext())
{
Map.Entry entry = (Map.Entry) entries.next();
@@ -192,7 +192,7 @@
preRemovalPreparation(key);
store.removePassivated(key);
if (log.isTraceEnabled())
- log(key);
+ log(key, passivationTime);
// Must use iterator to avoid ConcurrentModificationException
entries.remove();
postRemovalCleanup(key);
@@ -214,16 +214,18 @@
// Private -------------------------------------------------------
- private void log(Object key)
+ private void log(Object key, long passivationTime)
{
if (log.isTraceEnabled())
{
- m_buffer.setLength(0);
- m_buffer.append("Removing from storage bean '");
- m_buffer.append(m_container.getBeanMetaData().getEjbName());
- m_buffer.append("' with id = ");
- m_buffer.append(key);
- log.trace(m_buffer.toString());
+ buffer.setLength(0);
+ buffer.append("Removing from storage bean '");
+ buffer.append(m_container.getBeanMetaData().getEjbName());
+ buffer.append("' with id = ");
+ buffer.append(key);
+ buffer.append(", passivationTime=");
+ buffer.append(passivationTime);
+ log.trace(buffer.toString());
}
}
More information about the jboss-cvs-commits
mailing list