You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@zookeeper.apache.org by Jonathan Smith <jo...@mail.com> on 2013/01/23 13:12:12 UTC
ZooKeeper Watch triggered multiple times for the same notification – contrary to docs
I have a node that has a children watch on it. Whenever the
NodeChildrenChanged event is received I obtain the children using
getChildren passing in my watcher then iterate through all children
and perform a getData() also passing in my watcher so that I am also
notified of any changes to the data on the children.
E.g.
public void check() {
List<String> children =
zkclient.getChildren().usingWatcher(myWatcher).forPath(PATH);
for (String name : children) {
byte[] data =
zkclient.getData().usingWatcher(myWatcher).forPath(getPathFromName(name));
// do stuff
}
}
CuratorWatcher myWatcher = new CuratorWatcher() {
@Override
public void process(WatchedEvent event) throws Exception {
logger.info("received watch event: " + event);
if (event.getType().equals(EventType.NodeChildrenChanged)
|| event.getType().equals(EventType.NodeDataChanged)) {
check();
}
}
};
This means that whenever a child is added/removed, another getData
call will be made with the watcher.
After reading the ZooKeeper documentation I thought it would be fine
to keep setting the watcher since I should only be given the same
watch notification once:
“A watch object, or function/context pair, will only be triggered once
for a given notification. For example, if the same watch object is
registered for an exists and a getData call for the same file and that
file is then deleted, the watch object would only be invoked once with
the deletion notification for the file.”
http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#ch_zkWatches
However I have observed that when a node is deleted I am receiving the
NodeDeleted watch event multiple times:
received watch event: WatchedEvent state:SyncConnected
type:NodeDeleted path:/a/b
received watch event: WatchedEvent state:SyncConnected
type:NodeDeleted path:/a/b
received watch event: WatchedEvent state:SyncConnected
type:NodeDeleted path:/a/b
...
This means the watch is being triggered multiple times unnecessarily.
I am using the Curator framework however I believe this just passes
the watches through and therefore this is a ZooKeeper issue. I am
using zookeeper server version 3.4.5, zookeeper client 3.3.1,
curator-framework 1.2.2.
Is the documentation wrong / is this a bug or have I misunderstood?
Many thanks,
Jon
Re: ZooKeeper Watch triggered multiple times for the same notification – contrary to docs
Posted by Jonathan Smith <jo...@mail.com>.
Thanks, it looks like this was an issue with Curator that has now been fixed:
https://github.com/Netflix/curator/commit/27550024ad3dcda7c2494f633d0b60cdc2f43ad2
+1.3.2 - xxxxxxxxxxxxxxxx
+========================
+* MAJOR BUG FIX - Issue 232: ZooKeeper guarantees that "A watch
object, or function/context pair, will only
+be triggered once for a given notification." Curator was breaking
this guarantee by internally creating a
+new Watcher object each time one was needed. This is now fixed and
ZooKeeper's guarantee is restored. Big
+thanks to user barkbay for his persistence and help on this.
+
On 24 January 2013 00:35, Jordan Zimmerman <jo...@jordanzimmerman.com> wrote:
> I agree that the docs are misleading. The watcher triggers once for the event registered. However, watchers can (and will) receive multiple connection-type events (EventType.None). That said, I think Curator recipes should be resilient to this. Please post an issue at the Curator github site: https://github.com/Netflix/curator/issues
>
> -JZ
>
> On Jan 23, 2013, at 4:12 AM, Jonathan Smith <jo...@mail.com> wrote:
>
>> I have a node that has a children watch on it. Whenever the
>> NodeChildrenChanged event is received I obtain the children using
>> getChildren passing in my watcher then iterate through all children
>> and perform a getData() also passing in my watcher so that I am also
>> notified of any changes to the data on the children.
>>
>> E.g.
>>
>> public void check() {
>> List<String> children =
>> zkclient.getChildren().usingWatcher(myWatcher).forPath(PATH);
>> for (String name : children) {
>> byte[] data =
>> zkclient.getData().usingWatcher(myWatcher).forPath(getPathFromName(name));
>> // do stuff
>> }
>> }
>>
>>
>> CuratorWatcher myWatcher = new CuratorWatcher() {
>> @Override
>> public void process(WatchedEvent event) throws Exception {
>> logger.info("received watch event: " + event);
>> if (event.getType().equals(EventType.NodeChildrenChanged)
>> || event.getType().equals(EventType.NodeDataChanged)) {
>> check();
>> }
>> }
>> };
>>
>> This means that whenever a child is added/removed, another getData
>> call will be made with the watcher.
>>
>> After reading the ZooKeeper documentation I thought it would be fine
>> to keep setting the watcher since I should only be given the same
>> watch notification once:
>>
>> “A watch object, or function/context pair, will only be triggered once
>> for a given notification. For example, if the same watch object is
>> registered for an exists and a getData call for the same file and that
>> file is then deleted, the watch object would only be invoked once with
>> the deletion notification for the file.”
>>
>> http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#ch_zkWatches
>>
>> However I have observed that when a node is deleted I am receiving the
>> NodeDeleted watch event multiple times:
>>
>> received watch event: WatchedEvent state:SyncConnected
>> type:NodeDeleted path:/a/b
>> received watch event: WatchedEvent state:SyncConnected
>> type:NodeDeleted path:/a/b
>> received watch event: WatchedEvent state:SyncConnected
>> type:NodeDeleted path:/a/b
>> ...
>>
>> This means the watch is being triggered multiple times unnecessarily.
>>
>> I am using the Curator framework however I believe this just passes
>> the watches through and therefore this is a ZooKeeper issue. I am
>> using zookeeper server version 3.4.5, zookeeper client 3.3.1,
>> curator-framework 1.2.2.
>>
>> Is the documentation wrong / is this a bug or have I misunderstood?
>>
>> Many thanks,
>> Jon
>
Re: ZooKeeper Watch triggered multiple times for the same notification – contrary to docs
Posted by Jordan Zimmerman <jo...@jordanzimmerman.com>.
I agree that the docs are misleading. The watcher triggers once for the event registered. However, watchers can (and will) receive multiple connection-type events (EventType.None). That said, I think Curator recipes should be resilient to this. Please post an issue at the Curator github site: https://github.com/Netflix/curator/issues
-JZ
On Jan 23, 2013, at 4:12 AM, Jonathan Smith <jo...@mail.com> wrote:
> I have a node that has a children watch on it. Whenever the
> NodeChildrenChanged event is received I obtain the children using
> getChildren passing in my watcher then iterate through all children
> and perform a getData() also passing in my watcher so that I am also
> notified of any changes to the data on the children.
>
> E.g.
>
> public void check() {
> List<String> children =
> zkclient.getChildren().usingWatcher(myWatcher).forPath(PATH);
> for (String name : children) {
> byte[] data =
> zkclient.getData().usingWatcher(myWatcher).forPath(getPathFromName(name));
> // do stuff
> }
> }
>
>
> CuratorWatcher myWatcher = new CuratorWatcher() {
> @Override
> public void process(WatchedEvent event) throws Exception {
> logger.info("received watch event: " + event);
> if (event.getType().equals(EventType.NodeChildrenChanged)
> || event.getType().equals(EventType.NodeDataChanged)) {
> check();
> }
> }
> };
>
> This means that whenever a child is added/removed, another getData
> call will be made with the watcher.
>
> After reading the ZooKeeper documentation I thought it would be fine
> to keep setting the watcher since I should only be given the same
> watch notification once:
>
> “A watch object, or function/context pair, will only be triggered once
> for a given notification. For example, if the same watch object is
> registered for an exists and a getData call for the same file and that
> file is then deleted, the watch object would only be invoked once with
> the deletion notification for the file.”
>
> http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#ch_zkWatches
>
> However I have observed that when a node is deleted I am receiving the
> NodeDeleted watch event multiple times:
>
> received watch event: WatchedEvent state:SyncConnected
> type:NodeDeleted path:/a/b
> received watch event: WatchedEvent state:SyncConnected
> type:NodeDeleted path:/a/b
> received watch event: WatchedEvent state:SyncConnected
> type:NodeDeleted path:/a/b
> ...
>
> This means the watch is being triggered multiple times unnecessarily.
>
> I am using the Curator framework however I believe this just passes
> the watches through and therefore this is a ZooKeeper issue. I am
> using zookeeper server version 3.4.5, zookeeper client 3.3.1,
> curator-framework 1.2.2.
>
> Is the documentation wrong / is this a bug or have I misunderstood?
>
> Many thanks,
> Jon