[jboss-cvs] JBossAS SVN: r60068 - trunk/ejb3/src/main/org/jboss/ejb3/cache/tree.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Jan 27 18:16:01 EST 2007


Author: bstansberry at jboss.com
Date: 2007-01-27 18:16:00 -0500 (Sat, 27 Jan 2007)
New Revision: 60068

Modified:
   trunk/ejb3/src/main/org/jboss/ejb3/cache/tree/StatefulTreeCache.java
Log:
Deal with ProxiedStatefulBeanContext
General tidying up

Modified: trunk/ejb3/src/main/org/jboss/ejb3/cache/tree/StatefulTreeCache.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/cache/tree/StatefulTreeCache.java	2007-01-27 23:12:23 UTC (rev 60067)
+++ trunk/ejb3/src/main/org/jboss/ejb3/cache/tree/StatefulTreeCache.java	2007-01-27 23:16:00 UTC (rev 60068)
@@ -41,6 +41,7 @@
 import org.jboss.ejb3.Container;
 import org.jboss.ejb3.Pool;
 import org.jboss.ejb3.cache.ClusteredStatefulCache;
+import org.jboss.ejb3.stateful.ProxiedStatefulBeanContext;
 import org.jboss.ejb3.stateful.StatefulBeanContext;
 import org.jboss.mx.util.MBeanProxyExt;
 import org.jboss.mx.util.MBeanServerLocator;
@@ -131,7 +132,8 @@
       }
       catch (CacheException e)
       {
-         throw new RuntimeException(e);
+         RuntimeException re = convertToRuntimeException(e);
+         throw re;
       }
       if (entry == null)
       {
@@ -141,12 +143,13 @@
       // Mark it to eviction thread that don't passivate it yet.
       // Note the Fqn we use is relative to the region!
       region.markNodeCurrentlyInUse(new Fqn(key.toString()), MarkInUseWaitTime);
-      if(log.isDebugEnabled())
+      entry.lastUsed = System.currentTimeMillis();
+      
+      if(log.isTraceEnabled())
       {
          log.debug("get: retrieved bean with cache id " +id.toString());
       }
-
-      entry.lastUsed = System.currentTimeMillis();
+      
       return entry;
    }
 
@@ -155,7 +158,7 @@
       Fqn id = new Fqn(cacheNode, key.toString());
       try
       {
-         if(log.isDebugEnabled())
+         if(log.isTraceEnabled())
          {
             log.debug("remove: cache id " +id.toString());
          }
@@ -163,7 +166,8 @@
       }
       catch (CacheException e)
       {
-         throw new RuntimeException(e);
+         RuntimeException re = convertToRuntimeException(e);
+         throw re;
       }
    }
 
@@ -183,11 +187,24 @@
    {
       try
       {
-         cache.put(new Fqn(cacheNode, ctx.getId().toString()), "bean", ctx);
+         // Don't replicate proxies, as they are in the cache
+         // as elements of their containing bean context
+         // TODO -- if this is a ProxiedStatefulBeanContext
+         // should we replicate the parent context, since that's where
+         // the data is? 
+         if (!(ctx instanceof ProxiedStatefulBeanContext))
+         {
+            cache.put(new Fqn(cacheNode, ctx.getId().toString()), "bean", ctx);
+         }
+         else if (log.isTraceEnabled())
+         {
+            log.trace("replicate(): ignoring replicate call for proxy to " + ctx.getId());
+         }
       }
       catch (CacheException e)
       {
-         throw new RuntimeException(e);
+         RuntimeException re = convertToRuntimeException(e);
+         throw re;
       }
    }
 
@@ -224,9 +241,11 @@
 
    public void start()
    {
-      // register to listen for cache event
-      // TODO this approach may not be scalable when there are many beans since then we will need to go thru
-      // N listeners to figure out which this event this belongs to.
+      // register to listen for cache events
+      
+      // TODO this approach may not be scalable when there are many beans 
+      // since then we will need to go thru N listeners to figure out which 
+      // one this event belongs to. Consider having a singleton listener
       listener = new ClusteredStatefulCacheListener();
       cache.addCacheListener(listener);
    }
@@ -258,16 +277,28 @@
       } 
       catch (CacheException e) 
       {
-         log.error("Stop(): can't remove bean from the underlying distributed cache");
+         log.error("stop(): can't remove bean from the underlying distributed cache");
       }
 
       log.debug("stop(): StatefulTreeCache stopped successfully for " +cacheNode);
    }
