[jboss-cvs] JBossAS SVN: r107441 - in projects/ejb3/branches/infinispan-int/core: src/main/java/org/jboss/ejb3/cache and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Aug 5 12:42:47 EDT 2010


Author: pferraro
Date: 2010-08-05 12:42:46 -0400 (Thu, 05 Aug 2010)
New Revision: 107441

Added:
   projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/
   projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCache.java
   projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCacheFactory.java
Modified:
   projects/ejb3/branches/infinispan-int/core/pom.xml
   projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/tree/StatefulTreeCache.java
   projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/remoting/ReplicantsManagerInterceptorFactory.java
Log:
[EJBTHREE-2049] Create an Infinispan-backed SFSB cache
CacheManagerLocator refactored from ha-server-api into ha-server-cache-jbc

Modified: projects/ejb3/branches/infinispan-int/core/pom.xml
===================================================================
--- projects/ejb3/branches/infinispan-int/core/pom.xml	2010-08-05 16:40:45 UTC (rev 107440)
+++ projects/ejb3/branches/infinispan-int/core/pom.xml	2010-08-05 16:42:46 UTC (rev 107441)
@@ -232,6 +232,13 @@
       <artifactId>jboss-logging-spi</artifactId>
     </dependency>
 
+    <!-- Needed for PersistenceXmlLoader -->
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.1.1</version>
+    </dependency>
+
 <!--
     <dependency>
       <groupId>org.jboss.test</groupId>
@@ -286,19 +293,6 @@
     </dependency>
 
     <dependency>
-      <groupId>org.jboss.cache</groupId>
-      <artifactId>jbosscache-core</artifactId>
-      <!-- not used anywhere else -->
-      <version>3.1.0.GA</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.jboss.javaee</groupId>
-          <artifactId>jboss-javaee</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-    <dependency>
       <groupId>org.jboss.aspects</groupId>
       <artifactId>jboss-aspects-test</artifactId>
       <version>1.0.0.Beta1</version>
@@ -324,7 +318,7 @@
     <dependency>
       <groupId>org.jboss.cluster</groupId>
       <artifactId>jboss-ha-client</artifactId>
-      <version>1.1.1.GA</version>
+      <version>1.1.2.Beta1</version>
       <exclusions>
         <exclusion>
           <groupId>org.jboss.aspects</groupId>
@@ -344,7 +338,7 @@
     <dependency>
       <groupId>org.jboss.cluster</groupId>
       <artifactId>jboss-ha-server-api</artifactId>
-      <version>1.1.1.GA</version>
+      <version>2.0.0.Alpha6</version>
       <exclusions>
         <exclusion>
           <groupId>org.jboss</groupId>
@@ -354,22 +348,45 @@
           <groupId>org.jboss.logging</groupId>
           <artifactId>jboss-logging-spi</artifactId>
         </exclusion>
+        <!-- Exclude here, make optional -->
         <exclusion>
-          <groupId>org.jboss.cache</groupId>
-          <artifactId>jbosscache-core</artifactId>
+          <groupId>org.jgroups</groupId>
+          <artifactId>jgroups</artifactId>
         </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.cluster</groupId>
+      <artifactId>jboss-ha-server-cache-jbc</artifactId>
+      <version>3.0.0.Alpha3</version>
+      <optional>true</optional>
+      <exclusions>
         <exclusion>
-          <groupId>org.jboss.cache</groupId>
-          <artifactId>jbosscache-pojo</artifactId>
+          <groupId>org.jboss.cluster</groupId>
+          <artifactId>jboss-ha-server-cache-spi</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>jgroups</groupId>
-          <artifactId>jgroups</artifactId>
+          <groupId>org.jboss.cluster</groupId>
+          <artifactId>jboss-ha-server-core</artifactId>
         </exclusion>
       </exclusions>
     </dependency>
 
     <dependency>
