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 ju...@apache.org on 2013/02/21 10:12:05 UTC

svn commit: r1448557 - /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java

Author: jukka
Date: Thu Feb 21 09:12:04 2013
New Revision: 1448557

URL: http://svn.apache.org/r1448557
Log:
OAK-633: SegmentMK: Hierarchy of journals

Use exponential backoff to reduce commit contention

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java?rev=1448557&r1=1448556&r2=1448557&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java Thu Feb 21 09:12:04 2013
@@ -27,6 +27,8 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.commit.MergingNodeStateDiff.DELETE_DELETED_NODE;
 import static org.apache.jackrabbit.oak.plugins.commit.MergingNodeStateDiff.DELETE_DELETED_PROPERTY;
 
+import java.util.concurrent.TimeUnit;
+
 import javax.annotation.Nonnull;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -176,20 +178,34 @@ class SegmentNodeStoreBranch implements 
             throws CommitFailedException {
         RecordId originalBaseId = baseId;
         RecordId originalRootId = rootId;
+        long backoff = 1;
         for (int i = 0; i < 10; i++) {
+            // rebase to latest head and apply commit hooks
             rebase();
-            RecordId headId =
-                    writer.writeNode(hook.processCommit(getBase(), getRoot()));
+            RecordId headId = writer.writeNode(
+                    hook.processCommit(getBase(), getRoot()));
             writer.flush();
+
+            // use optimistic locking to update the journal
             if (store.setJournalHead(journal, headId, baseId)) {
                 baseId = headId;
                 rootId = headId;
                 return getRoot();
             }
+
+            // someone else was faster, so clear state and try again later
             baseId = originalBaseId;
             rootId = originalRootId;
+
+            // use exponential backoff to reduce contention
+            try {
+                TimeUnit.MICROSECONDS.sleep(backoff);
+                backoff *= 2;
+            } catch (InterruptedException e) {
+                throw new CommitFailedException("Commit was interrupted", e);
+            }
         }
-        throw new CommitFailedException();
+        throw new CommitFailedException("System overloaded, try again later");
     }
 
     @Override