CURATOR-710: Fix leaking watch in EnsembleTracker#508
Conversation
a6319f0 to
b74abb0
Compare
CURATOR-667(apache#474) fixes asynchronous event path for `getConfig` to "/zookeeper/config" by using `CuratorFramework::usingNamespace(null)` to fetch data. It causes watcher not registering to possible `WatcherRemovalManager`, so leaking in `WatcherRemoveCuratorFramework::removeWatchers`.
b74abb0 to
cd03c72
Compare
| Watching setWatcherRemovalManager(WatcherRemovalManager watcherRemovalManager) { | ||
| this.watcherRemovalManager = watcherRemovalManager; | ||
| return this; | ||
| } |
There was a problem hiding this comment.
It seems the watcherRemovalManager already set in the constructor by this.watcherRemovalManager = client.getWatcherRemovalManager();?
There was a problem hiding this comment.
Or otherwise we can merge this setter into the constructor as a parameter.
| if (client.getWatcherRemovalManager() != null) { | ||
| client.getWatcherRemovalManager().add(namespaceWatcher); | ||
| } | ||
| if (doCommit && namespaceWatcher != null && watcherRemovalManager != null) { |
There was a problem hiding this comment.
Can you elaborate a bit when watcherRemovalManager can be different from client.getWatcherRemovalManager().
There was a problem hiding this comment.
I agree with the question: we can save some memory by not having the field. The performance impact is negligible
There was a problem hiding this comment.
- Given a fresh new
CuratorFrameworkImpl, sayframework0. - Let's assume
framework1 = framework0.newWatcherRemoveCuratorFramework().framework1.getWatcherRemovalManagerwill be theWatcherRemovalManager. - Let's assume
framework2 = frame1.usingNamespace(null).framework2will lossWatcherRemovalManagerfrom above. framework1.removeWatcherswill not drop watchers fromnew Watching(framework2, ...).
Step.2 is what exactly EnsembleTracker does.
Step.3 is what exactly GetConfigBuilderImpl(CURATOR-667(#474)) does currently.
Step.4 is where this bug emerges.
I have pushed a fixup commit 6b78a3b with comments to doc this.
There was a problem hiding this comment.
I get the point now. Let me check the code to see if we can have other less stateful/mutable solution 😆
There was a problem hiding this comment.
Briefly, the root cause is WatcherRemovalFacade::usingNamespace drop the removalManager. Then by convey the manager in the method, things should work well.
There was a problem hiding this comment.
I saw the patch. I think it is what I am trying to express in #517 (comment).
whether CuratorFramework::usingNamespace should inherit functionalities of this ?
It changes the behavior of CuratorFramework::usingNamespace, but I am ok.
There was a problem hiding this comment.
Yeah .. I suppose it's more like a bug to fix, since CURATOR-710 indicates that it's a bug anyway.
To provide an exit gate, perhaps we can add a new method to return a "basic CuratorFramework" to drop the removalManager explicitly, just like usingNamespace(null) to drop the namespace in facade. But we can leave it to #517.
|
Is this PR ready for review now? @kezhuw |
|
@tisonkun It is ready. I have closed and reopened to revive ci. |
Signed-off-by: tison <[email protected]>
avoid mutable state
CURATOR-667(#474) fixes asynchronous event path for
getConfigto"/zookeeper/config" by using
CuratorFramework::usingNamespace(null)tofetch data.
It causes watcher not registering to possible
WatcherRemovalManager,so leaking in
WatcherRemoveCuratorFramework::removeWatchers.