+   
+   /** 
+    * Creates a RuntimeException, but doesn't pass CacheException as the cause
+    * as it is a type that likely doesn't exist on a client.
+    * Instead creates a RuntimeException with the original exception's
+    * stack trace.
+    */   
+   private RuntimeException convertToRuntimeException(CacheException e)
+   {
+      RuntimeException re = new RuntimeException(e.getClass().getName() + " " + e.getMessage());
+      re.setStackTrace(e.getStackTrace());
+      return re;
+   }
 
    /**
-    * A TreeCacheListener. Note that extends it from AbstractTreeCacheListener is a bit heavy since
-    * it will get all the treecache events (instead of just passivation/activation). But we will have to
-    * wait untill JBossCache2.0 for the refactoring then.
+    * A CacheListener that allows us to get notifications of passivations and
+    * activations and thus notify the cached StatefulBeanContext.
     */
    public class ClusteredStatefulCacheListener extends AbstractCacheListener
    {
@@ -307,22 +338,22 @@
       @Override
       public void nodeLoaded(Fqn fqn, boolean pre, Map nodeData)
       {
-         if(pre) return;  // we are not interested in preActivate event
+         // Ignore everything but "post" events for nodes in our region
+         if(pre) return;
          if(fqn.size() != FQN_SIZE) return;
-         if(!fqn.isChildOrEquals(cacheNode)) return;  // don't care about fqn that doesn't belong to me.
+         if(!fqn.isChildOrEquals(cacheNode)) return;
          if (nodeData == null) return;
          
          StatefulBeanContext bean = (StatefulBeanContext) nodeData.get("bean");
          
          if(bean == null)
          {
-            throw new IllegalStateException("nodeActivate(): null bean instance.");
+            throw new IllegalStateException("nodeLoaded(): null bean instance.");
          }
 
-//         log.debug("nodeActivate(): send postActivate event on fqn: " +fqn);
          if(log.isTraceEnabled())
          {
-            log.trace("nodeActivate(): send postActivate event on fqn: " +fqn);
+            log.trace("nodeLoaded(): send postActivate event to bean at fqn: " +fqn);
          }
 
          bean.postActivate();
@@ -330,30 +361,62 @@
       }
 
       @Override
-      public void nodePassivated(Fqn fqn, boolean pre) {
-         if(!pre) return;  // we are not interested in postPassivate event
+      public void nodePassivated(Fqn fqn, boolean pre) 
+      {
+         // Ignore everything but "pre" events for nodes in our region
+         if(!pre) return;
          if(fqn.size() != FQN_SIZE) return;
-         if(!fqn.isChildOrEquals(cacheNode)) return;  // don't care about fqn that doesn't belong to me.
+         if(!fqn.isChildOrEquals(cacheNode)) return;
 
-         
+         StatefulBeanContext bean = null;
          try {
             InvocationContext ctx = cache.getInvocationContext();
             ctx.setOptionOverrides(getBypassOption());
-            StatefulBeanContext bean = (StatefulBeanContext) cache.get(fqn, "bean");
+            bean = (StatefulBeanContext) cache.get(fqn, "bean");
             if (bean != null && !bean.inUse)
+            {
+               if(log.isTraceEnabled())
+               {
+                  log.trace("nodePassivated(): send prePassivate event to bean at fqn: " +fqn);
+               }
                bean.prePassivate();
-
-         } catch (CacheException e) {
+            }
+         } 
+         catch (CacheException e) 
+         {
             log.error("nodePassivate(): can't retrieve bean instance from: " +fqn + " with exception: " +e);
             return;
          }
-
-//         log.debug("nodePassivate(): send prePassivate event on fqn: " +fqn);
-         if(log.isTraceEnabled())
+         catch (NoSuchEJBException e)
          {
-            log.trace("nodePassivate(): send prePassivate event on fqn: " +fqn);
-         }
-
+            if (bean instanceof ProxiedStatefulBeanContext)
+            {
+               // This is probably an orphaned proxy; double check and remove it
+               try
+               {
+                  bean.getContainedIn();
+                  // If that didn't fail, it's not an orphan
+                  throw e;
+               }
+               catch (NoSuchEJBException n)
+               {
+                  log.debug("nodePassivated(): removing orphaned proxy at " + fqn);
+                  try
+                  {
+                     cache.removeNode(fqn);
+                  }
+                  catch (CacheException c)
+                  {
+                     log.error("nodePassivated(): could not remove orphaned proxy at " + fqn, c);
+                     // Just fall through and let the eviction try
+                  }
+               }
+            }
+            else
+            {
+               throw e;
+            }
+         }         
       }
    }
    




More information about the jboss-cvs-commits mailing list