I am trying to use the c interface to zookeeper to implement the lock
recipe as described here:
I have a question about the watcher described in step 4 and 5 of the
> 4. The client calls*exists( )*with the watch flag set on the path in
> the lock directory with the next lowest sequence number.
> 5. if*exists( )*returns false, go to step*2*. Otherwise, wait for a
> notification for the pathname from the previous step before going to
The zookeeper.h header file has the following comment about the exists()
function. Each variant of exists() has a similar comment, with the
wording slightly changed to reflect how each variant specifies its
> * \param watcher if non-null a watch will set on the specified znode
> on the server.
> * The watch will be set even if the node does not exist. This allows
> * to watch for nodes to appear.
The critical phrase here is that "the watch will be set even if the node
does not exist". This implies that even if exists() returns false in
step 5 of the recipe, a watcher will still have been queued to watch for
the node to reappear. That node will never reappear in this algorithm
because it was originally created using the (ZOO_SEQUENCE|ZOO_EPHEMERAL)
flags. Any new nodes that are created in that directory will have new
What happens to the watcher in this case? Is there any way to cancel a
watcher, or is there an alternative way to accomplish the intent of the
lock recipe algorithm without using an exists() watcher?
Just to clarify, this situation can be replicated in a scenario in which
two clients contend for a lock in the following order, if I understand
the semantics correctly:
client A: acquire lock by running steps 1,2,3 of recipe
client B: run steps 1 and 2 of the recipe
client A: release lock (by deleting node)
client B: run steps 3,4,5 of the recipe
Client B will ultimately (and correctly) acquire the lock when exists()
returns false and it loops back around to step 2, but it looks like the
exists() watcher will remain queued indefinitely.