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 2015/04/15 10:50:42 UTC

svn commit: r1673681 - in /jackrabbit/oak/branches/1.2: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java

Author: mreutegg
Date: Wed Apr 15 08:50:41 2015
New Revision: 1673681

URL: http://svn.apache.org/r1673681
Log:
OAK-2762: Configurable maxLockTryTimeMS

Merged revision 1673410 from trunk

Modified:
    jackrabbit/oak/branches/1.2/   (props changed)
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java

Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Apr 15 08:50:41 2015
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672834-1672835,1673351,1673662-1673664
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672834-1672835,1673351,1673410,1673662-1673664
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java?rev=1673681&r1=1673680&r2=1673681&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java Wed Apr 15 08:50:41 2015
@@ -27,6 +27,7 @@ import static org.apache.jackrabbit.oak.
 import java.util.Random;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 
 import javax.annotation.CheckForNull;
@@ -54,6 +55,7 @@ class DocumentNodeStoreBranch implements
     private static final PerfLogger perfLogger = new PerfLogger(
             LoggerFactory.getLogger(DocumentNodeStoreBranch.class.getName()
                     + ".perf"));
+    private static final int MAX_LOCK_TRY_TIME_MULTIPLIER = Integer.getInteger("oak.maxLockTryTimeMultiplier", 3);
 
     private static final ConcurrentMap<Thread, DocumentNodeStoreBranch> BRANCHES = Maps.newConcurrentMap();
     private static final Random RANDOM = new Random();
@@ -87,7 +89,7 @@ class DocumentNodeStoreBranch implements
         this.dispatcher = new ChangeDispatcher(store.getRoot());
         this.branchState = new Unmodified(checkNotNull(base));
         this.maximumBackoff = Math.max((long) store.getMaxBackOffMillis(), MIN_BACKOFF);
-        this.maxLockTryTimeMS = (long) (store.getMaxBackOffMillis() * 3);
+        this.maxLockTryTimeMS = (long) (store.getMaxBackOffMillis() * MAX_LOCK_TRY_TIME_MULTIPLIER);
         this.mergeLock = mergeLock;
     }
 
@@ -180,18 +182,17 @@ class DocumentNodeStoreBranch implements
         // retry with exclusive lock, blocking other
         // concurrent writes
         // do not wait forever
-        boolean acquired = false;
+        Lock lock = null;
         try {
-            acquired = mergeLock.writeLock()
-                    .tryLock(maxLockTryTimeMS, MILLISECONDS);
+            lock = acquireMergeLock(true);
         } catch (InterruptedException e) {
             // ignore and proceed with shared lock used in base class
         }
         try {
             return merge0(hook, info);
         } finally {
-            if (acquired) {
-                mergeLock.writeLock().unlock();
+            if (lock != null) {
+                lock.unlock();
             }
         }
     }
@@ -228,9 +229,9 @@ class DocumentNodeStoreBranch implements
             }
             try {
                 final long start = perfLogger.start();
-                boolean acquired = mergeLock.readLock().tryLock(maxLockTryTimeMS, MILLISECONDS);
-                perfLogger.end(start, 1, "Merge - Acquired lock");
+                Lock lock = acquireMergeLock(false);
                 try {
+                    perfLogger.end(start, 1, "Merge - Acquired lock");
                     return branchState.merge(checkNotNull(hook), checkNotNull(info));
                 } catch (CommitFailedException e) {
                     LOG.trace("Merge Error", e);
@@ -242,8 +243,8 @@ class DocumentNodeStoreBranch implements
                         throw e;
                     }
                 } finally {
-                    if (acquired) {
-                        mergeLock.readLock().unlock();
+                    if (lock != null) {
+                        lock.unlock();
                     }
                 }
             } catch (InterruptedException e) {
@@ -258,6 +259,33 @@ class DocumentNodeStoreBranch implements
                 ex.getCode(), msg, ex.getCause());
     }
 
+    /**
+     * Acquires the merge lock either exclusive or shared.
+     *
+     * @param exclusive whether to acquire the merge lock exclusive.
+     * @return the acquired merge lock or {@code null} if the operation timed
+     * out.
+     * @throws InterruptedException if the current thread is interrupted while
+     *                              acquiring the lock
+     */
+    @CheckForNull
+    private Lock acquireMergeLock(boolean exclusive)
+            throws InterruptedException {
+        Lock lock;
+        if (exclusive) {
+            lock = mergeLock.writeLock();
+        } else {
+            lock = mergeLock.readLock();
+        }
+        boolean acquired = lock.tryLock(maxLockTryTimeMS, MILLISECONDS);
+        if (!acquired) {
+            String mode = exclusive ? "exclusive" : "shared";
+            LOG.info("Time out while acquiring merge lock ({})", mode);
+            lock = null;
+        }
+        return lock;
+    }
+
     private interface Changes {
         void with(Commit c);
     }