Skip to content

Commit

Permalink
Add sync() function to enable consistent cross-client views
Browse files Browse the repository at this point in the history
Per the ZooKeeper documentation, "ZooKeeper by itself doesn't guarantee
that changes occur synchronously across all servers". In order to
ensure a write that was committed by another client is visible to
another client, it's necessary to have the sync() function from the
ZooKeeper API available.
  • Loading branch information
Ashley Winters committed Jan 15, 2015
1 parent d152827 commit bfd940c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,46 @@ zookeeper.setData('/test/demo', null, 2, function (error, stat) {

---

#### void sync(path, callback)

Synchronize the client's view of the given path with the ZooKeeper leader.

It is possible for a client to read a stale value for a given path, even
after another client has received confirmation that the new value has been
committed. Only a quorum of servers has to agree to a given change for a
write to be confirmed, and we might be connected to a server that hasn't
seen the update yet.

The callback function will be called once we confirm that any read of the
given path will return a value at least as new as when sync() was called.

**Arguments**

* path `String` - Path of the node.
* callback(error) `Function` - The callback function.

**Example**

```javascript
zookeeper.sync('/test/demo', function (error) {
if (error) {
console.log(error.stack);
return;
}

zookeeper.getData('/test/demo', function (error, data, stat) {
if (error) {
console.log(error.stack);
return;
}

console.log('Fresh value read.');
});
});
```

---

#### void getACL(path, callback)

Retrieve the list of [ACL](#acl) and stat of the node of the given path.
Expand Down
36 changes: 36 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,42 @@ Client.prototype.create = function (path, data, acls, mode, callback) {
);
};

/**
* Synchronize this client's view of the given path with the
* ZooKeeper leader. From the callback, any read will see
* data at least as new as when this function was called.
*
* @method sync
* @param path {String} The node path.
* @param callback {Function} The callback function.
*/
Client.prototype.sync = function (path, callback) {
Path.validate(path);

assert(typeof callback === 'function', 'callback must be a function.');

var self = this,
header = new jute.protocol.RequestHeader(),
payload = new jute.protocol.SyncRequest(),
request;

header.type = jute.OP_CODES.SYNC;

payload.path = path;

request = new jute.Request(header, payload);

attempt(
self,
function (attempts, next) {
self.connectionManager.queue(request, function (error, response) {
next(error);
});
},
callback
);
};

/**
* Delete a node with the given path. If version is not -1, the request will
* fail when the provided version does not match the server version.
Expand Down
3 changes: 3 additions & 0 deletions lib/ConnectionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ ConnectionManager.prototype.onSocketData = function (buffer) {
case jute.OP_CODES.GET_DATA:
responsePayload = new jute.protocol.GetDataResponse();
break;
case jute.OP_CODES.SYNC:
responsePayload = new jute.protocol.SyncResponse();
break;
case jute.OP_CODES.SET_ACL:
responsePayload = new jute.protocol.SetACLResponse();
break;
Expand Down
6 changes: 6 additions & 0 deletions lib/jute/specification.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@
{ "name" : "data", "type" : "buffer" },
{ "name" : "stat", "type" : "data.Stat" }
],
"SyncRequest" : [
{ "name" : "path", "type" : "ustring" }
],
"SyncResponse" : [
{ "name" : "path", "type" : "ustring" }
],
"GetACLRequest" : [
{ "name" : "path", "type" : "ustring" }
],
Expand Down

0 comments on commit bfd940c

Please sign in to comment.