Author: bstansberry(a)jboss.com
Date: 2009-08-18 01:55:29 -0400 (Tue, 18 Aug 2009)
New Revision: 8189
Added:
core/trunk/src/test/java/org/jboss/cache/buddyreplication/DataGravitationCleanupFromDefunctTreeTest.java
Modified:
core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java
Log:
[JBCACHE-1530] Do it right this time
Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java 2009-08-17
15:09:11 UTC (rev 8188)
+++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java 2009-08-18
05:55:29 UTC (rev 8189)
@@ -761,7 +761,7 @@
{
coreFqn = buddyFqnTransformer.getActualFqn(backupFqn);
}
- Fqn<?> base = Fqn.fromRelativeElements(BUDDY_BACKUP_SUBTREE_FQN,
gen.owner, Integer.valueOf(gen.generation));
+ Fqn<?> base =
Fqn.fromRelativeElements(buddyFqnTransformer.getDeadBackupRoot(gen.owner),
Integer.valueOf(gen.generation));
result.add(Fqn.fromRelativeFqn(base, coreFqn));
}
}
@@ -1186,7 +1186,7 @@
historySet = newHistorySet;
}
- DefunctDataHistory history = new DefunctDataHistory(ownerName, (Integer)
defunctBackupRootFqn.getLastElement(), System.currentTimeMillis());
+ DefunctDataHistory history = new DefunctDataHistory(dataOwner, (Integer)
defunctBackupRootFqn.getLastElement(), System.currentTimeMillis());
historySet.add(history);
for (Object child : backupRoot.getChildren())
@@ -1412,13 +1412,13 @@
private class DefunctDataHistory
{
- private final String owner;
+ private final Address owner;
private final int generation;
private final long timestamp;
private long dataMoved;
private long moveElapsedTime;
- private DefunctDataHistory(String owner, int generation, long timestamp)
+ private DefunctDataHistory(Address owner, int generation, long timestamp)
{
this.owner = owner;
this.generation = generation;
@@ -1434,11 +1434,11 @@
private boolean isStale()
{
if (dataMoved == 0)
- return false;
+ return false; // migration is still ongoing
long max = Math.max(BuddyManager.this.configuration.getLockAcquisitionTimeout(),
60000);
max = max + moveElapsedTime;
- return System.currentTimeMillis() - max < dataMoved;
+ return System.currentTimeMillis() - max > dataMoved;
}
}
}
\ No newline at end of file
Added:
core/trunk/src/test/java/org/jboss/cache/buddyreplication/DataGravitationCleanupFromDefunctTreeTest.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/buddyreplication/DataGravitationCleanupFromDefunctTreeTest.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/buddyreplication/DataGravitationCleanupFromDefunctTreeTest.java 2009-08-18
05:55:29 UTC (rev 8189)
@@ -0,0 +1,124 @@
+package org.jboss.cache.buddyreplication;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeCreated;
+import org.jboss.cache.notifications.event.NodeCreatedEvent;
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.Test;
+
+/**
+ * Test for handling of JBCACHE-1530.
+ *
+ * @author Brian Stansberry
+ */
+@Test(groups = "functional", testName =
"buddyreplication.DataGravitationCleanupFromDefunctTreeTest")
+public class DataGravitationCleanupFromDefunctTreeTest extends BuddyReplicationTestsBase
+{
+ @CacheListener
+ public static class GravitationBlocker
+ {
+ private final Fqn<String> toBlock;
+ private final CountDownLatch toTrigger;
+ private final CountDownLatch toAwait;
+ private boolean blocked;
+
+ GravitationBlocker(Fqn<String> toBlock, CountDownLatch toTrigger,
CountDownLatch toAwait)
+ {
+ this.toBlock = toBlock;
+ this.toTrigger = toTrigger;
+ this.toAwait = toAwait;
+ }
+
+ @NodeCreated
+ public void nodeAdded(NodeCreatedEvent event)
+ {
+ if (!blocked && event.isOriginLocal() &&
event.getFqn().equals(toBlock))
+ {
+ blocked = true;
+ toTrigger.countDown();
+ try
+ {
+// System.out.println("blocking " + System.currentTimeMillis());
+ toAwait.await(10, TimeUnit.SECONDS);
+// System.out.println("released " + System.currentTimeMillis());
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ }
+
+ public void testOwnerDiesInMidGravitation() throws Exception
+ {
+ final List<CacheSPI<Object, Object>> caches = createCaches(1, 4, false,
false, false, false);
+ cachesTL.set(caches);
+
+ for (CacheSPI<Object, Object> c : caches)
+ {
+ c.getConfiguration().setFetchInMemoryState(false);
+
c.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+ c.start();
+ }
+
+ waitForBuddy(caches.get(0), caches.get(1), false);
+ waitForBuddy(caches.get(1), caches.get(2), false);
+ waitForBuddy(caches.get(2), caches.get(3), false);
+ waitForBuddy(caches.get(3), caches.get(0), false);
+ Thread.sleep(2000);//wait for state transfer
+
+ final Fqn<String> fqn = Fqn.fromString("/0");
+ caches.get(0).put(fqn, "k", "v");
+ Fqn backup = fqnTransformer.getBackupFqn(caches.get(0).getLocalAddress(), fqn);
+ assert (caches.get(1).exists(backup));
+
+ CountDownLatch toTrigger = new CountDownLatch(1);
+ CountDownLatch toAwait = new CountDownLatch(1);
+ GravitationBlocker blocker = new GravitationBlocker(fqn, toTrigger, toAwait);
+ caches.get(2).addCacheListener(blocker);
+
+ Future<?> future = Executors.newSingleThreadExecutor().submit(new Runnable()
{
+ public void run() {
+ // Trigger a gravitation
+
caches.get(2).getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
+ caches.get(2).get(fqn, "k");
+ }
+ });
+
+ assert (toTrigger.await(5, TimeUnit.SECONDS));
+
+ // Gravitation is now blocking on adding data to cache2
+
+ caches.get(0).stop();
+// System.out.println("stopped 0 " + System.currentTimeMillis());
+ // TODO need a way to know when this is done
+ TestingUtil.sleepThread(1000); // buddy group re-formation is async
+
+ toAwait.countDown(); // gravitation can now complete
+ assert (future.get(5, TimeUnit.SECONDS) == null); // and it now is complete
+
+ assert (blocker.blocked);
+
+ backup = fqnTransformer.getBackupFqn(caches.get(2).getLocalAddress(), fqn);
+ assert (caches.get(3).exists(backup));
+
+ assert ("v".equals(caches.get(2).put(fqn, "k",
"v1")));
+
+ // Now we gravitate to cache1. IF it has original "v" in its :DEAD tree
+ // it will gravitate that rather than asking cache3 and the assert will fail
+
+
caches.get(1).getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
+ Object val = caches.get(1).get(fqn, "k");
+ assert "v1".equals(val) : val + " is 'v1'";
+ }
+}
Property changes on:
core/trunk/src/test/java/org/jboss/cache/buddyreplication/DataGravitationCleanupFromDefunctTreeTest.java
___________________________________________________________________
Name: svn:keywords
+