Search in sources :

Example 41 with LogId

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

the class NodeImpl method preVote.

// in writeLock
private void preVote() {
    long oldTerm;
    try {
        LOG.info("Node {} term {} start preVote.", getNodeId(), this.currTerm);
        if (this.snapshotExecutor != null && this.snapshotExecutor.isInstallingSnapshot()) {
            LOG.warn("Node {} term {} doesn't do preVote when installing snapshot as the configuration may be out of date.", getNodeId(), this.currTerm);
            return;
        }
        if (!this.conf.contains(this.serverId)) {
            LOG.warn("Node {} can't do preVote as it is not in conf <{}>.", getNodeId(), this.conf);
            return;
        }
        oldTerm = this.currTerm;
    } finally {
        this.writeLock.unlock();
    }
    final LogId lastLogId = this.logManager.getLastLogId(true);
    boolean doUnlock = true;
    this.writeLock.lock();
    try {
        // pre_vote need defense ABA after unlock&writeLock
        if (oldTerm != this.currTerm) {
            LOG.warn("Node {} raise term {} when get lastLogId.", getNodeId(), this.currTerm);
            return;
        }
        this.prevVoteCtx.init(this.conf.getConf(), this.conf.isStable() ? null : this.conf.getOldConf());
        for (final PeerId peer : this.conf.listPeers()) {
            if (peer.equals(this.serverId)) {
                continue;
            }
            if (!this.rpcService.connect(peer.getEndpoint())) {
                LOG.warn("Node {} channel init failed, address={}.", getNodeId(), peer.getEndpoint());
                continue;
            }
            final OnPreVoteRpcDone done = new OnPreVoteRpcDone(peer, this.currTerm);
            done.request = // 
            RequestVoteRequest.newBuilder().setPreVote(// it's a pre-vote request.
            true).setGroupId(// 
            this.groupId).setServerId(// 
            this.serverId.toString()).setPeerId(// 
            peer.toString()).setTerm(// next term
            this.currTerm + 1).setLastLogIndex(// 
            lastLogId.getIndex()).setLastLogTerm(// 
            lastLogId.getTerm()).build();
            this.rpcService.preVote(peer.getEndpoint(), done.request, done);
        }
        this.prevVoteCtx.grant(this.serverId);
        if (this.prevVoteCtx.isGranted()) {
            doUnlock = false;
            electSelf();
        }
    } finally {
        if (doUnlock) {
            this.writeLock.unlock();
        }
    }
}
Also used : LogId(com.alipay.sofa.jraft.entity.LogId) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 42 with LogId

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

the class NodeImpl method electSelf.

// should be in writeLock
private void electSelf() {
    long oldTerm;
    try {
        LOG.info("Node {} start vote and grant vote self, term={}.", getNodeId(), this.currTerm);
        if (!this.conf.contains(this.serverId)) {
            LOG.warn("Node {} can't do electSelf as it is not in {}.", getNodeId(), this.conf);
            return;
        }
        if (this.state == State.STATE_FOLLOWER) {
            LOG.debug("Node {} stop election timer, term={}.", getNodeId(), this.currTerm);
            this.electionTimer.stop();
        }
        resetLeaderId(PeerId.emptyPeer(), new Status(RaftError.ERAFTTIMEDOUT, "A follower's leader_id is reset to NULL as it begins to request_vote."));
        this.state = State.STATE_CANDIDATE;
        this.currTerm++;
        this.votedId = this.serverId.copy();
        LOG.debug("Node {} start vote timer, term={} .", getNodeId(), this.currTerm);
        this.voteTimer.start();
        this.voteCtx.init(this.conf.getConf(), this.conf.isStable() ? null : this.conf.getOldConf());
        oldTerm = this.currTerm;
    } finally {
        this.writeLock.unlock();
    }
    final LogId lastLogId = this.logManager.getLastLogId(true);
    this.writeLock.lock();
    try {
        // vote need defense ABA after unlock&writeLock
        if (oldTerm != this.currTerm) {
            LOG.warn("Node {} raise term {} when getLastLogId.", getNodeId(), this.currTerm);
            return;
        }
        for (final PeerId peer : this.conf.listPeers()) {
            if (peer.equals(this.serverId)) {
                continue;
            }
            if (!this.rpcService.connect(peer.getEndpoint())) {
                LOG.warn("Node {} channel init failed, address={}.", getNodeId(), peer.getEndpoint());
                continue;
            }
            final OnRequestVoteRpcDone done = new OnRequestVoteRpcDone(peer, this.currTerm, this);
            done.request = // 
            RequestVoteRequest.newBuilder().setPreVote(// It's not a pre-vote request.
            false).setGroupId(// 
            this.groupId).setServerId(// 
            this.serverId.toString()).setPeerId(// 
            peer.toString()).setTerm(// 
            this.currTerm).setLastLogIndex(// 
            lastLogId.getIndex()).setLastLogTerm(// 
            lastLogId.getTerm()).build();
            this.rpcService.requestVote(peer.getEndpoint(), done.request, done);
        }
        this.metaStorage.setTermAndVotedFor(this.currTerm, this.serverId);
        this.voteCtx.grant(this.serverId);
        if (this.voteCtx.isGranted()) {
            becomeLeader();
        }
    } finally {
        this.writeLock.unlock();
    }
}
Also used : Status(com.alipay.sofa.jraft.Status) LogId(com.alipay.sofa.jraft.entity.LogId) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 43 with LogId

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

the class NodeImpl method unsafeApplyConfiguration.

