use of com.twitter.common.zookeeper.Group.GroupChangeListener in project commons by twitter.
the class CandidateImpl method offerLeadership.
@Override
public Supplier<Boolean> offerLeadership(final Leader leader) throws JoinException, WatchException, InterruptedException {
final Membership membership = group.join(dataSupplier, new Command() {
@Override
public void execute() {
leader.onDefeated();
}
});
final AtomicBoolean elected = new AtomicBoolean(false);
final AtomicBoolean abdicated = new AtomicBoolean(false);
group.watch(new GroupChangeListener() {
@Override
public void onGroupChange(Iterable<String> memberIds) {
boolean noCandidates = Iterables.isEmpty(memberIds);
String memberId = membership.getMemberId();
if (noCandidates) {
LOG.warning("All candidates have temporarily left the group: " + group);
} else if (!Iterables.contains(memberIds, memberId)) {
LOG.severe(String.format("Current member ID %s is not a candidate for leader, current voting: %s", memberId, memberIds));
} else {
boolean electedLeader = memberId.equals(getLeader(memberIds));
boolean previouslyElected = elected.getAndSet(electedLeader);
if (!previouslyElected && electedLeader) {
LOG.info(String.format("Candidate %s is now leader of group: %s", membership.getMemberPath(), memberIds));
leader.onElected(new ExceptionalCommand<JoinException>() {
@Override
public void execute() throws JoinException {
membership.cancel();
abdicated.set(true);
}
});
} else if (!electedLeader) {
if (previouslyElected) {
leader.onDefeated();
}
LOG.info(String.format("Candidate %s waiting for the next leader election, current voting: %s", membership.getMemberPath(), memberIds));
}
}
}
});
return new Supplier<Boolean>() {
@Override
public Boolean get() {
return !abdicated.get() && elected.get();
}
};
}
Aggregations