Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ public static EventType fromInt(int intValue) {
enum WatcherType {
Children(1),
Data(2),
Persistent(4),
PersistentRecursive(5),
Any(3);

// Integer representation of value
Expand All @@ -212,7 +214,10 @@ public static WatcherType fromInt(int intValue) {
return WatcherType.Data;
case 3:
return WatcherType.Any;

case 4:
return Persistent;
case 5:
return PersistentRecursive;
default:
throw new RuntimeException("Invalid integer value for conversion to WatcherType");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ public Map<Watcher.Event.EventType, Set<Watcher>> removeWatcher(
}
break;
}
case Persistent: {
synchronized (persistentWatches) {
removedWatcher = removeWatches(persistentWatches, watcher, clientPath, local, rc, persistentWatchersToRem);
}
break;
}
case PersistentRecursive: {
synchronized (persistentRecursiveWatches) {
removedWatcher = removeWatches(persistentRecursiveWatches, watcher, clientPath, local, rc, persistentWatchersToRem);
}
break;
}
case Any: {
synchronized (childWatches) {
removedWatcher = removeWatches(childWatches, watcher, clientPath, local, rc, childWatchersToRem);
Expand Down Expand Up @@ -225,18 +237,6 @@ void containsWatcher(String path, Watcher watcher, Watcher.WatcherType watcherTy
synchronized (childWatches) {
containsWatcher = contains(path, watcher, childWatches);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree on this direction that it delivers more reasonable behaviors. But it can somehow still a user-facing manner changes. Maybe we need a release note to describe it.

I'll check the final logic tomorrow and give a review result :D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are my findings:

  • containsWatcher is package private and used solely by ZKWatchManager::removeWatcher.
  • removeWatcher enforces more stringent NoWatcherException check than containsWatcher.

So, we are in lucking path that partially removing WatcherType::Data from AddWatchMode::Persistent is an error even it is permitted by server side(a.k.a rc is 0) and containsWatcher.

I pushed a test commit for this. I also pushed tests in kezhuw@8c35fce before ZOOKEEPER-4466. All these tests result in NOWATCHER when removing WatcherType::Data from AddWatchMode::Persistent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have add "Release Note" to ZOOKEEPER-4466, ZOOKEEPER-4471 and ZOOKEEPER-4472.

Is that sufficient for us ? @eolivelli @tisonkun @anmolnar

synchronized (persistentWatches) {
boolean contains_temp = contains(path, watcher,
persistentWatches);
containsWatcher |= contains_temp;
}

synchronized (persistentRecursiveWatches) {
boolean contains_temp = contains(path, watcher,
persistentRecursiveWatches);
containsWatcher |= contains_temp;
}
break;
}
case Data: {
Expand All @@ -248,17 +248,17 @@ void containsWatcher(String path, Watcher watcher, Watcher.WatcherType watcherTy
boolean contains_temp = contains(path, watcher, existWatches);
containsWatcher |= contains_temp;
}

break;
}
case Persistent: {
synchronized (persistentWatches) {
boolean contains_temp = contains(path, watcher,
persistentWatches);
containsWatcher |= contains_temp;
containsWatcher |= contains(path, watcher, persistentWatches);
}

break;
}
case PersistentRecursive: {
synchronized (persistentRecursiveWatches) {
boolean contains_temp = contains(path, watcher,
persistentRecursiveWatches);
containsWatcher |= contains_temp;
containsWatcher |= contains(path, watcher, persistentRecursiveWatches);
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class RemoveWatchesCommand extends CliCommand {
static {
options.addOption("c", false, "child watcher type");
options.addOption("d", false, "data watcher type");
options.addOption("p", false, "persistent watcher type");
options.addOption("r", false, "persistent recursive watcher type");
options.addOption("a", false, "any watcher type");
options.addOption("l", false, "remove locally when there is no server connection");
}
Expand Down Expand Up @@ -70,6 +72,10 @@ public boolean exec() throws CliWrapperException, MalformedPathException {
wtype = WatcherType.Children;
} else if (cl.hasOption("d")) {
wtype = WatcherType.Data;
} else if (cl.hasOption("p")) {
wtype = WatcherType.Persistent;
} else if (cl.hasOption("r")) {
wtype = WatcherType.PersistentRecursive;
} else if (cl.hasOption("a")) {
wtype = WatcherType.Any;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1563,11 +1563,16 @@ public boolean containsWatcher(String path, WatcherType type, Watcher watcher) {
case Data:
containsWatcher = this.dataWatches.containsWatcher(path, watcher, WatcherMode.STANDARD);
break;
case Persistent:
containsWatcher = this.dataWatches.containsWatcher(path, watcher, WatcherMode.PERSISTENT);
break;
case PersistentRecursive:
containsWatcher = this.dataWatches.containsWatcher(path, watcher, WatcherMode.PERSISTENT_RECURSIVE);
break;
case Any:
if (this.childWatches.containsWatcher(path, watcher, null)) {
containsWatcher = true;
}
if (this.dataWatches.containsWatcher(path, watcher, null)) {
} else if (this.dataWatches.containsWatcher(path, watcher, null)) {
containsWatcher = true;
}
break;
Expand All @@ -1584,6 +1589,17 @@ public boolean removeWatch(String path, WatcherType type, Watcher watcher) {
case Data:
removed = this.dataWatches.removeWatcher(path, watcher, WatcherMode.STANDARD);
break;
case Persistent:
if (this.childWatches.removeWatcher(path, watcher, WatcherMode.PERSISTENT)) {
removed = true;
}
if (this.dataWatches.removeWatcher(path, watcher, WatcherMode.PERSISTENT)) {
removed = true;
}
break;
case PersistentRecursive:
removed = this.dataWatches.removeWatcher(path, watcher, WatcherMode.PERSISTENT_RECURSIVE);
break;
case Any:
if (this.childWatches.removeWatcher(path, watcher, null)) {
removed = true;
Expand Down
Loading