You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2014/05/23 17:49:47 UTC

git commit: DistributedAtomicValues are initially in a "null" state (like a database). In this state, there's no good way currently to initialize it so that operations such as compareAndSet() work well. So, add a new method, initialize(), that sets a val

Repository: curator
Updated Branches:
  refs/heads/CURATOR-108 [created] ecac48caa


DistributedAtomicValues are initially in a "null" state (like a database). In this state, there's no good way currently
to initialize it so that operations such as compareAndSet() work well. So, add a new method, initialize(), that sets
a value if the node doesn't exist.

This closes #8


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

Branch: refs/heads/CURATOR-108
Commit: ecac48caa9f68ce3f74cecf168dd05d7bbfa843e
Parents: 07db9f6
Author: randgalt <ra...@apache.org>
Authored: Fri May 23 10:46:17 2014 -0500
Committer: randgalt <ra...@apache.org>
Committed: Fri May 23 10:46:17 2014 -0500

----------------------------------------------------------------------
 .../atomic/DistributedAtomicInteger.java        |  6 ++++
 .../recipes/atomic/DistributedAtomicLong.java   |  6 ++++
 .../recipes/atomic/DistributedAtomicNumber.java | 30 +++++++++++++-------
 .../recipes/atomic/DistributedAtomicValue.java  | 23 +++++++++++++++
 .../atomic/TestDistributedAtomicLong.java       | 24 ++++++++++++++++
 5 files changed, 79 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/ecac48ca/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicInteger.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicInteger.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicInteger.java
index 1b526bb..8c167c9 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicInteger.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicInteger.java
@@ -90,6 +90,12 @@ public class DistributedAtomicInteger implements DistributedAtomicNumber<Integer
         return new AtomicInteger(value.trySet(valueToBytes(newValue)));
     }
 
+    @Override
+    public boolean initialize(Integer initialize) throws Exception
+    {
+        return value.initialize(valueToBytes(initialize));
+    }
+
     /**
      * Add 1 to the current value and return the new value information. Remember to always
      * check {@link AtomicValue#succeeded()}.

http://git-wip-us.apache.org/repos/asf/curator/blob/ecac48ca/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicLong.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicLong.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicLong.java
index b2451c8..9ee5b27 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicLong.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicLong.java
@@ -90,6 +90,12 @@ public class DistributedAtomicLong implements DistributedAtomicNumber<Long>
         return new AtomicLong(value.trySet(valueToBytes(newValue)));
     }
 
+    @Override
+    public boolean initialize(Long initialize) throws Exception
+    {
+        return value.initialize(valueToBytes(initialize));
+    }
+
     /**
      * Add 1 to the current value and return the new value information. Remember to always
      * check {@link AtomicValue#succeeded()}.

http://git-wip-us.apache.org/repos/asf/curator/blob/ecac48ca/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicNumber.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicNumber.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicNumber.java
index d479814..0039a13 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicNumber.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicNumber.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.recipes.atomic;
 
 public interface DistributedAtomicNumber<T>
@@ -27,20 +28,19 @@ public interface DistributedAtomicNumber<T>
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>     get() throws Exception;
+    public AtomicValue<T> get() throws Exception;
 
     /**
      * Atomically sets the value to the given updated value
      * if the current value {@code ==} the expected value.
      * Remember to always check {@link AtomicValue#succeeded()}.
      *
-     *
      * @param expectedValue the expected value
-     * @param newValue the new value for the counter
+     * @param newValue      the new value for the counter
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>    compareAndSet(T expectedValue, T newValue) throws Exception;
+    public AtomicValue<T> compareAndSet(T expectedValue, T newValue) throws Exception;
 
     /**
      * Attempt to atomically set the value to the given value. Remember to always
@@ -50,7 +50,17 @@ public interface DistributedAtomicNumber<T>
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>    trySet(T newValue) throws Exception;
+    public AtomicValue<T> trySet(T newValue) throws Exception;
+
+    /**
+     * Atomic values are initially set to the equivalent of <code>NULL</code> in a database.
+     * Use this method to initialize the value. The value will be set if and only iff the node does not exist.
+     *
+     * @param value the initial value to set
+     * @return true if the value was set, false if the node already existed
+     * @throws Exception ZooKeeper errors
+     */
+    public boolean initialize(T value) throws Exception;
 
     /**
      * Forcibly sets the value of the counter without any guarantees of atomicity.
@@ -58,7 +68,7 @@ public interface DistributedAtomicNumber<T>
      * @param newValue the new value
      * @throws Exception ZooKeeper errors
      */
