Home | About | Sematext search-lucene.com search-hadoop.com
 Search Hadoop and all its subprojects:

Switch to Threaded View
Zookeeper >> mail # user >> question about lock recipe and watchers


Copy link to this message
-
question about lock recipe and watchers
Hello,

I am trying to use the c interface to zookeeper to implement the lock
recipe as described here:

http://zookeeper.apache.org/doc/r3.1.2/recipes.html#sc_recipes_Locks

I have a question about the watcher described in step 4 and 5 of the
algorithm:

> 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
> step*2*.
>

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
watcher function:

>  * \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
> clients
>  * 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
sequence numbers.

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.

many thanks,
-Phil