Search in sources :

Example 1 with JoinRequest

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();
    }
}
Also used : Configuration(io.atomix.protocols.raft.storage.system.Configuration) JoinRequest(io.atomix.protocols.raft.protocol.JoinRequest)

Aggregations

JoinRequest (io.atomix.protocols.raft.protocol.JoinRequest)1 Configuration (io.atomix.protocols.raft.storage.system.Configuration)1