-    public void              forceSet(T newValue) throws Exception;
+    public void forceSet(T newValue) throws Exception;
 
     /**
      * Add 1 to the current value and return the new value information. Remember to always
@@ -67,7 +77,7 @@ public interface DistributedAtomicNumber<T>
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>    increment() throws Exception;
+    public AtomicValue<T> increment() throws Exception;
 
     /**
      * Subtract 1 from the current value and return the new value information. Remember to always
@@ -76,7 +86,7 @@ public interface DistributedAtomicNumber<T>
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>    decrement() throws Exception;
+    public AtomicValue<T> decrement() throws Exception;
 
     /**
      * Add delta to the current value and return the new value information. Remember to always
@@ -86,7 +96,7 @@ public interface DistributedAtomicNumber<T>
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>    add(T delta) throws Exception;
+    public AtomicValue<T> add(T delta) throws Exception;
 
     /**
      * Subtract delta from the current value and return the new value information. Remember to always
@@ -96,5 +106,5 @@ public interface DistributedAtomicNumber<T>
      * @return value info
      * @throws Exception ZooKeeper errors
      */
-    public AtomicValue<T>    subtract(T delta) throws Exception;
+    public AtomicValue<T> subtract(T delta) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/ecac48ca/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicValue.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicValue.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicValue.java
index 910ece7..4ba3097 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicValue.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/atomic/DistributedAtomicValue.java
@@ -187,6 +187,29 @@ public class DistributedAtomicValue
         return result;
     }
 
+    /**
+     * Atomic values are initially set to the equivalent of <code>NULL</code> in a database.
+     * Use this method to initialize the value. The value will be set if and only iff the node does not exist.
+     *
+     * @param value the initial value to set
+     * @return true if the value was set, false if the node already existed
+     * @throws Exception ZooKeeper errors
+     */
+    public boolean initialize(byte[] value) throws Exception
+    {
+        ensurePath.ensure(client.getZookeeperClient());
+        try
+        {
+            client.create().forPath(path, value);
+        }
+        catch ( KeeperException.NodeExistsException ignore )
+        {
+            // ignore
+            return false;
+        }
+        return true;
+    }
+
     AtomicValue<byte[]>   trySet(MakeValue makeValue) throws Exception
     {
         MutableAtomicValue<byte[]>  result = new MutableAtomicValue<byte[]>(null, null, false);

http://git-wip-us.apache.org/repos/asf/curator/blob/ecac48ca/curator-recipes/src/test/java/org/apache/curator/framework/recipes/atomic/TestDistributedAtomicLong.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/atomic/TestDistributedAtomicLong.java b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/atomic/TestDistributedAtomicLong.java
index c2e0888..9d9fe03 100644
--- a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/atomic/TestDistributedAtomicLong.java
+++ b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/atomic/TestDistributedAtomicLong.java
@@ -26,6 +26,7 @@ import org.apache.curator.retry.RetryOneTime;
 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 import org.apache.commons.math.stat.descriptive.SynchronizedSummaryStatistics;
 import org.apache.curator.test.BaseClassForTests;
+import org.apache.curator.utils.CloseableUtils;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 import org.testng.collections.Lists;
@@ -75,6 +76,29 @@ public class TestDistributedAtomicLong extends BaseClassForTests
     }
 
     @Test
+    public void testCompareAndSetWithFreshInstance() throws Exception
+    {
+        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
+        try
+        {
+            client.start();
+            DistributedAtomicLong dal = new DistributedAtomicLong(client, "/counter", new RetryOneTime(1));
+            AtomicValue<Long> result = dal.compareAndSet(0L, 1L);
+            Assert.assertFalse(result.succeeded());
+
+            Assert.assertTrue(dal.initialize(0L));
+            result = dal.compareAndSet(0L, 1L);
+            Assert.assertTrue(result.succeeded());
+
+            Assert.assertFalse(dal.initialize(0L));
+        }
+        finally
+        {
+            CloseableUtils.closeQuietly(client);
+        }
+    }
+
+    @Test
     public void     testCompareAndSet() throws Exception
     {
         final CuratorFramework      client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));