[jboss-cvs] JBossAS SVN: r107211 - in projects/cluster: ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 29 13:30:52 EDT 2010


Author: pferraro
Date: 2010-07-29 13:30:51 -0400 (Thu, 29 Jul 2010)
New Revision: 107211

Added:
   projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/
   projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/CacheInvoker.java
   projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/RetryingCacheInvoker.java
   projects/cluster/ha-server-ispn/trunk/src/test/java/org/jboss/ha/ispn/invoker/
   projects/cluster/ha-server-ispn/trunk/src/test/java/org/jboss/ha/ispn/invoker/RetryingCacheInvokerTest.java
Removed:
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/CacheInvoker.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvoker.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvokerTest.java
Modified:
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerImpl.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerTest.java
Log:
Refactor retrying cache invoker into ha-server-ispn

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/CacheInvoker.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/CacheInvoker.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/CacheInvoker.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -1,62 +0,0 @@
-/*
- * 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.ha.web.tomcat.service.session.distributedcache.impl;
-
-import org.infinispan.Cache;
-import org.infinispan.atomic.AtomicMap;
-import org.infinispan.context.Flag;
-
-/**
- * Encapsulates logic used to invoke an operation on a cache.
- * @author Paul Ferraro
- */
-public interface CacheInvoker
-{
-   /**
-    * Invokes the specified operation on the specified cache.
-    * @param <R> the type of the cache operation result
-    * @param cache an infinispan cache
-    * @param operation a cache operation
-    * @return the result of the cache operation
-    */
-   <R> R invoke(Cache<String, AtomicMap<Object, Object>> cache, Operation<R> operation);
-   
-   /**
-    * Indicates whether or not to set the {@link Flag#FORCE_SYNCHRONOUS} flag prior to invoking the cache operation
-    * @param forceSynchronous
-    */
-   void setForceSynchronous(boolean forceSynchronous);
-   
-   /**
-    * Encapsulates a cache operation.
-    * @param <R> the return type of the cache operation
-    */
-   interface Operation<R>
-   {
-      /**
-       * Invoke some operation on the specified cache.
-       * @param cache an infinispan cache
-       * @return the result of the cache operation
-       */
-      R invoke(Cache<String, AtomicMap<Object, Object>> cache);
-   }
-}

Modified: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -22,6 +22,8 @@
 package org.jboss.ha.web.tomcat.service.session.distributedcache.impl;
 
 import org.jboss.ha.ispn.DefaultCacheContainerRegistry;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.ha.ispn.invoker.RetryingCacheInvoker;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactory;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;

Modified: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerImpl.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerImpl.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerImpl.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -45,6 +45,7 @@
 import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
 import org.infinispan.transaction.tm.BatchModeTransactionManager;
 import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
 import org.jboss.logging.Logger;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvoker.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvoker.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvoker.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -1,113 +0,0 @@
