Search in sources :

Example 71 with Status

use of com.alipay.sofa.jraft.Status in project sofa-jraft by sofastack.

the class NodeImpl method onError.

public void onError(final RaftException error) {
    LOG.warn("Node {} got error: {}.", getNodeId(), 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(com.alipay.sofa.jraft.Status)

Example 72 with Status

use of com.alipay.sofa.jraft.Status in project sofa-jraft by sofastack.

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.timerManager.schedule(() -> onTransferTimeout(stopArg), this.options.getElectionTimeoutMs(), TimeUnit.MILLISECONDS);
    } finally {
        this.writeLock.unlock();
    }
    return Status.OK();
}
Also used : Status(com.alipay.sofa.jraft.Status) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 73 with Status

use of com.alipay.sofa.jraft.Status in project sofa-jraft by sofastack.

the class NodeImpl method checkDeadNodes.

private boolean checkDeadNodes(final Configuration conf, final long monotonicNowMs, final boolean stepDownOnCheckFail) {
    // Check learner replicators at first.
    for (final PeerId peer : conf.getLearners()) {
        checkReplicator(peer);
    }
    // Ensure quorum nodes alive.
    final List<PeerId> peers = conf.listPeers();
    final Configuration deadNodes = new Configuration();
    if (checkDeadNodes0(peers, monotonicNowMs, true, deadNodes)) {
        return true;
    }
    if (stepDownOnCheckFail) {
        LOG.warn("Node {} steps down when alive nodes don't satisfy quorum, term={}, deadNodes={}, conf={}.", getNodeId(), this.currTerm, deadNodes, conf);
        final Status status = new Status();
        status.setError(RaftError.ERAFTTIMEDOUT, "Majority of the group dies: %d/%d", deadNodes.size(), peers.size());
        stepDown(this.currTerm, false, status);
    }
    return false;
}
Also used : Status(com.alipay.sofa.jraft.Status) Configuration(com.alipay.sofa.jraft.conf.Configuration) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 74 with Status

use of com.alipay.sofa.jraft.Status in project sofa-jraft by sofastack.

the class NodeImpl method handleInstallSnapshot.

@Override
public Message handleInstallSnapshot(final InstallSnapshotRequest request, final RpcRequestClosure done) {
    if (this.snapshotExecutor == null) {
        return // 
        RpcFactoryHelper.responseFactory().newResponse(InstallSnapshotResponse.getDefaultInstance(), RaftError.EINVAL, "Not supported snapshot");
    }
    final PeerId serverId = new PeerId();
    if (!serverId.parse(request.getServerId())) {
        LOG.warn("Node {} ignore InstallSnapshotRequest from {} bad server id.", getNodeId(), request.getServerId());
        return // 
        RpcFactoryHelper.responseFactory().newResponse(InstallSnapshotResponse.getDefaultInstance(), RaftError.EINVAL, "Parse serverId failed: %s", request.getServerId());
    }
    this.writeLock.lock();
    try {
        if (!this.state.isActive()) {
            LOG.warn("Node {} ignore InstallSnapshotRequest as it is not in active state {}.", getNodeId(), this.state);
            return // 
            RpcFactoryHelper.responseFactory().newResponse(InstallSnapshotResponse.getDefaultInstance(), RaftError.EINVAL, "Node %s:%s is not in active state, state %s.", this.groupId, this.serverId, this.state.name());
        }
        if (request.getTerm() < this.currTerm) {
            LOG.warn("Node {} ignore stale InstallSnapshotRequest from {}, term={}, currTerm={}.", getNodeId(), request.getPeerId(), request.getTerm(), this.currTerm);
            return // 
            InstallSnapshotResponse.newBuilder().setTerm(// 
            this.currTerm).setSuccess(// 
            false).build();
        }
        checkStepDown(request.getTerm(), serverId);
        if (!serverId.equals(this.leaderId)) {
            LOG.error("Another peer {} declares that it is the leader at term {} which was occupied by leader {}.", serverId, this.currTerm, this.leaderId);
            // Increase the term by 1 and make both leaders step down to minimize the
            // loss of split brain
            stepDown(request.getTerm() + 1, false, new Status(RaftError.ELEADERCONFLICT, "More than one leader in the same term."));
            return // 
            InstallSnapshotResponse.newBuilder().setTerm(// 
            request.getTerm() + 1).setSuccess(// 
            false).build();
        }
    } finally {
        this.writeLock.unlock();
    }
    final long startMs = Utils.monotonicMs();
    try {
        if (LOG.isInfoEnabled()) {
            LOG.info("Node {} received InstallSnapshotRequest from {}, lastIncludedLogIndex={}, lastIncludedLogTerm={}, lastLogId={}.", getNodeId(), request.getServerId(), request.getMeta().getLastIncludedIndex(), request.getMeta().getLastIncludedTerm(), this.logManager.getLastLogId(false));
        }
        this.snapshotExecutor.installSnapshot(request, InstallSnapshotResponse.newBuilder(), done);
        return null;
    } finally {
        this.metrics.recordLatency("install-snapshot", Utils.monotonicMs() - startMs);
    }
}
Also used : Status(com.alipay.sofa.jraft.Status) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 75 with Status

use of com.alipay.sofa.jraft.Status in project sofa-jraft by sofastack.

the class NodeImpl method handleReadIndexRequest.

/**
 * Handle read index request.
 */
@Override
public void handleReadIndexRequest(final ReadIndexRequest request, final RpcResponseClosure<ReadIndexResponse> done) {
    final long startMs = Utils.monotonicMs();
    this.readLock.lock();
    try {
        switch(this.state) {
            case STATE_LEADER:
                readLeader(request, ReadIndexResponse.newBuilder(), done);
                break;
            case STATE_FOLLOWER:
                readFollower(request, done);
                break;
            case STATE_TRANSFERRING:
                done.run(new Status(RaftError.EBUSY, "Is transferring leadership."));
                break;
            default:
                done.run(new Status(RaftError.EPERM, "Invalid state for readIndex: %s.", this.state));
                break;
        }
    } finally {
        this.readLock.unlock();
        this.metrics.recordLatency("handle-read-index", Utils.monotonicMs() - startMs);
        this.metrics.recordSize("handle-read-index-entries", request.getEntriesCount());
    }
}
Also used : Status(com.alipay.sofa.jraft.Status)

Aggregations

Status (com.alipay.sofa.jraft.Status)213 Test (org.junit.Test)63 PeerId (com.alipay.sofa.jraft.entity.PeerId)55 CountDownLatch (java.util.concurrent.CountDownLatch)36 BaseKVStoreClosure (com.alipay.sofa.jraft.rhea.storage.BaseKVStoreClosure)33 Configuration (com.alipay.sofa.jraft.conf.Configuration)25 Message (com.google.protobuf.Message)24 ReadIndexClosure (com.alipay.sofa.jraft.closure.ReadIndexClosure)22 ArrayList (java.util.ArrayList)22 Node (com.alipay.sofa.jraft.Node)21 Closure (com.alipay.sofa.jraft.Closure)17 Task (com.alipay.sofa.jraft.entity.Task)17 ByteBuffer (java.nio.ByteBuffer)16 Endpoint (com.alipay.sofa.jraft.util.Endpoint)15 List (java.util.List)15 RaftException (com.alipay.sofa.jraft.error.RaftException)14 LogEntry (com.alipay.sofa.jraft.entity.LogEntry)12 LogId (com.alipay.sofa.jraft.entity.LogId)12 KVStoreClosure (com.alipay.sofa.jraft.rhea.storage.KVStoreClosure)12 JRaftException (com.alipay.sofa.jraft.error.JRaftException)11