You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@zookeeper.apache.org by Phil Carns <ca...@mcs.anl.gov> on 2012/09/15 03:23:11 UTC

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




RE: question about lock recipe and watchers

Posted by Robin Bate Boerop <ro...@userevents.com>.
Phil, thank you for the experience report!

Maybe the website should be updated with this suggestion...
________________________________________
From: Phil Carns [carns@mcs.anl.gov]
Sent: 17 September 2012 15:15
To: user@zookeeper.apache.org
Subject: Re: question about lock recipe and watchers

I tried out Michi's suggestion over the weekend and it seems to be
working great.  I just used a one-byte get() in place of the exists()
call recommended in the recipe.  I'm actually using wget(), to be
precise.  The wget() either returns an error immediately (because the
node has already been deleted) or else returns successfully and queues a
watcher that triggers when the node is deleted later.  There is no need
to set a value in the node.




Re: question about lock recipe and watchers

Posted by Phil Carns <ca...@mcs.anl.gov>.
On 09/17/2012 02:00 PM, Robin Bate Boerop wrote:
> I am about to implement a locking algorithm based on the below modification to the Zookeeper-website-recommended one. Does anyone else have experience with this?
>
> Thank you, Michi, for the suggestion below.
> ________________________________________
> From: mutsuzaki@gmail.com [mutsuzaki@gmail.com] on behalf of Michi Mutsuzaki [michi@cs.stanford.edu]
> Sent: 15 September 2012 02:32
> To: user@zookeeper.apache.org
> Subject: Re: question about lock recipe and watchers
>
> You could set the watch using get() instead of exists(). These watches
> get set if and only if the znode exists, and they get triggered when
> the znode goes away.
>

I tried out Michi's suggestion over the weekend and it seems to be 
working great.  I just used a one-byte get() in place of the exists() 
call recommended in the recipe.  I'm actually using wget(), to be 
precise.  The wget() either returns an error immediately (because the 
node has already been deleted) or else returns successfully and queues a 
watcher that triggers when the node is deleted later.  There is no need 
to set a value in the node.

-Phil




RE: question about lock recipe and watchers

Posted by Robin Bate Boerop <ro...@userevents.com>.
I am about to implement a locking algorithm based on the below modification to the Zookeeper-website-recommended one. Does anyone else have experience with this?

Thank you, Michi, for the suggestion below.
________________________________________
From: mutsuzaki@gmail.com [mutsuzaki@gmail.com] on behalf of Michi Mutsuzaki [michi@cs.stanford.edu]
Sent: 15 September 2012 02:32
To: user@zookeeper.apache.org
Subject: Re: question about lock recipe and watchers

You could set the watch using get() instead of exists(). These watches
get set if and only if the znode exists, and they get triggered when
the znode goes away.


Re: question about lock recipe and watchers

Posted by Phil Carns <ca...@mcs.anl.gov>.
On 09/15/2012 01:32 AM, Michi Mutsuzaki wrote:
> Hi Phil,
>
> On Fri, Sep 14, 2012 at 6:23 PM, Phil Carns <ca...@mcs.anl.gov> wrote:
>> 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?
> Right now the API doesn't provide a way to cancel watches, so the
> watches will remain active until the session is closed.
>
> https://issues.apache.org/jira/browse/ZOOKEEPER-442
>
> You could set the watch using get() instead of exists(). These watches
> get set if and only if the znode exists, and they get triggered when
> the znode goes away.
>
> --Michi

Hi Michi,

Thank you very much for the link and the get() suggestion.  I will try 
that out.

thanks,
-Phil

Re: question about lock recipe and watchers

Posted by Michi Mutsuzaki <mi...@cs.stanford.edu>.
Hi Phil,

On Fri, Sep 14, 2012 at 6:23 PM, Phil Carns <ca...@mcs.anl.gov> wrote:
> 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?

Right now the API doesn't provide a way to cancel watches, so the
watches will remain active until the session is closed.

https://issues.apache.org/jira/browse/ZOOKEEPER-442

You could set the watch using get() instead of exists(). These watches
get set if and only if the znode exists, and they get triggered when
the znode goes away.

--Michi