+      <groupId>org.jboss.cluster</groupId>
+      <artifactId>jboss-ha-server-ispn</artifactId>
+      <version>1.0.0.Alpha1</version>
+      <optional>true</optional>
+      <exclusions>
+        <exclusion>
+          <groupId>org.infinispan</groupId>
+          <artifactId>infinispan-tree</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
       <groupId>org.jboss.ejb3</groupId>
       <artifactId>jboss-ejb3-cache</artifactId>
       <version>1.0.0</version>
@@ -416,13 +433,13 @@
     <dependency>
       <groupId>org.jboss.ejb3</groupId>
       <artifactId>jboss-ejb3-ext-api</artifactId>
-      <version>1.1.1</version>
+      <version>1.1.2-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.jboss.ejb3</groupId>
       <artifactId>jboss-ejb3-ext-api-impl</artifactId>
-      <version>1.1.1</version>
+      <version>1.1.2-SNAPSHOT</version>
     </dependency>
 
     <dependency>

Added: projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCache.java
===================================================================
--- projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCache.java	                        (rev 0)
+++ projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCache.java	2010-08-05 16:42:46 UTC (rev 107441)
@@ -0,0 +1,672 @@
+package org.jboss.ejb3.cache.infinispan;
+
+import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.ejb.EJBException;
+import javax.ejb.NoSuchEJBException;
+
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+import org.infinispan.config.Configuration.CacheMode;
+import org.infinispan.distribution.DistributionManager;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryActivated;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryPassivated;
+import org.infinispan.notifications.cachelistener.event.CacheEntryActivatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryPassivatedEvent;
+import org.jboss.ejb3.EJBContainer;
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.ClusteredStatefulCache;
+import org.jboss.ejb3.cache.tree.ContextInUseException;
+import org.jboss.ejb3.stateful.NestedStatefulBeanContext;
+import org.jboss.ejb3.stateful.StatefulBeanContext;
+import org.jboss.ejb3.stateful.StatefulContainer;
+import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.logging.Logger;
+import org.jboss.util.loading.ContextClassLoaderSwitcher;
+import org.jboss.util.loading.ContextClassLoaderSwitcher.SwitchContext;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+ at Listener
+public class InfinispanStatefulCache implements ClusteredStatefulCache
+{
+   @SuppressWarnings("unchecked")
+   // Need to cast since ContextClassLoaderSwitcher.NewInstance does not generically implement PrivilegedAction<ContextClassLoaderSwitcher>
+   private final ContextClassLoaderSwitcher switcher = (ContextClassLoaderSwitcher) AccessController.doPrivileged(ContextClassLoaderSwitcher.INSTANTIATOR);
+   
+   private final CacheContainerRegistry registry;
+   private final CacheInvoker invoker;
+   private final String defaultContainerName;
+   final ThreadFactory threadFactory;
+
+   private final AtomicInteger createCount = new AtomicInteger(0);
+   private final AtomicInteger passivatedCount = new AtomicInteger(0);
+   private final AtomicInteger removeCount = new AtomicInteger(0);
+   private final AtomicBoolean resetTotalSize = new AtomicBoolean(true);
+   
+   private volatile int totalSize = 0;
+   
+   // Defined in initialize(...)
+   long removalTimeout;
+   Map<Object, Long> beans = null;
+   Logger log;
+   private StatefulContainer ejbContainer;
+   private CacheConfig cacheConfig;
+   private ScheduledExecutorService executor;
+
+   // Defined in start()
+   private Cache<Object, StatefulBeanContext> cache;
+   private WeakReference<ClassLoader> classLoaderRef;
+   
+   public InfinispanStatefulCache(CacheContainerRegistry registry, String defaultContainerName, CacheInvoker invoker, ThreadFactory threadFactory)
+   {
+      this.registry = registry;
+      this.invoker = invoker;
+      this.threadFactory = threadFactory;
+      this.defaultContainerName = defaultContainerName;
+   }
+
+   @Override
+   public void initialize(EJBContainer container) throws Exception
+   {
+      this.ejbContainer = (StatefulContainer) container;
+      this.log = Logger.getLogger(getClass().getName() + "." + this.ejbContainer.getEjbName());
+      
+      this.cacheConfig = this.ejbContainer.getAnnotation(CacheConfig.class);
+
+      this.removalTimeout = this.cacheConfig.removalTimeoutSeconds() * 1000L;
+      
+      if (this.removalTimeout > 0)
+      {
+         this.beans = new ConcurrentHashMap<Object, Long>();
+      }
+   }
+
+   @Override
+   public void start()
+   {
+      this.classLoaderRef = new WeakReference<ClassLoader>(this.ejbContainer.getClassloader());
+
+      if (this.cache == null)
+      {
+         String containerName = this.defaultContainerName;
+         String templateCacheName = this.cacheConfig.name();
+         
+         if ((templateCacheName != null) && !templateCacheName.trim().isEmpty())
+         {
+            // Parse cache container name
+            String[] parts = templateCacheName.split(":");
+            if (parts.length == 2)
+            {
+               containerName = parts[0];
+               templateCacheName = parts[1];
+            }
+         }
+         else
+         {
+            templateCacheName = CacheConfig.DEFAULT_CLUSTERED_OBJECT_NAME;
+         }
+         
+         String cacheName = this.ejbContainer.getDeploymentPropertyListString();
+         
+         CacheContainer container = this.registry.getCacheContainer(containerName);
+         Cache<?, ?> templateCache = container.getCache(templateCacheName);
+         Configuration configuration = templateCache.getConfiguration().clone();
+         
+         int backups = this.cacheConfig.backups();
+         CacheConfig.Mode mode = this.cacheConfig.mode();
+
+         CacheMode cacheMode = configuration.getCacheMode();
+         
+         if (backups != CacheConfig.DEFAULT_BACKUPS)
+         {
+            configuration.setNumOwners(backups);
+            
+            if (backups == CacheConfig.NO_BACKUPS)
+            {
+               cacheMode = CacheMode.LOCAL;
+            }
+            else
+            {
+               boolean synchronous = cacheMode.isSynchronous();
+               if (backups > 0)
+               {
+                  cacheMode = synchronous ? CacheMode.DIST_SYNC : CacheMode.DIST_ASYNC;
+               }
+               else // Negative backups means total replication
+               {
+                  cacheMode = synchronous ? CacheMode.REPL_SYNC : CacheMode.REPL_ASYNC;
+               }
+            }
+         }
+         
+         switch (mode)
+         {
+            case SYNCHRONOUS:
+            {
+               cacheMode = cacheMode.toSync();
+               break;
+            }
+            case ASYNCHRONOUS:
+            {
+               cacheMode = cacheMode.toAsync();
+               break;
+            }
+            case DEFAULT:
+            {
+               // Do nothing
+            }
+         }
+         
+         configuration.setCacheMode(cacheMode);
+         
+         EmbeddedCacheManager manager = (EmbeddedCacheManager) templateCache.getCacheManager();
+         
+         manager.defineConfiguration(cacheName, configuration);
+         
+         this.cache = container.getCache(cacheName);
+      }
+      
+      this.cache.start();
+      
+      this.cache.addListener(this);
+      
+      if (this.removalTimeout > 0)
+      {
+         final String threadName = "SFSB Removal Thread - " + this.ejbContainer.getObjectName().getCanonicalName();
+         
+         // Decorate our thread factory and customize thread name
+         ThreadFactory threadFactory = new ThreadFactory()
+         {
+            @Override
+            public Thread newThread(Runnable task)
+            {
+               final Thread thread = InfinispanStatefulCache.this.threadFactory.newThread(task);
+               // Thread.setName() is a privileged action
+               PrivilegedAction<Void> action = new PrivilegedAction<Void>()
+               {
+                  @Override
+                  public Void run()
+                  {
+                     thread.setName(threadName);
+                     return null;
+                  }
+               };
+               AccessController.doPrivileged(action);
+               return thread;
+            }
+         };
+         
+         this.executor = Executors.newScheduledThreadPool(1, threadFactory);
+         this.executor.scheduleWithFixedDelay(new RemovalTimeoutTask(), this.removalTimeout, this.removalTimeout, TimeUnit.MILLISECONDS);
+      }
+      
+      this.resetTotalSize.set(true);
+   }
+   
+   @Override
+   public void stop()
+   {
+      if (this.executor != null)
+      {
+         this.executor.shutdownNow();
+      }
+      
+      this.cache.removeListener(this);
+      this.cache.stop();
+      
+      this.classLoaderRef.clear();
+   }
+   
+   @Override
+   public StatefulBeanContext peek(Object id) throws NoSuchEJBException
+   {
+      return this.get(id, false);
+   }
+
+   @Override
+   public void release(StatefulBeanContext bean)
+   {
+      synchronized (bean)
+      {
+         this.setInUse(bean, false);
+      }
+   }
+
+   @Override
+   public void replicate(final StatefulBeanContext bean)
+   {
+      // StatefulReplicationInterceptor should only pass us the ultimate
+      // parent context for a tree of nested beans, which should always be
+      // a standard StatefulBeanContext
+      if (bean instanceof NestedStatefulBeanContext)
+      {
+         throw new IllegalArgumentException("Received unexpected replicate call for nested context " + bean.getId());
+      }
+      
+      bean.preReplicate();
+      
+      Operation<StatefulBeanContext> operation = new Operation<StatefulBeanContext>()
+      {
+         @Override
+         public StatefulBeanContext invoke(Cache<Object, StatefulBeanContext> cache)
+         {
+            return cache.put(bean.getId(), bean);
+         }
+      };
+      
+      this.invoker.invoke(this.cache, operation);
+      
+      bean.markedForReplication = false;
+   }
+
+   @Override
+   public void remove(final Object id)
+   {
+      Operation<StatefulBeanContext> operation = new Operation<StatefulBeanContext>()
+      {
+         @Override
+         public StatefulBeanContext invoke(Cache<Object, StatefulBeanContext> cache)
+         {
+            return cache.get(id);
+         }
+      };
+      
+      final StatefulBeanContext bean = this.invoker.invoke(this.cache, operation);
+
+      if (bean == null)
+      {
+         throw new NoSuchEJBException("Could not find Stateful bean: " + id);
+      }
+      
+      if (!bean.isRemoved())
+      {
+         this.ejbContainer.destroy(bean);
+      }
+      else if (this.log.isTraceEnabled())
+      {
+         this.log.trace("remove: " + id + " already removed from pool");
+      }
+
+      if (bean.getCanRemoveFromCache())
+      {
+         operation = new Operation<StatefulBeanContext>()
+         {
+            @Override
+            public StatefulBeanContext invoke(Cache<Object, StatefulBeanContext> cache)
+            {
+               return cache.remove(id);
+            }
+         };
+         
+         this.invoker.invoke(this.cache, operation);
+      }
+      else
+      {
+         // We can't remove the context as it contains live nested beans
+         // But, we must replicate it so other nodes know the parent is removed!
+         operation = new Operation<StatefulBeanContext>()
+         {
+            @Override
+            public StatefulBeanContext invoke(Cache<Object, StatefulBeanContext> cache)
+            {
+               return cache.put(id, bean);
+            }
+         };
+         
+         this.invoker.invoke(this.cache, operation);
+         
+         if(log.isTraceEnabled())
+         {
+            log.trace("remove: removed bean " + id + " cannot be removed from cache");
+         }
+      }
+      
+      if (this.beans != null)
+      {
+         this.beans.remove(id);
+      }
+
+      this.removeCount.incrementAndGet();
+      this.resetTotalSize.set(true);
+   }
+
+   @Override
+   public StatefulBeanContext create(Class<?>[] initTypes, Object[] initValues)
+   {
+      final StatefulBeanContext bean = this.create();
+      
+      if (this.log.isTraceEnabled())
+      {
+         this.log.trace("Caching context " + bean.getId() + " of type " + bean.getClass().getName());
+      }
+      
+      try
+      {
+         bean.preReplicate();
+         
+         Operation<StatefulBeanContext> operation = new Operation<StatefulBeanContext>()
+         {
+            @Override
+            public StatefulBeanContext invoke(Cache<Object, StatefulBeanContext> cache)
+            {
+               return cache.put(bean.getId(), bean);
+            }
+         };
+         
+         this.invoker.invoke(this.cache, operation);
+         
+         bean.markedForReplication = false;
+         
+         this.setInUse(bean, true);
+         
+         this.createCount.incrementAndGet();
+         this.resetTotalSize.set(true);
+         
+         return bean;
+      }
+      catch (EJBException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new EJBException(e);
+      }
+   }
+
+   /**
+    * Copy of {@link org.jboss.ejb3.stateful.StatefulContainer#create(Class[], Object[])}
+    * with additional logic to ensure that the generated bean will cache locally.
+    * @see {@link org.jboss.ejb3.stateful.StatefulContainer#create(Class[], Object[])}
+    */
+   private StatefulBeanContext create()
+   {
+      StatefulBeanContext bean = (StatefulBeanContext) this.ejbContainer.createBeanContext();
+      
+      DistributionManager manager = this.cache.getAdvancedCache().getDistributionManager();
+      
+      if (manager != null)
+      {
+         // If using distribution mode, ensure that bean will cache locally
+         while (!manager.isLocal(bean.getId()))
+         {
+            bean = new MyStatefulBeanContext(bean.getContainer(), bean.getInstance());
+         }
+      }
+
+      // Tell context how to handle replication
+      CacheConfig config = this.ejbContainer.getAnnotation(CacheConfig.class);
+      if (config != null)
+      {
+         bean.setReplicationIsPassivation(config.replicationIsPassivation());
+      }
+
+      // this is for propagated extended PC's
+      bean = bean.pushContainedIn();
+
+      this.ejbContainer.pushContext(bean);
+      try
+      {
+         this.ejbContainer.injectBeanContext(bean);
+      }
+      finally
+      {
+         this.ejbContainer.popContext();
+         // this is for propagated extended PC's
+         bean.popContainedIn();
+      }
+
+      this.ejbContainer.invokePostConstruct(bean);
+
+      return bean;
+   }
+   
+   @Override
+   public StatefulBeanContext get(Object id) throws EJBException
+   {
+      return this.get(id, true);
+   }
+
+   @Override
+   public StatefulBeanContext get(final Object key, boolean markInUse) throws EJBException
+   {
+      Operation<StatefulBeanContext> getOperation = new Operation<StatefulBeanContext>()
+      {
+         @Override
+         public StatefulBeanContext invoke(Cache<Object, StatefulBeanContext> cache)
+         {
+            return cache.get(key);
+         }
+      };
+      
+      StatefulBeanContext bean = this.invoker.invoke(this.cache, getOperation);
+      
+      if (bean == null)
+      {
+         throw new NoSuchEJBException("Could not find stateful bean: " + key);
+      }
+      else if (markInUse && bean.isRemoved())
+      {
+         throw new NoSuchEJBException("Could not find stateful bean: " + key +
+                                      " (bean was marked as removed)");
+      }
+      
+      bean.postReplicate();
+      
+      if (markInUse)
+      {
+         synchronized (bean)
+         {
+            this.setInUse(bean, true);
+         }
+      }
+
+      if (this.log.isTraceEnabled())
+      {
+         this.log.trace("get: retrieved bean with cache id " + key);
+      }
+
+      return bean;
+   }
+
+   @Override
+   public int getAvailableCount()
+   {
+      int maxSize = this.getMaxSize();
+      return (maxSize < 0) ? maxSize : maxSize - this.getCurrentSize();
+   }
+
+   @Override
+   public int getCacheSize()
+   {
+      return this.getTotalSize() - this.getPassivatedCount();
+   }
+
+   @Override
+   public int getCreateCount()
+   {
+      return this.createCount.get();
+   }
+
+   @Override
+   public int getCurrentSize()
+   {
+      return this.getCacheSize();
+   }
+
+   @Override
+   public int getMaxSize()
+   {
+      return (this.cacheConfig == null) ? -1 : this.cacheConfig.maxSize();
+   }
+
+   @Override
+   public int getPassivatedCount()
+   {
+      return this.passivatedCount.get();
+   }
+
+   @Override
+   public int getRemoveCount()
+   {
+      return this.removeCount.get();
+   }
+
+   @Override
+   public int getTotalSize()
+   {
+      if (this.beans != null)
+      {
+         return this.beans.size();
+      }
+      
+      if (this.resetTotalSize.compareAndSet(true, false))
+      {
+         this.totalSize = this.cache.size();
+      }
+      
+      return this.totalSize;
+   }
+
+   @Override
+   public boolean isStarted()
+   {
+      return (this.cache != null) ? this.cache.getStatus() == ComponentStatus.RUNNING : false;
+   }
+
+   @CacheEntryActivated
+   public void activated(CacheEntryActivatedEvent event)
+   {
+      if (event.isPre()) return;
+      
+      this.passivatedCount.decrementAndGet();
+      this.resetTotalSize.set(true);
+
+      StatefulBeanContext bean = this.cache.get(event.getKey());
+      
+      SwitchContext switchContext = this.switcher.getSwitchContext();
+      ClassLoader classLoader = this.classLoaderRef.get();
+      
+      try
+      {
+         if (classLoader != null)
+         {
+            switchContext.setClassLoader(classLoader);
+         }
+
+         bean.activateAfterReplication();
+      }
+      finally
+      {
+         switchContext.reset();
+      }
+   }
+
+   @CacheEntryPassivated
+   public void passivated(CacheEntryPassivatedEvent event)
+   {
+      if (!event.isPre()) return;
+      
+      Object key = event.getKey();
+      StatefulBeanContext bean = this.cache.get(event.getKey());
+      
+      SwitchContext switchContext = this.switcher.getSwitchContext();
+      ClassLoader classLoader = this.classLoaderRef.get();
+      
+      try
+      {
+         if (classLoader != null)
+         {
+            switchContext.setClassLoader(classLoader);
+         }
+
+         if (!bean.getCanPassivate())
+         {
+            // Abort the eviction
+            throw new ContextInUseException("Cannot passivate bean " + key +
+                  " -- it or one if its children is currently in use");
+         }
+         
+         bean.passivateAfterReplication();
+      }
+      finally
+      {
+         switchContext.reset();
+      }
+      
+      this.passivatedCount.incrementAndGet();
+      this.resetTotalSize.set(true);
+   }
+   
+   private void setInUse(StatefulBeanContext bean, boolean inUse)
+   {
+      bean.setInUse(inUse);
+      bean.lastUsed = System.currentTimeMillis();
+      
+      if (this.beans != null)
+      {
+         this.beans.put(bean.getId(), Long.valueOf(bean.lastUsed));
+      }
+   }
+   
+   class RemovalTimeoutTask implements Runnable
+   {
+      @Override
+      public void run()
+      {
+         long now = System.currentTimeMillis();
+
+         for (Map.Entry<Object, Long> entry: InfinispanStatefulCache.this.beans.entrySet())
+         {
+            if (now - entry.getValue().longValue() >= InfinispanStatefulCache.this.removalTimeout)
+            {
+               Object key = entry.getKey();
+               
+               try
+               {
+                  InfinispanStatefulCache.this.remove(key);
+               }
+               catch (NoSuchEJBException e)
+               {
+                  InfinispanStatefulCache.this.beans.remove(key);
+               }
+               catch (Exception e)
+               {
+                  InfinispanStatefulCache.this.log.error("problem removing SFSB " + key, e);
+               }
+            }
+         }
+      }
+   }
+   
+   // Simplified CacheInvoker.Operation using specific key/value types
+   interface Operation<R> extends CacheInvoker.Operation<Object, StatefulBeanContext, R>
+   {
+   }
+   
+   public static class MyStatefulBeanContext extends StatefulBeanContext
+   {
+      MyStatefulBeanContext(StatefulContainer container, Object bean)
+      {
+         super(container, bean);
+      }
+   }
+}

