private void checkLeadership(List<String> children) throws Exception { final String localOurPath = ourPath.get(); List<String> sortedChildren = LockInternals.getSortedChildren(LOCK_NAME, sorter, children); int ourIndex = (localOurPath != null) ? sortedChildren.indexOf(ZKPaths.getNodeFromPath(localOurPath)) : -1; if (ourIndex < 0) { log.error("Can't find our node. Resetting. Index: " + ourIndex); reset(); } else if (ourIndex == 0) { setLeadership(true); } else { 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) && (localOurPath != null)) { try { getChildren(); } catch (Exception ex) { log.error("An error occurred checking the leadership.", ex); } } } }; BackgroundCallback callback = new BackgroundCallback() { @Override public void processResult(CuratorFramework client, CuratorEvent event) throws Exception { if (event.getResultCode() == KeeperException.Code.NONODE.intValue()) { // previous node is gone - reset reset(); } } }; client .checkExists() .usingWatcher(watcher) .inBackground(callback) .forPath(ZKPaths.makePath(latchPath, watchPath)); } }
private void checkForLeadership() throws Exception { List<String> sortedChildren = LockInternals.getSortedChildren(client, latchPath, LOCK_NAME, sorter); if (sortedChildren.size() == 0) { throw new Exception("no children - unexpected state"); } int ourIndex = sortedChildren.indexOf(ZKPaths.getNodeFromPath(ourPath)); if (ourIndex == 0) { setLeadership(true); } else { final String ourPathWhenWatched = ourPath; // protected against a lost/suspended connection and an old watcher - I'm not // sure if this is possible but it can't hurt String watchPath = sortedChildren.get(ourIndex - 1); Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { if ((event.getType() == Event.EventType.NodeDeleted) && (ourPath != null) && ourPath.equals(ourPathWhenWatched)) { try { checkForLeadership(); } catch (Exception ex) { log.error("An error ocurred checking the leadership.", ex); } } } }; if (client.checkExists().usingWatcher(watcher).forPath(ZKPaths.makePath(latchPath, watchPath)) == null) { // the previous Participant may be down, so we need to reevaluate the list // to get the actual previous Participant or get the leadership checkForLeadership(); } } }
/** * Return the id for the current leader. If for some reason there is no current leader, a dummy * participant is returned. * * <p><B>NOTE</B> - this method polls the ZK server. Therefore it can possibly return a value that * does not match {@link #hasLeadership()} as hasLeadership uses a local field of the class. * * @return leader * @throws Exception ZK errors, interruptions, etc. */ public Participant getLeader() throws Exception { Collection<String> participantNodes = LockInternals.getParticipantNodes(client, latchPath, LOCK_NAME, sorter); return LeaderSelector.getLeader(client, participantNodes); }