Add workaround to avoid delays from concurrent FLUSH calls in JGroups 2.6.1

Use different "entity keys" per test to avoid cross-test pollution

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14253 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Brian Stansberry 2007-12-21 19:48:42 +00:00
parent ad856661ab
commit 773e1e46f1
4 changed files with 71 additions and 33 deletions

View File

@ -64,10 +64,12 @@ import org.jboss.cache.transaction.BatchModeTransactionManager;
public abstract class AbstractCollectionRegionAccessStrategyTestCase extends AbstractJBossCacheTestCase { public abstract class AbstractCollectionRegionAccessStrategyTestCase extends AbstractJBossCacheTestCase {
public static final String REGION_NAME = "test/com.foo.test"; public static final String REGION_NAME = "test/com.foo.test";
public static final String KEY = "KEY"; public static final String KEY_BASE = "KEY";
public static final String VALUE1 = "VALUE1"; public static final String VALUE1 = "VALUE1";
public static final String VALUE2 = "VALUE2"; public static final String VALUE2 = "VALUE2";
protected static int testCount;
protected static Configuration localCfg; protected static Configuration localCfg;
protected static JBossCacheRegionFactory localRegionFactory; protected static JBossCacheRegionFactory localRegionFactory;
protected static Cache localCache; protected static Cache localCache;
@ -114,12 +116,18 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
invalidation = CacheHelper.isClusteredInvalidation(localCache); invalidation = CacheHelper.isClusteredInvalidation(localCache);
synchronous = CacheHelper.isSynchronous(localCache); synchronous = CacheHelper.isSynchronous(localCache);
optimistic = localCache.getConfiguration().getNodeLockingScheme() == org.jboss.cache.config.Configuration.NodeLockingScheme.OPTIMISTIC; optimistic = localCache.getConfiguration().getNodeLockingScheme() == org.jboss.cache.config.Configuration.NodeLockingScheme.OPTIMISTIC;
localCollectionRegion = localRegionFactory.buildCollectionRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription()); localCollectionRegion = localRegionFactory.buildCollectionRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription());
localAccessStrategy = localCollectionRegion.buildAccessStrategy(getAccessType()); localAccessStrategy = localCollectionRegion.buildAccessStrategy(getAccessType());
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
remoteCollectionRegion = remoteRegionFactory.buildCollectionRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription()); remoteCollectionRegion = remoteRegionFactory.buildCollectionRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription());
remoteAccessStrategy = remoteCollectionRegion.buildAccessStrategy(getAccessType()); remoteAccessStrategy = remoteCollectionRegion.buildAccessStrategy(getAccessType());
@ -229,6 +237,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
*/ */
private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { private void putFromLoadTest(final boolean useMinimalAPI) throws Exception {
final String KEY = KEY_BASE + testCount++;
final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch1 = new CountDownLatch(1);
final CountDownLatch writeLatch2 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1);
final CountDownLatch completionLatch = new CountDownLatch(2); final CountDownLatch completionLatch = new CountDownLatch(2);
@ -400,6 +410,9 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
} }
private void evictOrRemoveTest(boolean evict) { private void evictOrRemoveTest(boolean evict) {
final String KEY = KEY_BASE + testCount++;
assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
@ -422,6 +435,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
} }
private void evictOrRemoveAllTest(boolean evict) { private void evictOrRemoveAllTest(boolean evict) {
final String KEY = KEY_BASE + testCount++;
Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX); Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX);

View File

