You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2013/06/06 00:33:38 UTC

git commit: Fixed Zookeeper to recursively create parent paths as necessary.

Updated Branches:
  refs/heads/master 85b1f4af1 -> 56eb02422


Fixed Zookeeper to recursively create parent paths as necessary.

Review: https://reviews.apache.org/r/11366


Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/56eb0242
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/56eb0242
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/56eb0242

Branch: refs/heads/master
Commit: 56eb024221b396381bb5a4038b6c47f27088abf0
Parents: 85b1f4a
Author: Vinod Kone <vi...@twitter.com>
Authored: Thu May 23 23:26:31 2013 -0700
Committer: Vinod Kone <vi...@twitter.com>
Committed: Wed Jun 5 15:31:15 2013 -0700

----------------------------------------------------------------------
 src/tests/zookeeper_tests.cpp |   12 ++++----
 src/zookeeper/zookeeper.cpp   |   51 ++++++++++++++++++-----------------
 src/zookeeper/zookeeper.hpp   |    2 +-
 3 files changed, 33 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/56eb0242/src/tests/zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_tests.cpp b/src/tests/zookeeper_tests.cpp
index 77a5ab2..16c5fb7 100644
--- a/src/tests/zookeeper_tests.cpp
+++ b/src/tests/zookeeper_tests.cpp
@@ -82,12 +82,12 @@ TEST_F(ZooKeeperTest, Create)
   ZooKeeper nonOwnerZk(server->connectString(), NO_TIMEOUT, &watcher);
   watcher.awaitSessionEvent(ZOO_CONNECTED_STATE);
   nonOwnerZk.authenticate("digest", "non-owner:non-owner");
-  EXPECT_EQ(ZNOAUTH, nonOwnerZk.create("/foo/bar/baz",
-                                       "",
-                                       zookeeper::EVERYONE_READ_CREATOR_ALL,
-                                       0,
-                                       NULL,
-                                       true));
+  EXPECT_EQ(ZNODEEXISTS, nonOwnerZk.create("/foo/bar/baz",
+                                           "",
+                                           zookeeper::EVERYONE_READ_CREATOR_ALL,
+                                           0,
+                                           NULL,
+                                           true));
   EXPECT_EQ(ZOK, nonOwnerZk.create("/foo/bar/baz/bam",
                                    "44",
                                    zookeeper::EVERYONE_READ_CREATOR_ALL,

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/56eb0242/src/zookeeper/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/zookeeper.cpp b/src/zookeeper/zookeeper.cpp
index 267c38a..de33003 100644
--- a/src/zookeeper/zookeeper.cpp
+++ b/src/zookeeper/zookeeper.cpp
@@ -517,41 +517,42 @@ int ZooKeeper::authenticate(const string& scheme, const string& credentials)
 }
 
 
-int ZooKeeper::create(const string& path, const string& data,
-                      const ACL_vector& acl, int flags, string* result,
-                      bool recursive)
+int ZooKeeper::create(
+    const string& path,
+    const string& data,
+    const ACL_vector& acl,
+    int flags,
+    string* result,
+    bool recursive)
 {
   if (!recursive) {
     return impl->create(path, data, acl, flags, result).get();
   }
 
-  // Do "recursive" create, i.e., ensure intermediate znodes exist.
-  string prefix = "/";
-  int code = ZOK;
-  foreach (const string& token, strings::tokenize(path, "/")) {
-    prefix = path::join(prefix, token);
-
-    // Make sure we include 'flags' and 'data' for the final znode.
-    if (prefix == path || (prefix + "/") == path) {
-      code = impl->create(path, data, acl, flags, result).get();
-    } else {
-      code = impl->create(prefix, "", acl, 0, result).get();
-    }
+  // First check if the path exists.
+  int code = impl->exists(path, false, NULL).get();
+  if (code == ZOK) {
+    return ZNODEEXISTS;
+  }
 
-    // We fail all non-OK return codes except for:
-    // ZNODEEXISTS says the node in the znode path we are trying to
-    //   create already exists - this is what we wanted, so we
-    //   continue.
-    // ZNOAUTH says we can't write the node, but it doesn't tell us
-    //   whether the node already exists. We take the optimistic
-    //   approach and assume the node's parent doesn't allow us to
-    //   write an already existing node (but it exists).
-    if (code != ZOK && code != ZNODEEXISTS && code != ZNOAUTH) {
+  // Now recursively create the parent path.
+  // NOTE: We don't use 'dirname()' to get the parent path here
+  // because, it doesn't return the expected path when a path ends
+  // with "/". For example, to create path "/a/b/", we want to
+  // recursively create "/a/b", instead of just creating "/a".
+  const string& parent = path.substr(0, path.find_last_of("/"));
+  if (!parent.empty()) {
+    code = create(parent, "", acl, 0, result, true);
+    if (code != ZOK && code != ZNODEEXISTS) {
       return code;
     }
   }
 
-  return code;
+  // Finally create the path.
+  // TODO(vinod): Delete any intermediate nodes created if this fails.
+  // This requires synchronization because the deletion might affect
+  // other callers (different threads/processes) acting on this path.
+  return impl->create(path, data, acl, flags, result).get();
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/56eb0242/src/zookeeper/zookeeper.hpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/zookeeper.hpp b/src/zookeeper/zookeeper.hpp
index 99e689e..7243543 100644
--- a/src/zookeeper/zookeeper.hpp
+++ b/src/zookeeper/zookeeper.hpp
@@ -184,7 +184,7 @@ public:
 	     const ACL_vector &acl,
 	     int flags,
 	     std::string *result,
-             bool recursive = false);
+	     bool recursive = false);
 
   /**
    * \brief delete a node in zookeeper synchronously.