jdoig
jdoig

Reputation: 1492

Is it possible to watch for events on all descendant nodes in ZooKeeper?

When using ZooKeeper is it possible to watch for all events on descendant znodes?

for example if I have:

     (/)
     /  \
   (/a)  (/b)
   /       \
(/c)       (/d)

Is there a way to watch the root for changes to /a, /b, /c and /d ?

Upvotes: 9

Views: 5561

Answers (4)

rocky chi
rocky chi

Reputation: 31

It's possible by using Persistent, Recursive Watches if you upgrade your zookeeper version to 3.6.0. see Persistent, Recursive Watches and Zookeeper Watchers

Also there is Curator Persistent Recursive Watcher support too.

Upvotes: 1

Muhammad Gelbana
Muhammad Gelbana

Reputation: 4000

Use the TreeCache instead of the PathCache

Upvotes: 1

sbridges
sbridges

Reputation: 25150

There is no ZooKeeper api to do that, you will have to write your own.

If you are using Curator, you can use PathCache which maintains watches on a node, and that node's children. You can write some code to create more PathCaches as you discover descendants of the root you are watching.

If you are going to roll your own version of this, it is actually quite tricky to get right. This blog describes some of the problems.

Upvotes: 8

Sswater Shi
Sswater Shi

Reputation: 189

I know this is an old question. I just post here for reference for some other person like me.

I'm looking for this too. Following the tip of @sbridges, I think I could do like this.

PathChildrenCache pathcache = new PathChildrenCache(client, "/some/path", true);

PathChildrenCacheListener listner1 = new PathChildrenCacheListener() {
    Map<String, PathChildrenCache> listener2s = new HashMap<String, PathChildrenCache>();
    @Override
    public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
        String path = event.getData().getPath();

        if(event.getType() == Type.CHILD_ADDED) {
            PathChildrenCache cache2 = new PathChildrenCache(client, path, true);
            cache2.getListenable().addListener(this);
            cache2.start();
            listener2s.put(path, cache2);
        }
        else if(event.getType() == Type.CHILD_REMOVED) {
            PathChildrenCache cache2 = listener2s.remove(path);
            if(cache2 != null) cache2.close();
        }

        System.out.println("" + Thread.currentThread().getId() + "\t" + event);
    }
};
pathcache.getListenable().addListener(listner1);

If someone find something wrong, please tell me.

Upvotes: 1

Related Questions