Added: projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCacheFactory.java
===================================================================
--- projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCacheFactory.java	                        (rev 0)
+++ projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/infinispan/InfinispanStatefulCacheFactory.java	2010-08-05 16:42:46 UTC (rev 107441)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, 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.ejb3.cache.infinispan;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import org.jboss.ejb3.cache.Ejb3CacheFactory;
+import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.DefaultCacheContainerRegistry;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.ha.ispn.invoker.RetryingCacheInvoker;
+
+/**
+ * @author Paul Ferraro
+ */
+public class InfinispanStatefulCacheFactory implements Ejb3CacheFactory
+{
+   private static final String DEFAULT_CACHE_CONTAINER = "sfsb";
+   
+   private CacheContainerRegistry registry = DefaultCacheContainerRegistry.getInstance();
+   private String defaultContainerName = DEFAULT_CACHE_CONTAINER;
+   private ThreadFactory threadFactory = Executors.defaultThreadFactory();
+   private CacheInvoker invoker = new RetryingCacheInvoker(0, 0);
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.ejb3.cache.Ejb3CacheFactory#createCache()
+    */
+   @Override
+   @SuppressWarnings("deprecation")
+   public org.jboss.ejb3.cache.StatefulCache createCache()
+   {
+      return new InfinispanStatefulCache(this.registry, this.defaultContainerName, this.invoker, this.threadFactory);
+   }
+   
+   public void setCacheContainerRegistry(CacheContainerRegistry registry)
+   {
+      this.registry = registry;
+   }
+   
+   public void setThreadFactory(ThreadFactory threadFactory)
+   {
+      this.threadFactory = threadFactory;
+   }
+   
+   public void setDefaultCacheContainerName(String defaultContainerName)
+   {
+      this.defaultContainerName = defaultContainerName;
+   }
+   
+   public void setCacheInvoker(CacheInvoker invoker)
+   {
+      this.invoker = invoker;
+   }
+}

