[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