Search in sources :

Example 6 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class NodeImpl method handleVoteTimeout.

private void handleVoteTimeout() {
    this.writeLock.lock();
    if (this.state != State.STATE_CANDIDATE) {
        this.writeLock.unlock();
        return;
    }
    // This is needed for the node, which won preVote in a previous iteration, but leader wasn't elected.
    if (this.prevVoteCtx.isGranted())
        adjustElectionTimeout();
    if (this.raftOptions.isStepDownWhenVoteTimedout()) {
        LOG.warn("Candidate node {} term {} steps down when election reaching vote timeout: fail to get quorum vote-granted.", this.nodeId, this.currTerm);
        stepDown(this.currTerm, false, new Status(RaftError.ETIMEDOUT, "Vote timeout: fail to get quorum vote-granted."));
        // unlock in preVote
        preVote();
    } else {
        LOG.debug("Node {} term {} retry to vote self.", getNodeId(), this.currTerm);
        // unlock in electSelf
        electSelf();
    }
}
Also used : Status(org.apache.ignite.raft.jraft.Status)

Example 7 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class NodeImpl method onError.

public void onError(final RaftException error) {
    LOG.warn("Node {} got error: {}.", getNodeId(), (Object) error);
    if (this.fsmCaller != null) {
        // onError of fsmCaller is guaranteed to be executed once.
        this.fsmCaller.onError(error);
    }
    if (this.readOnlyService != null) {
        this.readOnlyService.setError(error);
    }
    this.writeLock.lock();
    try {
        // If it is follower, also step down to call on_stop_following.
        if (this.state.compareTo(State.STATE_FOLLOWER) <= 0) {
            stepDown(this.currTerm, this.state == State.STATE_LEADER, new Status(RaftError.EBADNODE, "Raft node(leader or candidate) is in error."));
        }
        if (this.state.compareTo(State.STATE_ERROR) < 0) {
            this.state = State.STATE_ERROR;
        }
    } finally {
        this.writeLock.unlock();
    }
}
Also used : Status(org.apache.ignite.raft.jraft.Status)

Example 8 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class NodeImpl method transferLeadershipTo.

@Override
public Status transferLeadershipTo(final PeerId peer) {
    Requires.requireNonNull(peer, "Null peer");
    this.writeLock.lock();
    try {
        if (this.state != State.STATE_LEADER) {
            LOG.warn("Node {} can't transfer leadership to peer {} as it is in state {}.", getNodeId(), peer, this.state);
            return new Status(this.state == State.STATE_TRANSFERRING ? RaftError.EBUSY : RaftError.EPERM, "Not a leader");
        }
        if (this.confCtx.isBusy()) {
            // It's very messy to deal with the case when the |peer| received
            // TimeoutNowRequest and increase the term while somehow another leader
            // which was not replicated with the newest configuration has been
            // elected. If no add_peer with this very |peer| is to be invoked ever
            // after nor this peer is to be killed, this peer will spin in the voting
            // procedure and make the each new leader stepped down when the peer
            // reached vote timeout and it starts to vote (because it will increase
            // the term of the group)
            // To make things simple, refuse the operation and force users to
            // invoke transfer_leadership_to after configuration changing is
            // completed so that the peer's configuration is up-to-date when it
            // receives the TimeOutNowRequest.
            LOG.warn("Node {} refused to transfer leadership to peer {} when the leader is changing the configuration.", getNodeId(), peer);
            return new Status(RaftError.EBUSY, "Changing the configuration");
        }
        PeerId peerId = peer.copy();
        // last_log_id will be selected.
        if (peerId.equals(PeerId.ANY_PEER)) {
            LOG.info("Node {} starts to transfer leadership to any peer.", getNodeId());
            if ((peerId = this.replicatorGroup.findTheNextCandidate(this.conf)) == null) {
                return new Status(-1, "Candidate not found for any peer");
            }
        }
        if (peerId.equals(this.serverId)) {
            LOG.info("Node {} transferred leadership to self.", this.serverId);
            return Status.OK();
        }
        if (!this.conf.contains(peerId)) {
            LOG.info("Node {} refused to transfer leadership to peer {} as it is not in {}.", getNodeId(), peer, this.conf);
            return new Status(RaftError.EINVAL, "Not in current configuration");
        }
        final long lastLogIndex = this.logManager.getLastLogIndex();
        if (!this.replicatorGroup.transferLeadershipTo(peerId, lastLogIndex)) {
            LOG.warn("No such peer {}.", peer);
            return new Status(RaftError.EINVAL, "No such peer %s", peer);
        }
        this.state = State.STATE_TRANSFERRING;
        final Status status = new Status(RaftError.ETRANSFERLEADERSHIP, "Raft leader is transferring leadership to %s", peerId);
        onLeaderStop(status);
        LOG.info("Node {} starts to transfer leadership to peer {}.", getNodeId(), peer);
        final StopTransferArg stopArg = new StopTransferArg(this, this.currTerm, peerId);
        this.stopTransferArg = stopArg;
        this.transferTimer = this.getOptions().getScheduler().schedule(() -> onTransferTimeout(stopArg), this.options.getElectionTimeoutMs(), TimeUnit.MILLISECONDS);
    } finally {
        this.writeLock.unlock();
    }
    return Status.OK();
}
Also used : Status(org.apache.ignite.raft.jraft.Status) PeerId(org.apache.ignite.raft.jraft.entity.PeerId)

