in ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java [589:623]
private synchronized CompletableFuture<Void> changeToFollower(
long newTerm, boolean force, boolean allowListener, Object reason, AtomicBoolean metadataUpdated) {
final RaftPeerRole old = role.getCurrentRole();
if (old == RaftPeerRole.LISTENER && !allowListener) {
throw new IllegalStateException("Unexpected role " + old);
}
CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
if ((old != RaftPeerRole.FOLLOWER || force) && old != RaftPeerRole.LISTENER) {
setRole(RaftPeerRole.FOLLOWER, reason);
if (old == RaftPeerRole.LEADER) {
future = role.shutdownLeaderState(false)
.exceptionally(e -> {
if (e != null) {
if (!getInfo().isAlive()) {
LOG.info("Since server is not alive {}, safely ignore {}", this, e.toString());
return null;
}
}
throw new CompletionException("Failed to shutdownLeaderState: " + this, e);
});
state.setLeader(null, reason);
} else if (old == RaftPeerRole.CANDIDATE) {
future = role.shutdownLeaderElection();
} else if (old == RaftPeerRole.FOLLOWER) {
future = role.shutdownFollowerState();
}
metadataUpdated.set(state.updateCurrentTerm(newTerm));
role.startFollowerState(this, reason);
setFirstElection(reason);
} else {
metadataUpdated.set(state.updateCurrentTerm(newTerm));
}
return future;
}