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 <[email protected]> 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 <[email protected]> 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 >
