Author: mreutegg Date: Tue Nov 3 15:53:36 2015 New Revision: 1712313 URL: http://svn.apache.org/viewvc?rev=1712313&view=rev Log: OAK-3579: BackgroundLeaseUpdate not scheduled when asyncDelay=0
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1712313&r1=1712312&r2=1712313&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Tue Nov 3 15:53:36 2015 @@ -68,6 +68,8 @@ import javax.management.NotCompliantMBea import com.google.common.base.Function; import com.google.common.base.Predicates; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.common.cache.Cache; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -2561,18 +2563,35 @@ public final class DocumentNodeStore static abstract class NodeStoreTask implements Runnable { final WeakReference<DocumentNodeStore> ref; private final AtomicBoolean isDisposed; - private int delay; + private final Supplier<Integer> delaySupplier; - NodeStoreTask(DocumentNodeStore nodeStore, AtomicBoolean isDisposed) { - ref = new WeakReference<DocumentNodeStore>(nodeStore); - delay = nodeStore.getAsyncDelay(); + NodeStoreTask(final DocumentNodeStore nodeStore, + final AtomicBoolean isDisposed, + Supplier<Integer> delay) { + this.ref = new WeakReference<DocumentNodeStore>(nodeStore); this.isDisposed = isDisposed; + if (delay == null) { + delay = new Supplier<Integer>() { + @Override + public Integer get() { + DocumentNodeStore ns = ref.get(); + return ns != null ? ns.getAsyncDelay() : 0; + } + }; + } + this.delaySupplier = delay; + } + + NodeStoreTask(final DocumentNodeStore nodeStore, + final AtomicBoolean isDisposed) { + this(nodeStore, isDisposed, null); } protected abstract void execute(@Nonnull DocumentNodeStore nodeStore); @Override public void run() { + int delay = delaySupplier.get(); while (delay != 0 && !isDisposed.get()) { synchronized (isDisposed) { try { @@ -2588,7 +2607,7 @@ public final class DocumentNodeStore } catch (Throwable t) { LOG.warn("Background operation failed: " + t.toString(), t); } - delay = nodeStore.getAsyncDelay(); + delay = delaySupplier.get(); } else { // node store not in use anymore break; @@ -2633,7 +2652,7 @@ public final class DocumentNodeStore BackgroundLeaseUpdate(DocumentNodeStore nodeStore, AtomicBoolean isDisposed) { - super(nodeStore, isDisposed); + super(nodeStore, isDisposed, Suppliers.ofInstance(1000)); } @Override Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1712313&r1=1712312&r2=1712313&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java Tue Nov 3 15:53:36 2015 @@ -27,11 +27,15 @@ import static org.apache.jackrabbit.oak. import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.getModifiedInSecs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -40,6 +44,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; @@ -1621,6 +1626,47 @@ public class DocumentNodeStoreTest { } + // OAK-3579 + @Test + public void backgroundLeaseUpdateThread() throws Exception { + int clusterId = -1; + Random random = new Random(); + // pick a random clusterId between 1000 and 2000 + // and make sure it is not in use (give up after 10 tries) + for (int i = 0; i < 10; i++) { + int id = random.nextInt(1000) + 1000; + if (!backgroundLeaseUpdateThreadRunning(id)) { + clusterId = id; + break; + } + } + assertNotEquals(-1, clusterId); + DocumentNodeStore ns = builderProvider.newBuilder().setAsyncDelay(0) + .setClusterId(clusterId).getNodeStore(); + for (int i = 0; i < 10; i++) { + if (!backgroundLeaseUpdateThreadRunning(clusterId)) { + Thread.sleep(100); + } + } + assertTrue(backgroundLeaseUpdateThreadRunning(clusterId)); + // access DocumentNodeStore to make sure it is not + // garbage collected prematurely + assertEquals(clusterId, ns.getClusterId()); + } + + private static boolean backgroundLeaseUpdateThreadRunning(int clusterId) { + String threadName = "DocumentNodeStore lease update thread (" + clusterId + ")"; + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + for (ThreadInfo ti : threadBean.getThreadInfo(threadBean.getAllThreadIds())) { + if (ti != null) { + if (threadName.equals(ti.getThreadName())) { + return true; + } + } + } + return false; + } + /** * Utility class that eases creating single cluster id merge conflicts. The two methods: * <ul>