in ratis-server/src/main/java/org/apache/ratis/server/impl/TransferLeadership.java [201:239]
private Result sendStartLeaderElection(FollowerInfo follower) {
final TermIndex lastEntry = server.getState().getLastEntry();
final Result result = isFollowerUpToDate(follower, lastEntry);
if (result != Result.SUCCESS) {
return result;
}
final RaftPeerId transferee = follower.getId();
LOG.info("{}: sendStartLeaderElection to follower {}, lastEntry={}",
server.getMemberId(), transferee, lastEntry);
final RaftProtos.StartLeaderElectionRequestProto r = ServerProtoUtils.toStartLeaderElectionRequestProto(
server.getMemberId(), transferee, lastEntry);
final CompletableFuture<RaftProtos.StartLeaderElectionReplyProto> f = CompletableFuture.supplyAsync(() -> {
server.getLeaderElectionMetrics().onTransferLeadership();
try {
return server.getServerRpc().startLeaderElection(r);
} catch (IOException e) {
throw new CompletionException("Failed to sendStartLeaderElection to follower " + transferee, e);
}
}, server.getServerExecutor()).whenComplete((reply, exception) -> {
if (reply != null) {
LOG.info("{}: Received startLeaderElection reply from {}: success? {}",
server.getMemberId(), transferee, reply.getServerReply().getSuccess());
} else if (exception != null) {
LOG.warn(server.getMemberId() + ": Failed to startLeaderElection for " + transferee, exception);
}
});
if (f.isCompletedExceptionally()) { // already failed
try {
f.join();
} catch (Throwable t) {
return new Result(t);
}
}
return Result.SUCCESS;
}