Example 9 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class CliServiceImpl method removePeer.

@Override
public Status removePeer(final String groupId, final Configuration conf, final PeerId peer) {
    Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
    Requires.requireNonNull(conf, "Null configuration");
    Requires.requireNonNull(peer, "Null peer");
    Requires.requireTrue(!peer.isEmpty(), "Removing peer is blank");
    final PeerId leaderId = new PeerId();
    final Status st = getLeader(groupId, conf, leaderId);
    if (!st.isOk()) {
        return st;
    }
    if (!this.cliClientService.connect(leaderId.getEndpoint())) {
        return new Status(-1, "Fail to init channel to leader %s", leaderId);
    }
    RemovePeerRequest req = cliOptions.getRaftMessagesFactory().removePeerRequest().groupId(groupId).leaderId(leaderId.toString()).peerId(peer.toString()).build();
    try {
        final Message result = this.cliClientService.removePeer(leaderId.getEndpoint(), req, null).get();
        if (result instanceof RemovePeerResponse) {
            final RemovePeerResponse resp = (RemovePeerResponse) result;
            final Configuration oldConf = new Configuration();
            for (final String peerIdStr : resp.oldPeersList()) {
                final PeerId oldPeer = new PeerId();
                oldPeer.parse(peerIdStr);
                oldConf.addPeer(oldPeer);
            }
            final Configuration newConf = new Configuration();
            for (final String peerIdStr : resp.newPeersList()) {
                final PeerId newPeer = new PeerId();
                newPeer.parse(peerIdStr);
                newConf.addPeer(newPeer);
            }
            LOG.info("Configuration of replication group {} changed from {} to {}", groupId, oldConf, newConf);
            return Status.OK();
        } else {
            return statusFromResponse(result);
        }
    } catch (final Exception e) {
        return new Status(-1, e.getMessage());
    }
}
Also used : Status(org.apache.ignite.raft.jraft.Status) Message(org.apache.ignite.raft.jraft.rpc.Message) Configuration(org.apache.ignite.raft.jraft.conf.Configuration) RemovePeerResponse(org.apache.ignite.raft.jraft.rpc.CliRequests.RemovePeerResponse) JRaftException(org.apache.ignite.raft.jraft.error.JRaftException) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) RemovePeerRequest(org.apache.ignite.raft.jraft.rpc.CliRequests.RemovePeerRequest)

Example 10 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class CliServiceImpl method getLeader.

