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

View File

@ -64,10 +64,12 @@ import org.jboss.cache.transaction.BatchModeTransactionManager;
public abstract class AbstractEntityRegionAccessStrategyTestCase extends AbstractJBossCacheTestCase {
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 VALUE2 = "VALUE2";
protected static int testCount;
protected static Configuration localCfg;
protected static JBossCacheRegionFactory localRegionFactory;
protected static Cache localCache;
@ -116,9 +118,15 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
protected void setUp() throws Exception {
super.setUp();
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
localEntityRegion = localRegionFactory.buildEntityRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription());
localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType());
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
remoteEntityRegion = remoteRegionFactory.buildEntityRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription());
remoteAccessStrategy = remoteEntityRegion.buildAccessStrategy(getAccessType());
@ -187,6 +195,24 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
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
* as we expected.
@ -220,7 +246,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
* Second tries to do a putFromLoad with stale data (i.e. it took
* longer to read from the db). Both commit their tx. Then
* 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).
*
* @param useMinimalAPI
@ -228,6 +254,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
*/
private void putFromLoadTest(final boolean useMinimalAPI) throws Exception {
final String KEY = KEY_BASE + testCount++;
final CountDownLatch writeLatch1 = new CountDownLatch(1);
final CountDownLatch writeLatch2 = new CountDownLatch(1);
final CountDownLatch completionLatch = new CountDownLatch(2);
@ -319,13 +347,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertTrue("Threads completed", completionLatch.await(2, TimeUnit.SECONDS));
if (node1Failure != null)
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
assertThreadsRanCleanly();
long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp));
@ -350,6 +372,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
*/
public void testInsert() throws Exception {
final String KEY = KEY_BASE + testCount++;
final CountDownLatch readLatch = new CountDownLatch(1);
final CountDownLatch commitLatch = new CountDownLatch(1);
final CountDownLatch completionLatch = new CountDownLatch(2);
@ -431,13 +455,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS));
}
if (node1Failure != null)
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
assertThreadsRanCleanly();
long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE1, localAccessStrategy.get(KEY, txTimestamp));
@ -450,6 +468,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
*/
public void testUpdate() throws Exception {
final String KEY = KEY_BASE + testCount++;
// Set up initial state
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
@ -542,13 +562,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
assertTrue(completionLatch.await(1, TimeUnit.SECONDS));
}
if (node1Failure != null)
throw node1Failure;
if (node2Failure != null)
throw node2Failure;
assertEquals("node1 saw no exceptions", null, node1Exception);
assertEquals("node2 saw no exceptions", null, node2Exception);
assertThreadsRanCleanly();
long txTimestamp = System.currentTimeMillis();
assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp));
@ -591,6 +605,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
}
private void evictOrRemoveTest(boolean evict) {
final String KEY = KEY_BASE + testCount++;
assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
@ -616,6 +633,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
private void evictOrRemoveAllTest(boolean evict) {
final String KEY = KEY_BASE + testCount++;
Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX);
Node regionRoot = localCache.getRoot().getChild(regionFqn);
@ -641,14 +660,16 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis()));
// Wait for async propagation
sleep(250);
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
// Wait for async propagation
sleep(250);
if (isUsingOptimisticLocking()) {
regionRoot = localCache.getRoot().getChild(regionFqn);
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 {
final String KEY = KEY_BASE + testCount++;
long txTimestamp = System.currentTimeMillis();
BatchModeTransactionManager.getInstance().begin();
assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
@ -77,6 +80,9 @@ public abstract class AbstractReadOnlyAccessTestCase extends AbstractEntityRegio
@Override
public void testUpdate() throws Exception {
final String KEY = KEY_BASE + testCount++;
try {
localAccessStrategy.update(KEY, VALUE2, new Integer(2), new Integer(1));
fail("Call to update did not throw exception");

View File

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