private void unsafeApplyConfiguration(final Configuration newConf, final Configuration oldConf, final boolean leaderStart) {
    Requires.requireTrue(this.confCtx.isBusy(), "ConfigurationContext is not busy");
    final LogEntry entry = new LogEntry(EnumOutter.EntryType.ENTRY_TYPE_CONFIGURATION);
    entry.setId(new LogId(0, this.currTerm));
    entry.setPeers(newConf.listPeers());
    entry.setLearners(newConf.listLearners());
    if (oldConf != null) {
        entry.setOldPeers(oldConf.listPeers());
        entry.setOldLearners(oldConf.listLearners());
    }
    final ConfigurationChangeDone configurationChangeDone = new ConfigurationChangeDone(this.currTerm, leaderStart);
    // Use the new_conf to deal the quorum of this very log
    if (!this.ballotBox.appendPendingTask(newConf, oldConf, configurationChangeDone)) {
        Utils.runClosureInThread(configurationChangeDone, new Status(RaftError.EINTERNAL, "Fail to append task."));
        return;
    }
    final List<LogEntry> entries = new ArrayList<>();
    entries.add(entry);
    this.logManager.appendEntries(entries, new LeaderStableClosure(entries));
    checkAndSetConfiguration(false);
}
Also used : Status(com.alipay.sofa.jraft.Status) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) LogId(com.alipay.sofa.jraft.entity.LogId) LogEntry(com.alipay.sofa.jraft.entity.LogEntry)

Example 44 with LogId

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

the class FSMCallerImpl method doSnapshotLoad.

private void doSnapshotLoad(final LoadSnapshotClosure done) {
    Requires.requireNonNull(done, "LoadSnapshotClosure is null");
    final SnapshotReader reader = done.start();
    if (reader == null) {
        done.run(new Status(RaftError.EINVAL, "open SnapshotReader failed"));
        return;
    }
    final RaftOutter.SnapshotMeta meta = reader.load();
    if (meta == null) {
        done.run(new Status(RaftError.EINVAL, "SnapshotReader load meta failed"));
        if (reader.getRaftError() == RaftError.EIO) {
            final RaftException err = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_SNAPSHOT, RaftError.EIO, "Fail to load snapshot meta");
            setError(err);
        }
        return;
    }
    final LogId lastAppliedId = new LogId(this.lastAppliedIndex.get(), this.lastAppliedTerm);
    final LogId snapshotId = new LogId(meta.getLastIncludedIndex(), meta.getLastIncludedTerm());
    if (lastAppliedId.compareTo(snapshotId) > 0) {
        done.run(new Status(RaftError.ESTALE, "Loading a stale snapshot last_applied_index=%d last_applied_term=%d snapshot_index=%d snapshot_term=%d", lastAppliedId.getIndex(), lastAppliedId.getTerm(), snapshotId.getIndex(), snapshotId.getTerm()));
        return;
    }
    if (!this.fsm.onSnapshotLoad(reader)) {
        done.run(new Status(-1, "StateMachine onSnapshotLoad failed"));
        final RaftException e = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_STATE_MACHINE, RaftError.ESTATEMACHINE, "StateMachine onSnapshotLoad failed");
        setError(e);
        return;
    }
    if (meta.getOldPeersCount() == 0) {
        // Joint stage is not supposed to be noticeable by end users.
        final Configuration conf = new Configuration();
        for (int i = 0, size = meta.getPeersCount(); i < size; i++) {
            final PeerId peer = new PeerId();
            Requires.requireTrue(peer.parse(meta.getPeers(i)), "Parse peer failed");
            conf.addPeer(peer);
        }
        this.fsm.onConfigurationCommitted(conf);
    }
    this.lastAppliedIndex.set(meta.getLastIncludedIndex());
    this.lastAppliedTerm = meta.getLastIncludedTerm();
    done.run(Status.OK());
}
Also used : Status(com.alipay.sofa.jraft.Status) RaftException(com.alipay.sofa.jraft.error.RaftException) Configuration(com.alipay.sofa.jraft.conf.Configuration) RaftOutter(com.alipay.sofa.jraft.entity.RaftOutter) SnapshotReader(com.alipay.sofa.jraft.storage.snapshot.SnapshotReader) LogId(com.alipay.sofa.jraft.entity.LogId) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Aggregations

LogId (com.alipay.sofa.jraft.entity.LogId)44 LogEntry (com.alipay.sofa.jraft.entity.LogEntry)26 PeerId (com.alipay.sofa.jraft.entity.PeerId)18 Test (org.junit.Test)18 Status (com.alipay.sofa.jraft.Status)10 BaseStorageTest (com.alipay.sofa.jraft.storage.BaseStorageTest)9 ArrayList (java.util.ArrayList)8 ConfigurationEntry (com.alipay.sofa.jraft.conf.ConfigurationEntry)7 Configuration (com.alipay.sofa.jraft.conf.Configuration)5 ByteBuffer (java.nio.ByteBuffer)5 LogManager (com.alipay.sofa.jraft.storage.LogManager)4 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ConfigurationManager (com.alipay.sofa.jraft.conf.ConfigurationManager)3 EntryType (com.alipay.sofa.jraft.entity.EnumOutter.EntryType)2 BaseLogEntryCodecFactoryTest (com.alipay.sofa.jraft.entity.codec.BaseLogEntryCodecFactoryTest)2 RaftException (com.alipay.sofa.jraft.error.RaftException)2 LogStorageOptions (com.alipay.sofa.jraft.option.LogStorageOptions)2 RaftOptions (com.alipay.sofa.jraft.option.RaftOptions)2 DisruptorMetricSet (com.alipay.sofa.jraft.util.DisruptorMetricSet)2