curator-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From randg...@apache.org
Subject [1/3] curator git commit: Because start() creates the node async, if close is called immediately, it might occur before the node creation. Handle this edge case by having the background response delete (async) the node if the instance has been closed
Date Tue, 02 Feb 2016 21:48:46 GMT
Repository: curator
Updated Branches:
  refs/heads/CURATOR-3.0 1f866815a -> 4e4072b08


Because start() creates the node async, if close is called immediately, it might occur before
the node creation. Handle this edge case by having the background response delete (async)
the node if the instance has been closed


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

Branch: refs/heads/CURATOR-3.0
Commit: e5afda580e2c7540f5095e1894c6866ce4ace8db
Parents: 4b59a5b
Author: randgalt <randgalt@apache.org>
Authored: Tue Feb 2 13:26:13 2016 -0500
Committer: randgalt <randgalt@apache.org>
Committed: Tue Feb 2 13:26:13 2016 -0500

----------------------------------------------------------------------
 .../framework/recipes/nodes/PersistentNode.java | 99 ++++++++++++++------
 .../recipes/nodes/TestPersistentNode.java       | 46 +++++++++
 2 files changed, 114 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/e5afda58/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
index 0d7ab9d..c472fdd 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/nodes/PersistentNode.java
@@ -159,41 +159,13 @@ public class PersistentNode implements Closeable
             @Override
             public void processResult(CuratorFramework client, CuratorEvent event) throws
Exception
             {
-                String path = null;
-                boolean nodeExists = false;
-                if ( event.getResultCode() == KeeperException.Code.NODEEXISTS.intValue()
)
+                if ( state.get() == State.STARTED )
                 {
-                    path = event.getPath();
-                    nodeExists = true;
-                }
-                else if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
-                {
-                    path = event.getName();
-                }
-                else if ( event.getResultCode() == KeeperException.Code.NOAUTH.intValue()
)
-                {
-                    log.warn("Client does not have authorisation to write node at path {}",
event.getPath());
-                    authFailure.set(true);
-                    return;
-                }
-                if ( path != null )
-                {
-                    authFailure.set(false);
-                    nodePath.set(path);
-                    watchNode();
-
-                    if ( nodeExists )
-                    {
-                        client.setData().inBackground(setDataCallback).forPath(getActualPath(),
getData());
-                    }
-                    else
-                    {
-                        initialisationComplete();
-                    }
+                    processBackgroundCallback(event);
                 }
                 else
                 {
-                    createNode();
+                    processBackgroundCallbackClosedState(event);
                 }
             }
         };
@@ -202,6 +174,71 @@ public class PersistentNode implements Closeable
         this.data.set(Arrays.copyOf(data, data.length));
     }
 
+    private void processBackgroundCallbackClosedState(CuratorEvent event)
+    {
+        String path = null;
+        if ( event.getResultCode() == KeeperException.Code.NODEEXISTS.intValue() )
+        {
+            path = event.getPath();
+        }
+        else if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
+        {
+            path = event.getName();
+        }
+
+        if ( path != null )
+        {
+            try
+            {
+                client.delete().guaranteed().inBackground().forPath(path);
+            }
+            catch ( Exception e )
+            {
+                log.error("Could not delete node after close", e);
+            }
+        }
+    }
+
+    private void processBackgroundCallback(CuratorEvent event) throws Exception
+    {
+        String path = null;
+        boolean nodeExists = false;
+        if ( event.getResultCode() == KeeperException.Code.NODEEXISTS.intValue() )
+        {
+            path = event.getPath();
+            nodeExists = true;
+        }
+        else if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
+        {
+            path = event.getName();
+        }
+        else if ( event.getResultCode() == KeeperException.Code.NOAUTH.intValue() )
+        {
+            log.warn("Client does not have authorisation to write node at path {}", event.getPath());
+            authFailure.set(true);
+            return;
+        }
+        if ( path != null )
+        {
+            authFailure.set(false);
+            nodePath.set(path);
+            watchNode();
+
+            if ( nodeExists )
+            {
+                client.setData().inBackground(setDataCallback).forPath(getActualPath(), getData());
+            }
+            else
+            {
+                initialisationComplete();
+            }
+        }
+        else
+        {
+            createNode();
+        }
+    }
+
     private void initialisationComplete()
     {
         CountDownLatch localLatch = initialCreateLatch.getAndSet(null);

http://git-wip-us.apache.org/repos/asf/curator/blob/e5afda58/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentNode.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentNode.java
b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentNode.java
index c006dd7..386a0fe 100644
--- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentNode.java
+++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/nodes/TestPersistentNode.java
@@ -59,4 +59,50 @@ public class TestPersistentNode extends BaseClassForTests
             CloseableUtils.closeQuietly(client);
         }
     }
+
+    @Test
+    public void testQuickClose() throws Exception
+    {
+        Timing timing = new Timing();
+        PersistentNode pen = null;
+        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(),
timing.session(), timing.connection(), new RetryOneTime(1));
+        try
+        {
+            client.start();
+            pen = new PersistentNode(client, CreateMode.PERSISTENT, false, "/test/one/two",
new byte[0]);
+            pen.start();
+            pen.close();
+            timing.sleepABit();
+            Assert.assertNull(client.checkExists().forPath("/test/one/two"));
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(pen);
+            CloseableUtils.closeQuietly(client);
+        }
+    }
+
+    @Test
+    public void testQuickCloseNodeExists() throws Exception
+    {
+        Timing timing = new Timing();
+        PersistentNode pen = null;
+        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(),
timing.session(), timing.connection(), new RetryOneTime(1));
+        try
+        {
+            client.start();
+            client.create().creatingParentsIfNeeded().forPath("/test/one/two");
+
+            pen = new PersistentNode(client, CreateMode.PERSISTENT, false, "/test/one/two",
new byte[0]);
+            pen.start();
+            pen.close();
+            timing.sleepABit();
+            Assert.assertNull(client.checkExists().forPath("/test/one/two"));
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(pen);
+            CloseableUtils.closeQuietly(client);
+        }
+    }
 }


Mime
View raw message