Author: reschke
Date: Mon Sep 10 12:46:55 2018
New Revision: 1840462
URL: http://svn.apache.org/viewvc?rev=1840462&view=rev
Log:
OAK-7709: DocumentNodeStore dispose aborts when store was disposed due to
LeaseUpdate error
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1840462&r1=1840461&r2=1840462&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
Mon Sep 10 12:46:55 2018
@@ -719,19 +719,28 @@ public final class DocumentNodeStore
backgroundUpdateThread,
backgroundSweepThread);
+ DocumentStoreException ex = null;
+
// create a tombstone commit revision after isDisposed is set to true.
// commits created earlier than this revision will be able to finish
// and we'll get a headOfQueue() callback when they are done
// after this call there are no more pending trunk commits and
// the commit queue is empty and stays empty
- Revision tombstone = commitQueue.createRevision();
- commitQueue.done(tombstone, new CommitQueue.Callback() {
- @Override
- public void headOfQueue(@NotNull Revision revision) {
- setRoot(getHeadRevision().update(revision));
- unsavedLastRevisions.put(ROOT_PATH, revision);
+ if (!readOnlyMode) {
+ try {
+ Revision tombstone = commitQueue.createRevision();
+ commitQueue.done(tombstone, new CommitQueue.Callback() {
+ @Override
+ public void headOfQueue(@NotNull Revision revision) {
+ setRoot(getHeadRevision().update(revision));
+ unsavedLastRevisions.put(ROOT_PATH, revision);
+ }
+ });
+ } catch (DocumentStoreException e) {
+ LOG.error("dispose: a DocumentStoreException happened during
dispose's attempt to commit a tombstone: " + e, e);
+ ex = e;
}
- });
+ }
try {
bundlingConfigHandler.close();
@@ -739,7 +748,6 @@ public final class DocumentNodeStore
LOG.warn("Error closing bundlingConfigHandler",
bundlingConfigHandler, e);
}
- DocumentStoreException ex = null;
// do a final round of background operations after
// the background thread stopped
if (!readOnlyMode) {
Modified:
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1840462&r1=1840461&r2=1840462&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
Mon Sep 10 12:46:55 2018
@@ -762,6 +762,41 @@ public class DocumentNodeStoreTest {
assertTrue(store2.getRoot().getChildNode("test").getChildNode("node").exists());
}
+ // verify that the dispose method does a best effort in releasing
resources (see OAK-7709)
+ @Test
+ public void disposeAfterLeaseFailure() throws Exception {
+ try {
+ final AtomicBoolean documentStoreDisposeWasReached = new
AtomicBoolean(false);
+ Clock clock = new Clock.Virtual();
+ clock.waitUntil(System.currentTimeMillis());
+
+ MemoryDocumentStore docStore = new MemoryDocumentStore() {
+ @Override
+ public void dispose() {
+ documentStoreDisposeWasReached.set(true);
+ }
+ };
+
+ DocumentNodeStore store1 =
builderProvider.newBuilder().setDocumentStore(docStore).setAsyncDelay(0).clock(clock)
+ .setClusterId(1).getNodeStore();
+
+ ClusterNodeInfo.setClock(clock);
+ // wait until lease expires
+ clock.waitUntil(clock.getTime() +
store1.getClusterInfo().getLeaseTime() + 1000);
+
+ assertFalse(documentStoreDisposeWasReached.get());
+ try {
+ store1.dispose();
+ fail("expected lease failure exception; test setup may be
incorrect");
+ } catch (DocumentStoreException expected) {
+ // due to lease update failure
+ }
+ assertTrue("The DocumentStore instance's dispose() method was not
called", documentStoreDisposeWasReached.get());
+ } finally {
+ ClusterNodeInfo.resetClockToDefault();
+ }
+ }
+
// OAK-2336
@Test
public void readBranchCommit() throws Exception {