[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