Modified: projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/tree/StatefulTreeCache.java
===================================================================
--- projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/tree/StatefulTreeCache.java	2010-08-05 16:40:45 UTC (rev 107440)
+++ projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/cache/tree/StatefulTreeCache.java	2010-08-05 16:42:46 UTC (rev 107441)
@@ -53,7 +53,7 @@
 import org.jboss.ejb3.stateful.ProxiedStatefulBeanContext;
 import org.jboss.ejb3.stateful.StatefulBeanContext;
 import org.jboss.ejb3.stateful.StatefulContainer;
-import org.jboss.ha.framework.server.CacheManagerLocator;
+import org.jboss.ha.cachemanager.CacheManagerLocator;
 import org.jboss.logging.Logger;
 import org.jboss.util.id.GUID;
 

Modified: projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/remoting/ReplicantsManagerInterceptorFactory.java
===================================================================
--- projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/remoting/ReplicantsManagerInterceptorFactory.java	2010-08-05 16:40:45 UTC (rev 107440)
+++ projects/ejb3/branches/infinispan-int/core/src/main/java/org/jboss/ejb3/remoting/ReplicantsManagerInterceptorFactory.java	2010-08-05 16:42:46 UTC (rev 107441)
@@ -29,6 +29,7 @@
 import org.jboss.aop.joinpoint.Joinpoint;
 import org.jboss.aspects.remoting.ReplicantsManagerInterceptor;
 import org.jboss.ejb3.session.SessionContainer;
+import org.jboss.ha.framework.server.HATarget;
 
 /**
  * Comment
@@ -46,7 +47,7 @@
    public Object createPerClass(Advisor advisor)
    {
       SessionContainer container = SessionContainer.getEJBContainer(advisor);
-      Map<?, ?> families = container.getClusterFamilies();
+      Map<String, HATarget> families = container.getClusterFamilies();
       assert families != null : "families is null";
       return new ReplicantsManagerInterceptor(families);
    }



More information about the jboss-cvs-commits mailing list