use of io.atomix.protocols.raft.protocol.JoinRequest in project atomix by atomix.
the class RaftClusterContext method join.
/**
* Recursively attempts to join the cluster.
*/
private void join(Iterator<RaftMemberContext> iterator) {
if (iterator.hasNext()) {
cancelJoinTimer();
joinTimeout = raft.getThreadContext().schedule(raft.getElectionTimeout().multipliedBy(2), () -> {
join(iterator);
});
RaftMemberContext member = iterator.next();
log.debug("Attempting to join via {}", member.getMember().nodeId());
JoinRequest request = JoinRequest.builder().withMember(new DefaultRaftMember(getMember().nodeId(), getMember().getType(), getMember().getLastUpdated())).build();
raft.getProtocol().join(member.getMember().nodeId(), request).whenCompleteAsync((response, error) -> {
// Cancel the join timer.
cancelJoinTimer();
if (error == null) {
if (response.status() == RaftResponse.Status.OK) {
log.info("Successfully joined via {}", member.getMember().nodeId());
Configuration configuration = new Configuration(response.index(), response.term(), response.timestamp(), response.members());
// Configure the cluster with the join response.
// Commit the configuration as we know it was committed via the successful join response.
configure(configuration).commit();
// If the local member is not present in the configuration, fail the future.
if (!members.contains(this.member)) {
joinFuture.completeExceptionally(new IllegalStateException("not a member of the cluster"));
} else if (joinFuture != null) {
joinFuture.complete(null);
}
} else if (response.error() == null || response.error().type() == RaftError.Type.CONFIGURATION_ERROR) {
// If the response error is null, that indicates that no error occurred but the leader was
// in a state that was incapable of handling the join request. Attempt to join the leader
// again after an election timeout.
log.debug("Failed to join {}", member.getMember().nodeId());
resetJoinTimer();
} else {
// If the response error was non-null, attempt to join via the next server in the members list.
log.debug("Failed to join {}", member.getMember().nodeId());
join(iterator);
}
} else {
log.debug("Failed to join {}", member.getMember().nodeId());
join(iterator);
}
}, raft.getThreadContext());
} else // If join attempts remain, schedule another attempt after two election timeouts. This allows enough time
// for servers to potentially timeout and elect a leader.
{
log.debug("Failed to join cluster, retrying...");
resetJoinTimer();
}
}
Aggregations