Repository: curator
Updated Branches:
  refs/heads/CURATOR-3.0 9fc755a9e -> f8814f619


Added Locker which uses Java 7's try-with-resource feature to make locking more 
reliable


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/58a8818b
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/58a8818b
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/58a8818b

Branch: refs/heads/CURATOR-3.0
Commit: 58a8818b749475cf2089d116c06359ad0390a2cc
Parents: d57aaeb
Author: randgalt <randg...@apache.org>
Authored: Sun Sep 6 12:26:56 2015 -0700
Committer: randgalt <randg...@apache.org>
Committed: Sun Sep 6 12:26:56 2015 -0700

----------------------------------------------------------------------
 .../curator/framework/recipes/locks/Locker.java | 67 ++++++++++++++++++++
 .../locks/TestInterProcessMutexBase.java        | 22 +++++++
 2 files changed, 89 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/58a8818b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/Locker.java
----------------------------------------------------------------------
diff --git 
a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/Locker.java
 
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/Locker.java
new file mode 100644
index 0000000..97788af
--- /dev/null
+++ 
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/Locker.java
@@ -0,0 +1,67 @@
+package org.apache.curator.framework.recipes.locks;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * <p>
+ *     Utility for safely acquiring a lock and releasing it using Java 7's
+ *     try-with-resource feature.
+ * </p>
+ *
+ * <p>
+ *     Canonical usage:
+ * <code><pre>
+ *     InterProcessMutex mutex = new InterProcessMutex(...) // or any 
InterProcessLock
+ *     try ( Locker locker = new Locker(mutex, maxTimeout, unit) )
+ *     {
+ *         // do work
+ *     }
+ * </pre></code>
+ * </p>
+ */
+public class Locker implements AutoCloseable
+{
+    private final InterProcessLock lock;
+    private final AtomicBoolean acquired;
+
+    /**
+     * @param lock a lock implementation (e.g. {@link InterProcessMutex}, 
{@link InterProcessSemaphoreV2}, etc.)
+     * @param timeout max timeout to acquire lock
+     * @param unit time unit of timeout
+     * @throws Exception Curator errors or {@link TimeoutException} if the 
lock cannot be acquired within the timeout
+     */
+    public Locker(InterProcessLock lock, long timeout, TimeUnit unit) throws 
Exception
+    {
+        this.lock = lock;
+        acquired = new AtomicBoolean(acquireLock(lock, timeout, unit));
+        if ( !acquired.get() )
+        {
+            throw new TimeoutException("Could not acquire lock within timeout 
of " + unit.toMillis(timeout) + "ms");
+        }
+    }
+
+    @Override
+    /**
+     * Relase the lock if it has been acquired. Can be safely called multiple 
times.
+     * Only the first call will unlock.
+     */
+    public void close() throws Exception
+    {
+        if ( acquired.compareAndSet(true, false) )
+        {
+            releaseLock();
+        }
+    }
+
+    protected void releaseLock() throws Exception
+    {
+        lock.release();
+    }
+
+    protected boolean acquireLock(InterProcessLock lock, long timeout, 
TimeUnit unit) throws Exception
+    {
+        return lock.acquire(timeout, unit);
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/58a8818b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
----------------------------------------------------------------------
diff --git 
a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
 
b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
index a784e46..5a8168e 100644
--- 
a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
+++ 
b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutexBase.java
@@ -56,6 +56,28 @@ public abstract class TestInterProcessMutexBase extends 
BaseClassForTests
     protected abstract InterProcessLock makeLock(CuratorFramework client);
 
     @Test
+    public void testLocker() throws Exception
+    {
+        final Timing timing = new Timing();
+        final CuratorFramework client = 
CuratorFrameworkFactory.newClient(server.getConnectString(), timing.session(), 
timing.connection(), new ExponentialBackoffRetry(100, 3));
+        try
+        {
+            client.start();
+
+            InterProcessLock lock = makeLock(client);
+            try ( Locker locker = new Locker(lock, timing.milliseconds(), 
TimeUnit.MILLISECONDS) )
+            {
+                Assert.assertTrue(lock.isAcquiredInThisProcess());
+            }
+            Assert.assertFalse(lock.isAcquiredInThisProcess());
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(client);
+        }
+    }
+
+    @Test
     public void testWaitingProcessKilledServer() throws Exception
     {
         final Timing timing = new Timing();

Reply via email to