@Override
public Status getLeader(final String groupId, final Configuration conf, final PeerId leaderId) {
    Requires.requireTrue(!StringUtils.isBlank(groupId), "Blank group id");
    Requires.requireNonNull(leaderId, "Null leader id");
    if (conf == null || conf.isEmpty()) {
        return new Status(RaftError.EINVAL, "Empty group configuration");
    }
    final Status st = new Status(-1, "Fail to get leader of group %s", groupId);
    for (final PeerId peer : conf) {
        if (!this.cliClientService.connect(peer.getEndpoint())) {
            LOG.error("Fail to connect peer {} to get leader for group {}.", peer, groupId);
            continue;
        }
        GetLeaderRequest rb = cliOptions.getRaftMessagesFactory().getLeaderRequest().groupId(groupId).peerId(peer.toString()).build();
        final Future<Message> result = this.cliClientService.getLeader(peer.getEndpoint(), rb, null);
        try {
            final Message msg = result.get(this.cliOptions.getTimeoutMs() <= 0 ? this.cliOptions.getRpcDefaultTimeout() : this.cliOptions.getTimeoutMs(), TimeUnit.MILLISECONDS);
            if (msg instanceof ErrorResponse) {
                if (st.isOk()) {
                    st.setError(-1, ((ErrorResponse) msg).errorMsg());
                } else {
                    final String savedMsg = st.getErrorMsg();
                    st.setError(-1, "%s, %s", savedMsg, ((ErrorResponse) msg).errorMsg());
                }
            } else {
                final GetLeaderResponse response = (GetLeaderResponse) msg;
                if (leaderId.parse(response.leaderId())) {
                    break;
                }
            }
        } catch (final Exception e) {
            if (st.isOk()) {
                st.setError(-1, e.getMessage());
            } else {
                final String savedMsg = st.getErrorMsg();
                st.setError(-1, "%s, %s", savedMsg, e.getMessage());
            }
        }
    }
    if (leaderId.isEmpty()) {
        return st;
    }
    return Status.OK();
}
Also used : Status(org.apache.ignite.raft.jraft.Status) Message(org.apache.ignite.raft.jraft.rpc.Message) GetLeaderRequest(org.apache.ignite.raft.jraft.rpc.CliRequests.GetLeaderRequest) GetLeaderResponse(org.apache.ignite.raft.jraft.rpc.CliRequests.GetLeaderResponse) JRaftException(org.apache.ignite.raft.jraft.error.JRaftException) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) ErrorResponse(org.apache.ignite.raft.jraft.rpc.RpcRequests.ErrorResponse)

Aggregations

Status (org.apache.ignite.raft.jraft.Status)121 Test (org.junit.jupiter.api.Test)49 PeerId (org.apache.ignite.raft.jraft.entity.PeerId)43 CountDownLatch (java.util.concurrent.CountDownLatch)31 Message (org.apache.ignite.raft.jraft.rpc.Message)21 ArrayList (java.util.ArrayList)20 Node (org.apache.ignite.raft.jraft.Node)20 Configuration (org.apache.ignite.raft.jraft.conf.Configuration)20 ReadIndexClosure (org.apache.ignite.raft.jraft.closure.ReadIndexClosure)16 LogId (org.apache.ignite.raft.jraft.entity.LogId)14 RaftException (org.apache.ignite.raft.jraft.error.RaftException)14 LogEntry (org.apache.ignite.raft.jraft.entity.LogEntry)11 JRaftException (org.apache.ignite.raft.jraft.error.JRaftException)11 SynchronizedClosure (org.apache.ignite.raft.jraft.closure.SynchronizedClosure)10 Endpoint (org.apache.ignite.raft.jraft.util.Endpoint)10 ByteBuffer (java.nio.ByteBuffer)9 List (java.util.List)9 ConfigurationEntry (org.apache.ignite.raft.jraft.conf.ConfigurationEntry)9 Task (org.apache.ignite.raft.jraft.entity.Task)8 RaftOptions (org.apache.ignite.raft.jraft.option.RaftOptions)8