diff options
author | randgalt <jordan@jordanzimmerman.com> | 2019-11-08 17:30:25 +0100 |
---|---|---|
committer | Enrico Olivelli <enrico.olivelli@diennea.com> | 2019-11-08 17:30:25 +0100 |
commit | 553639378d5cf86c2488afff4586e5e4cce38061 (patch) | |
tree | 746efbdec30726503f94aa4c1ad5dabab0130b01 /zookeeper-jute | |
parent | e41cac853de416026e0c2011e0429e858e5823b8 (diff) | |
download | zookeeper-553639378d5cf86c2488afff4586e5e4cce38061.tar.gz |
ZOOKEEPER-1416 - Persistent, recursive watchers
### Background
Note: this is a port of https://github.com/apache/zookeeper/pull/136
Implementation for a persistent, recursive watch addition for ZK. These watches are set via a new method, addPersistentWatch() and are removed via the existing watcher removal methods. Persistent, recursive watches have these characteristics: a) Once set, they do not auto-remove when triggered; b) they trigger for all event types (child, data, etc.) on the node they are registered for and any child znode recursively; c) they are efficiently implemented by using the existing watch internals. A new class PathIterator walks up the path parent-by-parent when checking if a watcher applies.
### Implementation Details
- A new enum manages the different "modes" for watchers: `WatcherMode`.
- For traditional, "standard" watchers, the code path is almost exactly the same. There is very little overhead other than a bit of extra checks in `WatchManager`
- Given how this is implemented it was difficult to add support when `WatchManagerOptimized` is used. I'm open to adding it for that version but it will take work. We should consider not supporting persistent/recursive watchers when WatchManagerOptimized is used. I notice that `WatchManagerOptimized` is not even mentioned in the docs.
- The mode for a given watcher/path pair is held in a map inside of `WatcherModeManager`. The absence of an entry means Standard. This way, there's no overhead for old, standard watchers.
- `PathParentIterator` is the "meat" of the implementation. Rather than set watchers on every ZNode implied by a recursive watcher. WatchManager passes any paths it processes through PathParentIterator which iterates up each parent znode looking for watchers.
- The remainder of the changes are scaffolding to match how other watchers are used as well as Jute/API changes to set persistent/recursive watchers
### Testing
The tests were written years ago. I think they're comprehensive but reviewers should pay attention to anything that was missed. There is much ZooKeeper knowledge that's only in the heads of ZK committers.
- `PersistentWatcherTest` - tests persistent, non-recursive watchers
- `PersistentRecursiveWatcherTest` - tests persistent, recursive watchers
- `PathParentIteratorTest`- exercises edges of PathParentIterator
Author: randgalt <jordan@jordanzimmerman.com>
Reviewers: Enrico Olivelli <eolivelli@apache,org>, Norbert Kalmar <nkalmar@apache.org>, Andor Molnár <andor@apache.org>, Justin Mao Ling <maoling199210191@sina.com>
Closes #1106 from Randgalt/ZOOKEEPER-1416
Diffstat (limited to 'zookeeper-jute')
-rw-r--r-- | zookeeper-jute/src/main/resources/zookeeper.jute | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/zookeeper-jute/src/main/resources/zookeeper.jute b/zookeeper-jute/src/main/resources/zookeeper.jute index 8310664a6..6d5536575 100644 --- a/zookeeper-jute/src/main/resources/zookeeper.jute +++ b/zookeeper-jute/src/main/resources/zookeeper.jute @@ -73,6 +73,14 @@ module org.apache.zookeeper.proto { vector<ustring>existWatches; vector<ustring>childWatches; } + class SetWatches2 { + long relativeZxid; + vector<ustring>dataWatches; + vector<ustring>existWatches; + vector<ustring>childWatches; + vector<ustring>persistentWatches; + vector<ustring>persistentRecursiveWatches; + } class RequestHeader { int xid; int type; @@ -180,6 +188,10 @@ module org.apache.zookeeper.proto { class SetACLResponse { org.apache.zookeeper.data.Stat stat; } + class AddWatchRequest { + ustring path; + int mode; + } class WatcherEvent { int type; // event type int state; // state of the Keeper client runtime |