You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2018/03/07 08:37:19 UTC

svn commit: r1826086 - in /jackrabbit/oak/trunk/oak-store-document/src: main/java/org/apache/jackrabbit/oak/plugins/document/ test/java/org/apache/jackrabbit/oak/plugins/document/

Author: mreutegg
Date: Wed Mar  7 08:37:19 2018
New Revision: 1826086

URL: http://svn.apache.org/viewvc?rev=1826086&view=rev
Log:
OAK-7308: Retry commit on transient DocumentStoreException

Modified:
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/FailingDocumentStore.java

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java?rev=1826086&r1=1826085&r2=1826086&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java Wed Mar  7 08:37:19 2018
@@ -347,7 +347,15 @@ class DocumentNodeStoreBranch implements
         if (msg == null) {
             msg = "Failed to merge changes to the underlying store";
         }
-        return new CommitFailedException(OAK, 1, msg, t);
+        String type = OAK;
+        if (t instanceof DocumentStoreException) {
+            DocumentStoreException dse = (DocumentStoreException) t;
+            if (dse.getType() == DocumentStoreException.Type.TRANSIENT) {
+                // set type to MERGE, which indicates a retry may work
+                type = MERGE;
+            }
+        }
+        return new CommitFailedException(type, 1, msg, t);
     }
 
     /**

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=1826086&r1=1826085&r2=1826086&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 Wed Mar  7 08:37:19 2018
@@ -24,6 +24,7 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.document.Collection.JOURNAL;
 import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
 import static org.apache.jackrabbit.oak.plugins.document.Collection.SETTINGS;
+import static org.apache.jackrabbit.oak.plugins.document.DocumentStoreException.Type.TRANSIENT;
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS;
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS_RESOLUTION;
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.NUM_REVS_THRESHOLD;
@@ -3604,6 +3605,38 @@ public class DocumentNodeStoreTest {
         );
     }
 
+    @Test
+    public void retryOnTransientDocumentStoreException() {
+        FailingDocumentStore store = new FailingDocumentStore(new MemoryDocumentStore());
+        DocumentNodeStore ns = builderProvider.newBuilder()
+                .setAsyncDelay(0).setDocumentStore(store).getNodeStore();
+        NodeBuilder builder = ns.getRoot().builder();
+        builder.child("foo");
+
+        store.fail().after(0).once();
+        try {
+            merge(ns, builder);
+            fail("CommitFailedException expected");
+        } catch (CommitFailedException e) {
+            // expected
+        } finally {
+            store.fail().never();
+        }
+
+        builder = ns.getRoot().builder();
+        builder.child("bar");
+
+        store.fail().after(0).withType(TRANSIENT).once();
+        try {
+            merge(ns, builder);
+        } catch (CommitFailedException e) {
+            fail(e.toString());
+        } finally {
+            store.fail().never();
+        }
+        assertTrue(ns.getRoot().hasChildNode("bar"));
+    }
+
     private void getChildNodeCountTest(int numChildren,
                                        Iterable<Long> maxValues,
                                        Iterable<Long> expectedValues)

Modified: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/FailingDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/FailingDocumentStore.java?rev=1826086&r1=1826085&r2=1826086&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/FailingDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/FailingDocumentStore.java Wed Mar  7 08:37:19 2018
@@ -23,6 +23,8 @@ import java.util.concurrent.atomic.Atomi
 
 import com.google.common.collect.Lists;
 
+import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException.Type;
+
 import static java.util.Collections.singletonList;
 import static java.util.Collections.singletonMap;
 
@@ -39,6 +41,8 @@ class FailingDocumentStore extends Docum
 
     private AtomicLong numFailures = new AtomicLong(0);
 
+    private Type exceptionType = Type.GENERIC;
+
     class Fail {
 
         private Fail() {
@@ -51,10 +55,16 @@ class FailingDocumentStore extends Docum
             return this;
         }
 
+        Fail withType(Type type) {
+            exceptionType = type;
+            return this;
+        }
+
         void never() {
             p = -1;
             numFailures.set(0);
             failAfter.set(Long.MAX_VALUE);
+            exceptionType = Type.GENERIC;
         }
 
         void once() {
@@ -167,7 +177,7 @@ class FailingDocumentStore extends Docum
     private void maybeFail() {
         if (random.nextFloat() < p || failAfter.getAndDecrement() <= 0) {
             if (numFailures.getAndDecrement() > 0) {
-                throw new DocumentStoreException("write operation failed");
+                throw new DocumentStoreException("write operation failed", null, exceptionType);
             }
         }
     }