in curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java [539:602]
private void checkLeadership(List<String> children) throws Exception {
if (debugCheckLeaderShipLatch != null) {
debugCheckLeaderShipLatch.await();
}
final String localOurPath = ourPath.get();
List<String> sortedChildren = LockInternals.getSortedChildren(LOCK_NAME, sorter, children);
int ourIndex = (localOurPath != null) ? sortedChildren.indexOf(ZKPaths.getNodeFromPath(localOurPath)) : -1;
log.debug("[id={}] checkLeadership with ourPath: {}, children: {}", id, localOurPath, sortedChildren);
if (ourIndex < 0) {
log.error("[id={}] failed to find our node; resetting (index: {})", id, ourIndex);
reset();
return;
}
if (ourIndex == 0) {
client.getData()
.inBackground((client, event) -> {
final long ephemeralOwner =
event.getStat() != null ? event.getStat().getEphemeralOwner() : -1;
final long thisSessionId =
client.getZookeeperClient().getZooKeeper().getSessionId();
if (ephemeralOwner != thisSessionId) {
// this node is gone - reset
reset();
} else {
lastPathIsLeader.set(localOurPath);
setLeadership(true);
}
})
.forPath(localOurPath);
return;
}
setLeadership(false);
String watchPath = sortedChildren.get(ourIndex - 1);
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent event) {
if (state.get() == State.STARTED && event.getType() == Event.EventType.NodeDeleted) {
try {
getChildren();
} catch (Exception ex) {
ThreadUtils.checkInterrupted(ex);
log.error("[id={}] failed to check the leadership.", id, ex);
}
}
}
};
BackgroundCallback callback = new BackgroundCallback() {
@Override
public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
if (event.getResultCode() == KeeperException.Code.NONODE.intValue()) {
log.debug("[id={}] previous node is gone; retry getChildren", id);
getChildren();
}
}
};
// use getData() instead of exists() to avoid leaving unneeded watchers which is a type of resource leak
client.getData().usingWatcher(watcher).inBackground(callback).forPath(ZKPaths.makePath(latchPath, watchPath));
}