-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CURATOR-710: Fix leaking watch in EnsembleTracker #508
base: master
Are you sure you want to change the base?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the watcherRemovalManager
already set in the constructor by this.watcherRemovalManager = client.getWatcherRemovalManager();
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate a bit when watcherRemovalManager
can be different from client.getWatcherRemovalManager()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Given a fresh new
CuratorFrameworkImpl
, sayframework0
. - Let's assume
framework1 = framework0.newWatcherRemoveCuratorFramework()
.framework1.getWatcherRemovalManager
will be theWatcherRemovalManager
. - Let's assume
framework2 = frame1.usingNamespace(null)
.framework2
will lossWatcherRemovalManager
from above. framework1.removeWatchers
will not drop watchers fromnew Watching(framework2, ...)
.
Step.2 is what exactly EnsembleTracker
does.
curator/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java
Lines 87 to 90 in 6a27ff0
EnsembleTracker(CuratorFramework client, EnsembleProvider ensembleProvider) { | |
this.client = client.newWatcherRemoveCuratorFramework(); | |
this.ensembleProvider = ensembleProvider; | |
} |
Step.3 is what exactly GetConfigBuilderImpl
(CURATOR-667(#474)) does currently.
curator/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
Lines 41 to 45 in 6a27ff0
public GetConfigBuilderImpl(CuratorFrameworkImpl client) { | |
this.client = (CuratorFrameworkImpl) client.usingNamespace(null); | |
backgrounding = new Backgrounding(); | |
watching = new Watching(this.client); | |
} |
Step.4 is where this bug emerges.
curator/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java
Lines 99 to 104 in 6a27ff0
public void close() { | |
if (state.compareAndSet(State.STARTED, State.CLOSED)) { | |
client.removeWatchers(); | |
client.getConnectionStateListenable().removeListener(connectionStateListener); | |
} | |
} |
I have pushed a fixup commit 6b78a3b with comments to doc this.
CURATOR-667(#474) fixes asynchronous event path for
getConfig
to"/zookeeper/config" by using
CuratorFramework::usingNamespace(null)
tofetch data.
It causes watcher not registering to possible
WatcherRemovalManager
,so leaking in
WatcherRemoveCuratorFramework::removeWatchers
.