private synchronized CompletableFuture changeToFollower()

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;
  }