Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
3.6.3, 3.6.4
Description
I used to think watchers of different modes are orthogonal. I found there are not, when I wrote tests for unfinished rust client. And I wrote test cases in java and confirmed.
I copied test case here for evaluation. You also clone from my fork.
// zookeeper-server/src/test/java/org/apache/zookeeper/test/PersistentRecursiveWatcherTest.java
@Test
public void testPathOverlapWithStandardWatcher() throws Exception {
try (ZooKeeper zk = createClient(new CountdownWatcher(), hostPort)) {
CountDownLatch nodeCreated = new CountDownLatch(1);
zk.addWatch("/a", persistentWatcher, PERSISTENT_RECURSIVE);
zk.exists("/a", event -> nodeCreated.countDown());
zk.create("/a", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create("/a/b", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.delete("/a/b", -1);
zk.delete("/a", -1);
assertEvent(events, Watcher.Event.EventType.NodeCreated, "/a");
assertEvent(events, Watcher.Event.EventType.NodeCreated, "/a/b");
assertEvent(events, Watcher.Event.EventType.NodeDeleted, "/a/b");
assertEvent(events, Watcher.Event.EventType.NodeDeleted, "/a");
assertTrue(nodeCreated.await(5, TimeUnit.SECONDS));
}
}
@Test
public void testPathOverlapWithPersistentWatcher() throws Exception {
try (ZooKeeper zk = createClient(new CountdownWatcher(), hostPort)) {
zk.addWatch("/a", persistentWatcher, PERSISTENT_RECURSIVE);
zk.addWatch("/a/b", event -> {}, PERSISTENT);
zk.create("/a", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create("/a/b", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create("/a/b/c", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.delete("/a/b/c", -1);
zk.delete("/a/b", -1);
zk.delete("/a", -1);
assertEvent(events, Watcher.Event.EventType.NodeCreated, "/a");
assertEvent(events, Watcher.Event.EventType.NodeCreated, "/a/b");
assertEvent(events, Watcher.Event.EventType.NodeCreated, "/a/b/c");
assertEvent(events, Watcher.Event.EventType.NodeDeleted, "/a/b/c");
assertEvent(events, Watcher.Event.EventType.NodeDeleted, "/a/b");
assertEvent(events, Watcher.Event.EventType.NodeDeleted, "/a");
}
}
I skimmed the code and found two possible causes:
- ZKWatchManager.materialize materializes all persistent watchers(include recursive ones) for NodeChildrenChanged event.
- WatcherModeManager trackes only one watcher mode.
Attachments
Issue Links
- is related to
-
ZOOKEEPER-4472 Support persistent watchers removing individually
-
- Closed
-
- links to