[infinispan-commits] Infinispan SVN: r340 - in trunk/core/src: main/java/org/infinispan/interceptors and 1 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Tue May 26 07:22:05 EDT 2009
Author: vblagojevic at jboss.com
Date: 2009-05-26 07:22:05 -0400 (Tue, 26 May 2009)
New Revision: 340
Added:
trunk/core/src/test/java/org/infinispan/replication/SyncReplImplicitLockingTest.java
Modified:
trunk/core/src/main/java/org/infinispan/commands/LockControlCommand.java
trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java
Log:
[ISPN-70] - Transparent eager locking for transactions
tuning, unit test
Modified: trunk/core/src/main/java/org/infinispan/commands/LockControlCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/LockControlCommand.java 2009-05-26 10:42:08 UTC (rev 339)
+++ trunk/core/src/main/java/org/infinispan/commands/LockControlCommand.java 2009-05-26 11:22:05 UTC (rev 340)
@@ -32,6 +32,12 @@
import java.util.Collection;
/**
+ * LockControlCommand is a command that enables distributed locking across infinispan nodes.
+ * <p>
+ * For more details refer to:
+ * https://jira.jboss.org/jira/browse/ISPN-70
+ * https://jira.jboss.org/jira/browse/ISPN-48
+ *
* @author Vladimir Blagojevic (<a href="mailto:vblagoje at redhat.com">vblagoje at redhat.com</a>)
* @param
* @since 4.0
@@ -129,6 +135,7 @@
return "LockControlCommand{" +
"gtx=" + globalTx +
", cacheName='" + cacheName +
+ ", implicit='" + implicit +
", keys=" + keys + '}';
}
}
Modified: trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java 2009-05-26 10:42:08 UTC (rev 339)
+++ trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java 2009-05-26 11:22:05 UTC (rev 340)
@@ -19,6 +19,11 @@
* Interceptor in charge of eager, implicit locking of cache keys across cluster within
* transactional context
*
+ * <p>
+ * For more details refer to:
+ * https://jira.jboss.org/jira/browse/ISPN-70
+ * https://jira.jboss.org/jira/browse/ISPN-48
+ *
* @author <a href="mailto:vblagoje at redhat.com">Vladimir Blagojevic (vblagoje at redhat.com)</a>
* @since 4.0
*/
@@ -36,7 +41,7 @@
throws Throwable {
boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
if (localTxScope) {
- return lockEagerly(ctx, Collections.singleton(command.getKey()));
+ lockEagerly(ctx, Collections.singleton(command.getKey()));
}
return invokeNextInterceptor(ctx, command);
}
@@ -45,7 +50,7 @@
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
if (localTxScope) {
- return lockEagerly(ctx, Collections.singleton(command.getKey()));
+ lockEagerly(ctx, Collections.singleton(command.getKey()));
}
return invokeNextInterceptor(ctx, command);
}
@@ -55,7 +60,7 @@
throws Throwable {
boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
if (localTxScope) {
- return lockEagerly(ctx, Collections.singleton(command.getKey()));
+ lockEagerly(ctx, Collections.singleton(command.getKey()));
}
return invokeNextInterceptor(ctx, command);
}
@@ -64,7 +69,7 @@
public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
if (localTxScope) {
- return lockEagerly(ctx, command.getMap().keySet());
+ lockEagerly(ctx, command.getMap().keySet());
}
return invokeNextInterceptor(ctx, command);
}
@@ -73,7 +78,7 @@
public Object visitEvictCommand(InvocationContext ctx, EvictCommand command) throws Throwable {
boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
if (localTxScope) {
- return lockEagerly(ctx, Collections.singleton(command.getKey()));
+ lockEagerly(ctx, Collections.singleton(command.getKey()));
}
return invokeNextInterceptor(ctx, command);
}
@@ -83,7 +88,7 @@
throws Throwable {
boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
if (localTxScope) {
- return lockEagerly(ctx, Collections.singleton(command.getKey()));
+ lockEagerly(ctx, Collections.singleton(command.getKey()));
}
return invokeNextInterceptor(ctx, command);
}
Added: trunk/core/src/test/java/org/infinispan/replication/SyncReplImplicitLockingTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/replication/SyncReplImplicitLockingTest.java (rev 0)
+++ trunk/core/src/test/java/org/infinispan/replication/SyncReplImplicitLockingTest.java 2009-05-26 11:22:05 UTC (rev 340)
@@ -0,0 +1,194 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.infinispan.replication;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.transaction.TransactionManager;
+
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for implicit locking
+ *
+ * Transparent eager locking for transactions
+ * https://jira.jboss.org/jira/browse/ISPN-70
+ *
+ * @author <a href="mailto:vblagoje at redhat.com">Vladimir Blagojevic (vblagoje at redhat.com)</a>
+ */
+ at Test(groups = "functional", testName = "replication.SyncReplImplicitLockingTest")
+public class SyncReplImplicitLockingTest extends MultipleCacheManagersTest {
+ Cache<String, String> cache1, cache2;
+ String k = "key", v = "value";
+
+ protected void createCacheManagers() throws Throwable {
+ Configuration replSync = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
+ replSync.setLockAcquisitionTimeout(500);
+ replSync.setUseEagerLocking(true);
+ replSync.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+ createClusteredCaches(2, "replication.SyncReplImplicitLockingTest", replSync);
+
+ cache1 = manager(0).getCache("replication.SyncReplImplicitLockingTest");
+ cache2 = manager(1).getCache("replication.SyncReplImplicitLockingTest");
+ }
+
+ public void testLocksReleasedWithoutExplicitUnlock() throws Exception {
+ locksReleasedWithoutExplicitUnlockHelper(false);
+ locksReleasedWithoutExplicitUnlockHelper(true);
+ }
+
+ public void testConcurrentNonTxLocking() throws Exception {
+ concurrentLockingHelper(false, false);
+ concurrentLockingHelper(true, false);
+ }
+
+ public void testConcurrentTxLocking() throws Exception {
+ concurrentLockingHelper(false, true);
+ concurrentLockingHelper(true, true);
+ }
+
+ public void testLocksReleasedWithNoMods() throws Exception {
+ assertClusterSize("Should only be 2 caches in the cluster!!!", 2);
+
+ assertNull("Should be null", cache1.get(k));
+ assertNull("Should be null", cache2.get(k));
+
+ TransactionManager mgr = TestingUtil.getTransactionManager(cache1);
+ mgr.begin();
+
+ // do a dummy read
+ cache1.get(k);
+ mgr.commit();
+
+ assertNoLocks(cache1);
+ assertNoLocks(cache2);
+
+ cleanup();
+ }
+
+ private void concurrentLockingHelper(final boolean sameNode, final boolean useTx)
+ throws Exception {
+ assertClusterSize("Should only be 2 caches in the cluster!!!", 2);
+
+ assertNull("Should be null", cache1.get(k));
+ assertNull("Should be null", cache2.get(k));
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ log.info("Concurrent " + (useTx ? "tx" : "non-tx") + " write started "
+ + (sameNode ? "on same node..." : "on a different node..."));
+ TransactionManager mgr = null;
+ try {
+ if (useTx) {
+ mgr = TestingUtil.getTransactionManager(sameNode ? cache1 : cache2);
+ mgr.begin();
+ }
+ if (sameNode) {
+ cache1.put(k, "JBC");
+ } else {
+ cache2.put(k, "JBC");
+ }
+ } catch (Exception e) {
+ if (useTx) {
+ try {
+ mgr.commit();
+ } catch (Exception e1) {
+ }
+ }
+ latch.countDown();
+ }
+ }
+ };
+
+ String name = "Infinispan";
+ TransactionManager mgr = TestingUtil.getTransactionManager(cache1);
+ mgr.begin();
+ // lock node and start other thread whose write should now block
+ cache1.put(k, name);
+ t.start();
+
+ // wait till the put in thread t times out
+ assert latch.await(1, TimeUnit.SECONDS) : "Concurrent put didn't time out!";
+ mgr.commit();
+
+ t.join();
+
+ cache2.remove(k);
+ cleanup();
+ }
+
+ private void locksReleasedWithoutExplicitUnlockHelper(boolean useCommit) throws Exception {
+ assertClusterSize("Should only be 2 caches in the cluster!!!", 2);
+
+ assertNull("Should be null", cache1.get(k));
+ assertNull("Should be null", cache2.get(k));
+
+ String name = "Infinispan";
+ TransactionManager mgr = TestingUtil.getTransactionManager(cache1);
+ mgr.begin();
+
+ cache1.put(k, name);
+
+ if (useCommit)
+ mgr.commit();
+ else
+ mgr.rollback();
+
+ if (useCommit) {
+ assertEquals(name, cache1.get(k));
+ assertEquals("Should have replicated", name, cache2.get(k));
+ } else {
+ assertEquals(null, cache1.get(k));
+ assertEquals("Should not have replicated", null, cache2.get(k));
+ }
+
+ cache2.remove(k);
+ cleanup();
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void assertNoLocks(Cache cache) {
+ /*
+ * TODO cache.keySet() is not implemented yet LockManager lm =
+ * TestingUtil.extractLockManager(cache); for (Object key : cache.keySet()) assert
+ * !lm.isLocked(key);
+ */
+ }
+
+ protected void cleanup() {
+ assert cache1.isEmpty();
+ assert cache2.isEmpty();
+ cache1.clear();
+ cache2.clear();
+ }
+}
More information about the infinispan-commits
mailing list