-/*
- * 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.ha.web.tomcat.service.session.distributedcache.impl;
-
-import org.infinispan.Cache;
-import org.infinispan.atomic.AtomicMap;
-import org.infinispan.context.Flag;
-import org.infinispan.remoting.transport.jgroups.SuspectException;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.jboss.logging.Logger;
-
-/**
- * A cache invoker implementation that retries after a specified set of intervals upon timeout or suspect.
- * @author Paul Ferraro
- */
-public class RetryingCacheInvoker implements CacheInvoker
-{
-   private static final Logger log = Logger.getLogger(RetryingCacheInvoker.class);
-   
-   private final int[] backOffIntervals;
-
-   private volatile boolean forceSynchronous = false;
-   
-   /**
-    * Creates a new RetryingCacheInvoker.
-    * @param backOffIntervals specifies the sleep intervals between retries, and implicitly, the number of retries
-    */
-   public RetryingCacheInvoker(int... backOffIntervals)
-   {
-      this.backOffIntervals = backOffIntervals;
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.impl.CacheInvoker#invoke(org.infinispan.Cache, org.jboss.ha.web.tomcat.service.session.distributedcache.impl.CacheInvoker.Operation)
-    */
-   @Override
-   public <R> R invoke(Cache<String, AtomicMap<Object, Object>> cache, Operation<R> operation)
-   {
-      Exception exception = null;
-
-      for (int i = 0; i <= this.backOffIntervals.length; ++i)
-      {
-         if (this.forceSynchronous)
-         {
-            cache.getAdvancedCache().withFlags(Flag.FORCE_SYNCHRONOUS);
-         }
-         
-         try
-         {
-            return operation.invoke(cache);
-         }
-         catch (TimeoutException e)
-         {
-            exception = e;
-         }
-         catch (SuspectException e)
-         {
-            exception = e;
-         }
-         
-         if (i < this.backOffIntervals.length)
-         {
-            int delay = this.backOffIntervals[i];
-            
-            try
-            {
-               if (log.isTraceEnabled())
-               {
-                  log.trace(String.format("Cache operation failed.  Retrying in %d ms", Integer.valueOf(delay)), exception);
-               }
-               
-               Thread.sleep(delay);
-            }
-            catch (InterruptedException e)
-            {
-               Thread.currentThread().interrupt();
-            }
-         }
-      }
-      
-      throw new RuntimeException(String.format("Aborting cache operation after %d retries.", Integer.valueOf(this.backOffIntervals.length + 1)), exception);
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.impl.CacheInvoker#setForceSynchronous(boolean)
-    */
-   @Override
-   public void setForceSynchronous(boolean forceSynchronous)
-   {
-      this.forceSynchronous = forceSynchronous;
-   }
-}

Modified: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryTest.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryTest.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -34,6 +34,7 @@
 import org.jboss.ha.ispn.config.CacheContainerRegistryConfiguration;
 import org.jboss.ha.ispn.config.CacheContainerRegistryConfigurationEntry;
 import org.jboss.ha.ispn.config.CacheContainerRegistryConfigurationSource;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
 import org.jboss.metadata.web.jboss.ReplicationConfig;
 import org.jboss.metadata.web.jboss.ReplicationGranularity;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;

Modified: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerTest.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerTest.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -40,6 +40,7 @@
 import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
 import org.infinispan.transaction.tm.BatchModeTransactionManager;
 import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
 import org.jboss.metadata.web.jboss.ReplicationConfig;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvokerTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvokerTest.java	2010-07-29 16:20:03 UTC (rev 107210)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/impl/RetryingCacheInvokerTest.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -1,226 +0,0 @@
-/*
- * 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.ha.web.tomcat.service.session.distributedcache.impl;
-
-import org.easymock.EasyMock;
-import org.infinispan.AdvancedCache;
-import org.infinispan.Cache;
-import org.infinispan.atomic.AtomicMap;
-import org.infinispan.context.Flag;
-import org.infinispan.remoting.transport.jgroups.SuspectException;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class RetryingCacheInvokerTest
-{
-   @Test
-   public void simple()
-   {
-      @SuppressWarnings("unchecked")
-      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
-      @SuppressWarnings("unchecked")
-      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
-      Object expected = new Object();
-      
-      CacheInvoker invoker = new RetryingCacheInvoker();
-      
-      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
-      
-      EasyMock.replay(cache, operation);
-      
-      Object result = invoker.invoke(cache, operation);
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertSame(expected, result);
-      
-      EasyMock.reset(cache, operation);
-   }
-   
-   @Test
-   public void forceSynchronous()
-   {
-      CacheInvoker invoker = new RetryingCacheInvoker();
-      
-      invoker.setForceSynchronous(true);
-      
-      @SuppressWarnings("unchecked")
-      AdvancedCache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(AdvancedCache.class);
-      @SuppressWarnings("unchecked")
-      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
-      Object expected = new Object();
-      
-      EasyMock.expect(cache.getAdvancedCache()).andReturn(cache);
-      EasyMock.expect(cache.withFlags(Flag.FORCE_SYNCHRONOUS)).andReturn(cache);
-      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
-      
-      EasyMock.replay(cache, operation);
-      
-      Object result = invoker.invoke(cache, operation);
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertSame(expected, result);
-      
-      EasyMock.reset(cache, operation);
-      
-      
-      invoker.setForceSynchronous(false);
-      
-      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
-      
-      EasyMock.replay(cache, operation);
-      
-      result = invoker.invoke(cache, operation);
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertSame(expected, result);
-      
-      EasyMock.reset(cache, operation);
-   }
-   
-   @Test
-   public void retryAfterTimeout()
-   {
-      @SuppressWarnings("unchecked")
-      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
-      @SuppressWarnings("unchecked")
-      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
-      Object expected = new Object();
-      
-      CacheInvoker invoker = new RetryingCacheInvoker(1);
-      
-      EasyMock.expect(operation.invoke(cache)).andThrow(new TimeoutException());
-      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
-      
-      EasyMock.replay(cache, operation);
-      
-      Object result = invoker.invoke(cache, operation);
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertSame(expected, result);
-      
-      EasyMock.reset(cache, operation);
-   }
-   
-   @Test
-   public void retryAfterSuspect()
-   {
-      @SuppressWarnings("unchecked")
-      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
-      @SuppressWarnings("unchecked")
-      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
-      Object expected = new Object();
-      
-      CacheInvoker invoker = new RetryingCacheInvoker(1);
-      
-      EasyMock.expect(operation.invoke(cache)).andThrow(new SuspectException());
-      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
-      
-      EasyMock.replay(cache, operation);
-      
-      Object result = invoker.invoke(cache, operation);
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertSame(expected, result);
-      
-      EasyMock.reset(cache, operation);
-   }
-   
-   @Test
-   public void timeout()
-   {
-      @SuppressWarnings("unchecked")
-      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
-      @SuppressWarnings("unchecked")
-      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
-      TimeoutException lastException = new TimeoutException();
-      
-      CacheInvoker invoker = new RetryingCacheInvoker(1);
-      
-      EasyMock.expect(operation.invoke(cache)).andThrow(new TimeoutException());
-      EasyMock.expect(operation.invoke(cache)).andThrow(lastException);
-      
-      EasyMock.replay(cache, operation);
-      
-      RuntimeException exception = null;
-      
-      try
-      {
-         invoker.invoke(cache, operation);
-      }
-      catch (RuntimeException e)
-      {
-         exception = e;
-      }
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertNotNull(exception);
-      Assert.assertSame(lastException, exception.getCause());
-      
-      EasyMock.reset(cache, operation);
-   }
-   
-   @Test
-   public void suspect()
-   {
-      @SuppressWarnings("unchecked")
-      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
-      @SuppressWarnings("unchecked")
-      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
-      SuspectException lastException = new SuspectException();
-      
-      CacheInvoker invoker = new RetryingCacheInvoker(1);
-      
-      EasyMock.expect(operation.invoke(cache)).andThrow(new SuspectException());
-      EasyMock.expect(operation.invoke(cache)).andThrow(lastException);
-      
-      EasyMock.replay(cache, operation);
-      
-      RuntimeException exception = null;
-      
-      try
-      {
-         invoker.invoke(cache, operation);
-      }
-      catch (RuntimeException e)
-      {
-         exception = e;
-      }
-      
-      EasyMock.verify(cache, operation);
-      
-      Assert.assertNotNull(exception);
-      Assert.assertSame(lastException, exception.getCause());
-      
-      EasyMock.reset(cache, operation);
-   }
-}

Added: projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/CacheInvoker.java
===================================================================
--- projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/CacheInvoker.java	                        (rev 0)
+++ projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/CacheInvoker.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -0,0 +1,62 @@
+/*
+ * 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.ha.ispn.invoker;
+
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.context.Flag;
+
+/**
+ * Encapsulates logic used to invoke an operation on a cache.
+ * @author Paul Ferraro
+ */
+public interface CacheInvoker
+{
+   /**
+    * Invokes the specified operation on the specified cache.
+    * @param <R> the type of the cache operation result
+    * @param cache an infinispan cache
+    * @param operation a cache operation
+    * @return the result of the cache operation
+    */
+   <R> R invoke(Cache<String, AtomicMap<Object, Object>> cache, Operation<R> operation);
+   
+   /**
+    * Indicates whether or not to set the {@link Flag#FORCE_SYNCHRONOUS} flag prior to invoking the cache operation
+    * @param forceSynchronous
+    */
+   void setForceSynchronous(boolean forceSynchronous);
+   
+   /**
+    * Encapsulates a cache operation.
+    * @param <R> the return type of the cache operation
+    */
+   interface Operation<R>
+   {
+      /**
+       * Invoke some operation on the specified cache.
+       * @param cache an infinispan cache
+       * @return the result of the cache operation
+       */
+      R invoke(Cache<String, AtomicMap<Object, Object>> cache);
+   }
+}

Added: projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/RetryingCacheInvoker.java
===================================================================
--- projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/RetryingCacheInvoker.java	                        (rev 0)
+++ projects/cluster/ha-server-ispn/trunk/src/main/java/org/jboss/ha/ispn/invoker/RetryingCacheInvoker.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -0,0 +1,113 @@
+/*
+ * 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.ha.ispn.invoker;
+
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.context.Flag;
+import org.infinispan.remoting.transport.jgroups.SuspectException;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.jboss.logging.Logger;
+
+/**
+ * A cache invoker implementation that retries after a specified set of intervals upon timeout or suspect.
+ * @author Paul Ferraro
+ */
+public class RetryingCacheInvoker implements CacheInvoker
+{
+   private static final Logger log = Logger.getLogger(RetryingCacheInvoker.class);
+   
+   private final int[] backOffIntervals;
+
+   private volatile boolean forceSynchronous = false;
+   
+   /**
+    * Creates a new RetryingCacheInvoker.
+    * @param backOffIntervals specifies the sleep intervals between retries, and implicitly, the number of retries
+    */
+   public RetryingCacheInvoker(int... backOffIntervals)
+   {
+      this.backOffIntervals = backOffIntervals;
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.impl.CacheInvoker#invoke(org.infinispan.Cache, org.jboss.ha.web.tomcat.service.session.distributedcache.impl.CacheInvoker.Operation)
+    */
+   @Override
+   public <R> R invoke(Cache<String, AtomicMap<Object, Object>> cache, Operation<R> operation)
+   {
+      Exception exception = null;
+
+      for (int i = 0; i <= this.backOffIntervals.length; ++i)
+      {
+         if (this.forceSynchronous)
+         {
+            cache.getAdvancedCache().withFlags(Flag.FORCE_SYNCHRONOUS);
+         }
+         
+         try
+         {
+            return operation.invoke(cache);
+         }
+         catch (TimeoutException e)
+         {
+            exception = e;
+         }
+         catch (SuspectException e)
+         {
+            exception = e;
+         }
+         
+         if (i < this.backOffIntervals.length)
+         {
+            int delay = this.backOffIntervals[i];
+            
+            try
+            {
+               if (log.isTraceEnabled())
+               {
+                  log.trace(String.format("Cache operation failed.  Retrying in %d ms", Integer.valueOf(delay)), exception);
+               }
+               
+               Thread.sleep(delay);
+            }
+            catch (InterruptedException e)
+            {
+               Thread.currentThread().interrupt();
+            }
+         }
+      }
+      
+      throw new RuntimeException(String.format("Aborting cache operation after %d retries.", Integer.valueOf(this.backOffIntervals.length + 1)), exception);
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.impl.CacheInvoker#setForceSynchronous(boolean)
+    */
+   @Override
+   public void setForceSynchronous(boolean forceSynchronous)
+   {
+      this.forceSynchronous = forceSynchronous;
+   }
+}

Added: projects/cluster/ha-server-ispn/trunk/src/test/java/org/jboss/ha/ispn/invoker/RetryingCacheInvokerTest.java
===================================================================
--- projects/cluster/ha-server-ispn/trunk/src/test/java/org/jboss/ha/ispn/invoker/RetryingCacheInvokerTest.java	                        (rev 0)
+++ projects/cluster/ha-server-ispn/trunk/src/test/java/org/jboss/ha/ispn/invoker/RetryingCacheInvokerTest.java	2010-07-29 17:30:51 UTC (rev 107211)
@@ -0,0 +1,226 @@
+/*
+ * 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.ha.ispn.invoker;
+
+import org.easymock.EasyMock;
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.context.Flag;
+import org.infinispan.remoting.transport.jgroups.SuspectException;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class RetryingCacheInvokerTest
+{
+   @Test
+   public void simple()
+   {
+      @SuppressWarnings("unchecked")
+      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
+      @SuppressWarnings("unchecked")
+      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
+      Object expected = new Object();
+      
+      CacheInvoker invoker = new RetryingCacheInvoker();
+      
+      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
+      
+      EasyMock.replay(cache, operation);
+      
+      Object result = invoker.invoke(cache, operation);
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertSame(expected, result);
+      
+      EasyMock.reset(cache, operation);
+   }
+   
+   @Test
+   public void forceSynchronous()
+   {
+      CacheInvoker invoker = new RetryingCacheInvoker();
+      
+      invoker.setForceSynchronous(true);
+      
+      @SuppressWarnings("unchecked")
+      AdvancedCache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(AdvancedCache.class);
+      @SuppressWarnings("unchecked")
+      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
+      Object expected = new Object();
+      
+      EasyMock.expect(cache.getAdvancedCache()).andReturn(cache);
+      EasyMock.expect(cache.withFlags(Flag.FORCE_SYNCHRONOUS)).andReturn(cache);
+      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
+      
+      EasyMock.replay(cache, operation);
+      
+      Object result = invoker.invoke(cache, operation);
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertSame(expected, result);
+      
+      EasyMock.reset(cache, operation);
+      
+      
+      invoker.setForceSynchronous(false);
+      
+      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
+      
+      EasyMock.replay(cache, operation);
+      
+      result = invoker.invoke(cache, operation);
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertSame(expected, result);
+      
+      EasyMock.reset(cache, operation);
+   }
+   
+   @Test
+   public void retryAfterTimeout()
+   {
+      @SuppressWarnings("unchecked")
+      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
+      @SuppressWarnings("unchecked")
+      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
+      Object expected = new Object();
+      
+      CacheInvoker invoker = new RetryingCacheInvoker(1);
+      
+      EasyMock.expect(operation.invoke(cache)).andThrow(new TimeoutException());
+      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
+      
+      EasyMock.replay(cache, operation);
+      
+      Object result = invoker.invoke(cache, operation);
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertSame(expected, result);
+      
+      EasyMock.reset(cache, operation);
+   }
+   
+   @Test
+   public void retryAfterSuspect()
+   {
+      @SuppressWarnings("unchecked")
+      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
+      @SuppressWarnings("unchecked")
+      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
+      Object expected = new Object();
+      
+      CacheInvoker invoker = new RetryingCacheInvoker(1);
+      
+      EasyMock.expect(operation.invoke(cache)).andThrow(new SuspectException());
+      EasyMock.expect(operation.invoke(cache)).andReturn(expected);
+      
+      EasyMock.replay(cache, operation);
+      
+      Object result = invoker.invoke(cache, operation);
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertSame(expected, result);
+      
+      EasyMock.reset(cache, operation);
+   }
+   
+   @Test
+   public void timeout()
+   {
+      @SuppressWarnings("unchecked")
+      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
+      @SuppressWarnings("unchecked")
+      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
+      TimeoutException lastException = new TimeoutException();
+      
+      CacheInvoker invoker = new RetryingCacheInvoker(1);
+      
+      EasyMock.expect(operation.invoke(cache)).andThrow(new TimeoutException());
+      EasyMock.expect(operation.invoke(cache)).andThrow(lastException);
+      
+      EasyMock.replay(cache, operation);
+      
+      RuntimeException exception = null;
+      
+      try
+      {
+         invoker.invoke(cache, operation);
+      }
+      catch (RuntimeException e)
+      {
+         exception = e;
+      }
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertNotNull(exception);
+      Assert.assertSame(lastException, exception.getCause());
+      
+      EasyMock.reset(cache, operation);
+   }
+   
+   @Test
+   public void suspect()
+   {
+      @SuppressWarnings("unchecked")
+      Cache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(Cache.class);
+      @SuppressWarnings("unchecked")
+      CacheInvoker.Operation<Object> operation = EasyMock.createStrictMock(CacheInvoker.Operation.class);
+      SuspectException lastException = new SuspectException();
+      
+      CacheInvoker invoker = new RetryingCacheInvoker(1);
+      
+      EasyMock.expect(operation.invoke(cache)).andThrow(new SuspectException());
+      EasyMock.expect(operation.invoke(cache)).andThrow(lastException);
+      
+      EasyMock.replay(cache, operation);
+      
+      RuntimeException exception = null;
+      
+      try
+      {
+         invoker.invoke(cache, operation);
+      }
+      catch (RuntimeException e)
+      {
+         exception = e;
+      }
+      
+      EasyMock.verify(cache, operation);
+      
+      Assert.assertNotNull(exception);
+      Assert.assertSame(lastException, exception.getCause());
+      
+      EasyMock.reset(cache, operation);
+   }
+}



More information about the jboss-cvs-commits mailing list