Search in sources :

Example 1 with ReconfigureResponse

use of io.atomix.protocols.raft.protocol.ReconfigureResponse in project atomix by atomix.

the class LeaderRole method onReconfigure.

@Override
public CompletableFuture<ReconfigureResponse> onReconfigure(final ReconfigureRequest request) {
    raft.checkThread();
    logRequest(request);
    // See https://groups.google.com/forum/#!topic/raft-dev/t4xj6dJTP6E
    if (configuring() || initializing()) {
        return CompletableFuture.completedFuture(logResponse(ReconfigureResponse.builder().withStatus(RaftResponse.Status.ERROR).build()));
    }
    // If the member is not a known member of the cluster, fail the promotion.
    DefaultRaftMember existingMember = raft.getCluster().getMember(request.member().nodeId());
    if (existingMember == null) {
        return CompletableFuture.completedFuture(logResponse(ReconfigureResponse.builder().withStatus(RaftResponse.Status.ERROR).withError(RaftError.Type.UNKNOWN_SESSION).build()));
    }
    // the leader, fail the request to ensure servers can't reconfigure an old configuration.
    if (request.index() > 0 && request.index() < raft.getCluster().getConfiguration().index() || request.term() != raft.getCluster().getConfiguration().term()) {
        return CompletableFuture.completedFuture(logResponse(ReconfigureResponse.builder().withStatus(RaftResponse.Status.ERROR).withError(RaftError.Type.CONFIGURATION_ERROR).build()));
    }
    // If the member type has not changed, complete the configuration change successfully.
    if (existingMember.getType() == request.member().getType()) {
        Configuration configuration = raft.getCluster().getConfiguration();
        return CompletableFuture.completedFuture(logResponse(ReconfigureResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(configuration.index()).withTerm(raft.getCluster().getConfiguration().term()).withTime(raft.getCluster().getConfiguration().time()).withMembers(configuration.members()).build()));
    }
    // Update the member type.
    existingMember.update(request.member().getType(), Instant.now());
    Collection<RaftMember> members = raft.getCluster().getMembers();
    CompletableFuture<ReconfigureResponse> future = new CompletableFuture<>();
    configure(members).whenComplete((index, error) -> {
        if (error == null) {
            future.complete(logResponse(ReconfigureResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(index).withTerm(raft.getCluster().getConfiguration().term()).withTime(raft.getCluster().getConfiguration().time()).withMembers(members).build()));
        } else {
            future.complete(logResponse(ReconfigureResponse.builder().withStatus(RaftResponse.Status.ERROR).withError(RaftError.Type.PROTOCOL_ERROR).build()));
        }
    });
    return future;
}
Also used : RaftMember(io.atomix.protocols.raft.cluster.RaftMember) DefaultRaftMember(io.atomix.protocols.raft.cluster.impl.DefaultRaftMember) CompletableFuture(java.util.concurrent.CompletableFuture) DefaultRaftMember(io.atomix.protocols.raft.cluster.impl.DefaultRaftMember) Configuration(io.atomix.protocols.raft.storage.system.Configuration) ReconfigureResponse(io.atomix.protocols.raft.protocol.ReconfigureResponse)

Aggregations

RaftMember (io.atomix.protocols.raft.cluster.RaftMember)1 DefaultRaftMember (io.atomix.protocols.raft.cluster.impl.DefaultRaftMember)1 ReconfigureResponse (io.atomix.protocols.raft.protocol.ReconfigureResponse)1 Configuration (io.atomix.protocols.raft.storage.system.Configuration)1 CompletableFuture (java.util.concurrent.CompletableFuture)1