Java Code Examples for com.alipay.sofa.jraft.entity.PeerId#equals()

The following examples show how to use com.alipay.sofa.jraft.entity.PeerId#equals() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: sofa-jraft   File: CliServiceTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void testTransferLeader() throws Exception {
    final PeerId leader = this.cluster.getLeader().getNodeId().getPeerId().copy();
    assertNotNull(leader);

    final Set<PeerId> peers = this.conf.getPeerSet();
    PeerId targetPeer = null;
    for (final PeerId peer : peers) {
        if (!peer.equals(leader)) {
            targetPeer = peer;
            break;
        }
    }
    assertNotNull(targetPeer);
    assertTrue(this.cliService.transferLeader(this.groupId, this.conf, targetPeer).isOk());
    this.cluster.waitLeader();
    assertEquals(targetPeer, this.cluster.getLeader().getNodeId().getPeerId());
}
 
Example 2
Source Project: sofa-jraft   File: CliServiceTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void testTransferLeader() throws Exception {
    final PeerId leader = this.cluster.getLeader().getNodeId().getPeerId().copy();
    assertNotNull(leader);

    final Set<PeerId> peers = this.conf.getPeerSet();
    PeerId targetPeer = null;
    for (final PeerId peer : peers) {
        if (!peer.equals(leader)) {
            targetPeer = peer;
            break;
        }
    }
    assertNotNull(targetPeer);
    assertTrue(this.cliService.transferLeader(this.groupId, this.conf, targetPeer).isOk());
    this.cluster.waitLeader();
    assertEquals(targetPeer, this.cluster.getLeader().getNodeId().getPeerId());
}
 
Example 3
Source Project: sofa-jraft   File: CliServiceImpl.java    License: Apache License 2.0 5 votes vote down vote up
private PeerId findTargetPeer(final PeerId self, final String groupId, final Configuration conf,
                              final LeaderCounter leaderCounter) {
    for (final PeerId peerId : getAlivePeers(groupId, conf)) {
        if (peerId.equals(self)) {
            continue;
        }
        if (leaderCounter.get(peerId) >= leaderCounter.getExpectedAverage()) {
            continue;
        }
        return peerId;
    }
    return PeerId.emptyPeer();
}
 
Example 4
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 5 votes vote down vote up
private boolean checkDeadNodes0(final List<PeerId> peers, final long monotonicNowMs, final boolean checkReplicator,
                                final Configuration deadNodes) {
    final int leaderLeaseTimeoutMs = this.options.getLeaderLeaseTimeoutMs();
    int aliveCount = 0;
    long startLease = Long.MAX_VALUE;
    for (final PeerId peer : peers) {
        if (peer.equals(this.serverId)) {
            aliveCount++;
            continue;
        }
        if (checkReplicator) {
            checkReplicator(peer);
        }
        final long lastRpcSendTimestamp = this.replicatorGroup.getLastRpcSendTimestamp(peer);
        if (monotonicNowMs - lastRpcSendTimestamp <= leaderLeaseTimeoutMs) {
            aliveCount++;
            if (startLease > lastRpcSendTimestamp) {
                startLease = lastRpcSendTimestamp;
            }
            continue;
        }
        if (deadNodes != null) {
            deadNodes.addPeer(peer);
        }
    }
    if (aliveCount >= peers.size() / 2 + 1) {
        updateLastLeaderTimestamp(startLease);
        return true;
    }
    return false;
}
 
Example 5
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 5 votes vote down vote up
private List<PeerId> getAliveNodes(final Collection<PeerId> peers, final long monotonicNowMs) {
    final int leaderLeaseTimeoutMs = this.options.getLeaderLeaseTimeoutMs();
    final List<PeerId> alivePeers = new ArrayList<>();
    for (final PeerId peer : peers) {
        if (peer.equals(this.serverId)) {
            alivePeers.add(peer.copy());
            continue;
        }
        if (monotonicNowMs - this.replicatorGroup.getLastRpcSendTimestamp(peer) <= leaderLeaseTimeoutMs) {
            alivePeers.add(peer.copy());
        }
    }
    return alivePeers;
}
 
Example 6
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 5 votes vote down vote up
private void stopReplicator(final Collection<PeerId> keep, final Collection<PeerId> drop) {
    if (drop != null) {
        for (final PeerId peer : drop) {
            if (!keep.contains(peer) && !peer.equals(this.serverId)) {
                this.replicatorGroup.stopReplicator(peer);
            }
        }
    }
}
 
Example 7
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 4 votes vote down vote up
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(false) // It's not a pre-vote request.
                .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();
    }
}
 
Example 8
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 4 votes vote down vote up
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(true) // it's a pre-vote request.
                .setGroupId(this.groupId) //
                .setServerId(this.serverId.toString()) //
                .setPeerId(peer.toString()) //
                .setTerm(this.currTerm + 1) // next term
                .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();
        }
    }
}
 
Example 9
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 4 votes vote down vote up
@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();
        // if peer_id is ANY_PEER(0.0.0.0:0:0), the peer with the largest
        // 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();
}
 
Example 10
Source Project: sofa-jraft   File: NodeImpl.java    License: Apache License 2.0 4 votes vote down vote up
@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);
    }
}