CURATOR-18 There is a race between creating a node and deleting it. If LeaderLatch is closed while the node creation is in flight, the created node won't get deleted, and latch node will stay in ZK forever.
Project: http://git-wip-us.apache.org/repos/asf/incubator-curator/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-curator/commit/38f28b5c Tree: http://git-wip-us.apache.org/repos/asf/incubator-curator/tree/38f28b5c Diff: http://git-wip-us.apache.org/repos/asf/incubator-curator/diff/38f28b5c Branch: refs/heads/master Commit: 38f28b5c951fd341c9845a3538d52bb3508536e2 Parents: 3d6181c Author: randgalt <randg...@apache.org> Authored: Thu May 9 17:00:43 2013 -0700 Committer: randgalt <randg...@apache.org> Committed: Thu May 9 17:00:43 2013 -0700 ---------------------------------------------------------------------- .../framework/recipes/leader/LeaderLatch.java | 9 ++++- .../framework/recipes/leader/TestLeaderLatch.java | 30 +++++++++++++++ 2 files changed, 38 insertions(+), 1 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/38f28b5c/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java index 508ca7c..dc37386 100644 --- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java +++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java @@ -396,7 +396,14 @@ public class LeaderLatch implements Closeable if ( event.getResultCode() == KeeperException.Code.OK.intValue() ) { setNode(event.getName()); - getChildren(); + if ( state.get() == State.CLOSED ) + { + setNode(null); + } + else + { + getChildren(); + } } else { http://git-wip-us.apache.org/repos/asf/incubator-curator/blob/38f28b5c/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java ---------------------------------------------------------------------- diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java index 58a61ee..4741e76 100644 --- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java +++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/TestLeaderLatch.java @@ -80,6 +80,36 @@ public class TestLeaderLatch extends BaseClassForTests } @Test + public void testCreateDeleteRace() throws Exception + { + Timing timing = new Timing(); + CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), timing.session(), timing.connection(), new RetryOneTime(1)); + try + { + client.start(); + LeaderLatch latch = new LeaderLatch(client, PATH_NAME); + + latch.debugResetWaitLatch = new CountDownLatch(1); + + latch.start(); + latch.close(); + + timing.sleepABit(); + + latch.debugResetWaitLatch.countDown(); + + timing.sleepABit(); + + Assert.assertEquals(client.getChildren().forPath(PATH_NAME).size(), 0); + + } + finally + { + Closeables.closeQuietly(client); + } + } + + @Test public void testLostConnection() throws Exception { final int PARTICIPANT_QTY = 10;