CURATOR-84 More flexibility for InterProcessMutex extensions
Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/6ecfd791 Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/6ecfd791 Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/6ecfd791 Branch: refs/heads/master Commit: 6ecfd791b47410b0d6d1ddae92eb0cffe406d85b Parents: d2c37d0 Author: Karthik Kumar <[email protected]> Authored: Sat Aug 16 13:11:54 2014 -0400 Committer: Karthik Kumar <[email protected]> Committed: Wed Aug 20 09:17:08 2014 -0400 ---------------------------------------------------------------------- .../recipes/locks/InterProcessMutex.java | 17 +++++++- .../framework/recipes/locks/LockInternals.java | 9 +--- .../recipes/locks/LockInternalsDriver.java | 4 +- .../recipes/locks/PredicateResults.java | 8 ++-- .../locks/StandardLockInternalsDriver.java | 17 ++++++++ .../recipes/locks/TestInterProcessMutex.java | 43 ++++++++++++++++++++ 6 files changed, 84 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/6ecfd791/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/InterProcessMutex.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/InterProcessMutex.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/InterProcessMutex.java index ffdeb70..02a3d1f 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/InterProcessMutex.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/InterProcessMutex.java @@ -61,7 +61,17 @@ public class InterProcessMutex implements InterProcessLock, Revocable<InterProce */ public InterProcessMutex(CuratorFramework client, String path) { - this(client, path, LOCK_NAME, 1, new StandardLockInternalsDriver()); + this(client, path, new StandardLockInternalsDriver()); + } + + /** + * @param client client + * @param path the path to lock + * @param driver lock driver + */ + public InterProcessMutex(CuratorFramework client, String path, LockInternalsDriver driver) + { + this(client, path, LOCK_NAME, 1, driver); } /** @@ -201,6 +211,11 @@ public class InterProcessMutex implements InterProcessLock, Revocable<InterProce return null; } + protected String getLockPath() { + LockData lockData = threadData.get(Thread.currentThread()); + return lockData != null ? lockData.lockPath : null; + } + private boolean internalLock(long time, TimeUnit unit) throws Exception { /* http://git-wip-us.apache.org/repos/asf/curator/blob/6ecfd791/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternals.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternals.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternals.java index 706b242..74022e0 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternals.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternals.java @@ -214,14 +214,7 @@ public class LockInternals try { - if ( localLockNodeBytes != null ) - { - ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, localLockNodeBytes); - } - else - { - ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path); - } + ourPath = driver.createsTheLock(client, path, localLockNodeBytes); hasTheLock = internalLockLoop(startMillis, millisToWait, ourPath); } catch ( KeeperException.NoNodeException e ) http://git-wip-us.apache.org/repos/asf/curator/blob/6ecfd791/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternalsDriver.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternalsDriver.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternalsDriver.java index 1570eed..69e3ce6 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternalsDriver.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/LockInternalsDriver.java @@ -21,7 +21,9 @@ package org.apache.curator.framework.recipes.locks; import org.apache.curator.framework.CuratorFramework; import java.util.List; -interface LockInternalsDriver extends LockInternalsSorter +public interface LockInternalsDriver extends LockInternalsSorter { public PredicateResults getsTheLock(CuratorFramework client, List<String> children, String sequenceNodeName, int maxLeases) throws Exception; + + public String createsTheLock(CuratorFramework client, String path, byte[] lockNodeBytes) throws Exception; } http://git-wip-us.apache.org/repos/asf/curator/blob/6ecfd791/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/PredicateResults.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/PredicateResults.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/PredicateResults.java index 0f098ea..b032d98 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/PredicateResults.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/PredicateResults.java @@ -18,23 +18,23 @@ */ package org.apache.curator.framework.recipes.locks; -class PredicateResults +public class PredicateResults { private final boolean getsTheLock; private final String pathToWatch; - PredicateResults(String pathToWatch, boolean getsTheLock) + public PredicateResults(String pathToWatch, boolean getsTheLock) { this.pathToWatch = pathToWatch; this.getsTheLock = getsTheLock; } - String getPathToWatch() + public String getPathToWatch() { return pathToWatch; } - boolean getsTheLock() + public boolean getsTheLock() { return getsTheLock; } http://git-wip-us.apache.org/repos/asf/curator/blob/6ecfd791/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/StandardLockInternalsDriver.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/StandardLockInternalsDriver.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/StandardLockInternalsDriver.java index 25f07b8..0c9b6de 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/StandardLockInternalsDriver.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/locks/StandardLockInternalsDriver.java @@ -19,6 +19,7 @@ package org.apache.curator.framework.recipes.locks; import org.apache.curator.framework.CuratorFramework; +import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +42,22 @@ public class StandardLockInternalsDriver implements LockInternalsDriver } @Override + public String createsTheLock(CuratorFramework client, String path, byte[] lockNodeBytes) throws Exception + { + String ourPath; + if ( lockNodeBytes != null ) + { + ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, lockNodeBytes); + } + else + { + ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path); + } + return ourPath; + } + + + @Override public String fixForSorting(String str, String lockName) { return standardFixForSorting(str, lockName); http://git-wip-us.apache.org/repos/asf/curator/blob/6ecfd791/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutex.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutex.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutex.java index bbc3466..c116a50 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutex.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/locks/TestInterProcessMutex.java @@ -21,6 +21,8 @@ package org.apache.curator.framework.recipes.locks; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.RetryOneTime; +import org.apache.curator.test.KillSession; +import org.apache.zookeeper.CreateMode; import org.testng.Assert; import org.testng.annotations.Test; import java.util.Collection; @@ -107,4 +109,45 @@ public class TestInterProcessMutex extends TestInterProcessMutexBase client.close(); } } + + @Test + public void testPersistentLock() throws Exception { + final CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)); + client.start(); + + try { + final InterProcessMutex lock = new InterProcessMutex(client, LOCK_PATH, new StandardLockInternalsDriver() { + @Override + public String createsTheLock(CuratorFramework client, String path, byte[] lockNodeBytes) throws Exception { + String ourPath; + if ( lockNodeBytes != null ) + { + ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.PERSISTENT).forPath(path, lockNodeBytes); + } + else + { + ourPath = client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.PERSISTENT).forPath(path); + } + return ourPath; + } + }); + + // Get a persistent lock + lock.acquire(10, TimeUnit.SECONDS); + Assert.assertTrue(lock.isAcquiredInThisProcess()); + + // Kill the session, check that lock node still exists + KillSession.kill(client.getZookeeperClient().getZooKeeper(), server.getConnectString()); + Assert.assertNotNull(client.checkExists().forPath(LOCK_PATH)); + + // Release the lock and verify that the actual lock node created no longer exists + String actualLockPath = lock.getLockPath(); + lock.release(); + Assert.assertNull(client.checkExists().forPath(actualLockPath)); + } + finally { + client.close(); + } + + } }