@ -64,10 +64,12 @@ import org.jboss.cache.transaction.BatchModeTransactionManager;
public abstract class AbstractEntityRegionAccessStrategyTestCase extends AbstractJBossCacheTestCase { public abstract class AbstractEntityRegionAccessStrategyTestCase extends AbstractJBossCacheTestCase {
public static final String REGION_NAME = "test/com.foo.test"; public static final String REGION_NAME = "test/com.foo.test";
public static final String KEY = "KEY"; public static final String KEY_BASE = "KEY";
public static final String VALUE1 = "VALUE1"; public static final String VALUE1 = "VALUE1";
public static final String VALUE2 = "VALUE2"; public static final String VALUE2 = "VALUE2";
protected static int testCount;
protected static Configuration localCfg; protected static Configuration localCfg;
protected static JBossCacheRegionFactory localRegionFactory; protected static JBossCacheRegionFactory localRegionFactory;
protected static Cache localCache; protected static Cache localCache;
@ -116,9 +118,15 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
localEntityRegion = localRegionFactory.buildEntityRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription()); localEntityRegion = localRegionFactory.buildEntityRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription());
localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType()); localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType());
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
remoteEntityRegion = remoteRegionFactory.buildEntityRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription()); remoteEntityRegion = remoteRegionFactory.buildEntityRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription());
remoteAccessStrategy = remoteEntityRegion.buildAccessStrategy(getAccessType()); remoteAccessStrategy = remoteEntityRegion.buildAccessStrategy(getAccessType());
@ -186,6 +194,24 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
protected Fqn getRegionFqn(String regionName, String regionPrefix) { protected Fqn getRegionFqn(String regionName, String regionPrefix) {
return BasicRegionAdapter.getTypeLastRegionFqn(regionName, regionPrefix, EntityRegionImpl.TYPE); return BasicRegionAdapter.getTypeLastRegionFqn(regionName, regionPrefix, EntityRegionImpl.TYPE);
} }
protected void assertThreadsRanCleanly()
{
if (node1Failure != null)
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
if (node1Exception != null) {
log.error("node1 saw an exception", node1Exception);
assertEquals("node1 saw no exceptions", null, node1Exception);
}
if (node2Exception != null) {
log.error("node2 saw an exception", node2Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
}
}
/** /**
* This is just a setup test where we assert that the cache config is * This is just a setup test where we assert that the cache config is
@ -220,7 +246,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
* Second tries to do a putFromLoad with stale data (i.e. it took * Second tries to do a putFromLoad with stale data (i.e. it took
* longer to read from the db). Both commit their tx. Then * longer to read from the db). Both commit their tx. Then
* both start a new tx and get. First should see the updated data; * both start a new tx and get. First should see the updated data;
* second should either see the updated data (isInvalidation()( == false) * second should either see the updated data (isInvalidation() == false)
* or null (isInvalidation() == true). * or null (isInvalidation() == true).
* *
* @param useMinimalAPI * @param useMinimalAPI
@ -228,6 +254,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
*/ */
private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { private void putFromLoadTest(final boolean useMinimalAPI) throws Exception {
final String KEY = KEY_BASE + testCount++;
final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch1 = new CountDownLatch(1);
final CountDownLatch writeLatch2 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1);
final CountDownLatch completionLatch = new CountDownLatch(2); final CountDownLatch completionLatch = new CountDownLatch(2);
@ -319,13 +347,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertTrue("Threads completed", completionLatch.await(2, TimeUnit.SECONDS)); assertTrue("Threads completed", completionLatch.await(2, TimeUnit.SECONDS));
if (node1Failure != null) assertThreadsRanCleanly();
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp));
@ -349,6 +371,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
* Test method for {@link TransactionalAccess#insert(java.lang.Object, java.lang.Object, java.lang.Object)}. * Test method for {@link TransactionalAccess#insert(java.lang.Object, java.lang.Object, java.lang.Object)}.
*/ */
public void testInsert() throws Exception { public void testInsert() throws Exception {
final String KEY = KEY_BASE + testCount++;
final CountDownLatch readLatch = new CountDownLatch(1); final CountDownLatch readLatch = new CountDownLatch(1);
final CountDownLatch commitLatch = new CountDownLatch(1); final CountDownLatch commitLatch = new CountDownLatch(1);
@ -431,13 +455,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS)); assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS));
} }
if (node1Failure != null) assertThreadsRanCleanly();
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE1, localAccessStrategy.get(KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE1, localAccessStrategy.get(KEY, txTimestamp));
@ -449,6 +467,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
* Test method for {@link TransactionalAccess#update(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)}. * Test method for {@link TransactionalAccess#update(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)}.
*/ */
public void testUpdate() throws Exception { public void testUpdate() throws Exception {
final String KEY = KEY_BASE + testCount++;
// Set up initial state // Set up initial state
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
@ -542,13 +562,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertTrue(completionLatch.await(1, TimeUnit.SECONDS)); assertTrue(completionLatch.await(1, TimeUnit.SECONDS));
} }
if (node1Failure != null) assertThreadsRanCleanly();
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp));
@ -591,6 +605,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
} }
private void evictOrRemoveTest(boolean evict) { private void evictOrRemoveTest(boolean evict) {
final String KEY = KEY_BASE + testCount++;
assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
@ -615,6 +632,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
} }
private void evictOrRemoveAllTest(boolean evict) { private void evictOrRemoveAllTest(boolean evict) {
final String KEY = KEY_BASE + testCount++;
Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX); Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX);
@ -641,14 +660,16 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis())); assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis()));
// Wait for async propagation
sleep(250);
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
// Wait for async propagation // Wait for async propagation
sleep(250); sleep(250);
if (isUsingOptimisticLocking()) { if (isUsingOptimisticLocking()) {
regionRoot = localCache.getRoot().getChild(regionFqn); regionRoot = localCache.getRoot().getChild(regionFqn);
assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass());

View File

@ -58,6 +58,9 @@ public abstract class AbstractReadOnlyAccessTestCase extends AbstractEntityRegio
} }
private void putFromLoadTest(boolean minimal) throws Exception { private void putFromLoadTest(boolean minimal) throws Exception {
final String KEY = KEY_BASE + testCount++;
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin(); BatchModeTransactionManager.getInstance().begin();
assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
@ -77,6 +80,9 @@ public abstract class AbstractReadOnlyAccessTestCase extends AbstractEntityRegio
@Override @Override
public void testUpdate() throws Exception { public void testUpdate() throws Exception {
final String KEY = KEY_BASE + testCount++;
try { try {
localAccessStrategy.update(KEY, VALUE2, new Integer(2), new Integer(1)); localAccessStrategy.update(KEY, VALUE2, new Integer(2), new Integer(1));
fail("Call to update did not throw exception"); fail("Call to update did not throw exception");

View File

@ -53,6 +53,8 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
} }
public void testContestedPutFromLoad() throws Exception { public void testContestedPutFromLoad() throws Exception {
final String KEY = KEY_BASE + testCount++;
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
@ -129,13 +131,7 @@ public abstract class AbstractTransactionalAccessTestCase extends AbstractEntity
assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS)); assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS));
if (node1Failure != null) assertThreadsRanCleanly();
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
long txTimestamp = System.currentTimeMillis(); long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp)); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp));