Search in sources :

Example 11 with RaftState

use of com.hazelcast.cp.internal.raft.impl.state.RaftState in project hazelcast by hazelcast.

the class InstallSnapshotHandlerTask method innerRun.

@Override
protected void innerRun() {
    if (logger.isFineEnabled()) {
        logger.fine("Received " + req);
    }
    RaftState state = raftNode.state();
    SnapshotEntry snapshot = req.snapshot();
    // Reply false if term < currentTerm (§5.1)
    if (req.term() < state.term()) {
        if (logger.isFineEnabled()) {
            logger.warning("Stale snapshot: " + req + " received in current term: " + state.term());
        }
        raftNode.send(new AppendFailureResponse(localMember(), state.term(), snapshot.index() + 1), req.leader());
        return;
    }
    // Transform into follower if a newer term is seen or another node wins the election of the current term
    if (req.term() > state.term() || state.role() != FOLLOWER) {
        // If RPC request or response contains term T > currentTerm: set currentTerm = T, convert to follower (§5.1)
        logger.info("Demoting to FOLLOWER from current role: " + state.role() + ", term: " + state.term() + " to new term: " + req.term() + " and leader: " + req.leader());
        raftNode.toFollower(req.term());
    }
    if (!req.leader().equals(state.leader())) {
        logger.info("Setting leader: " + req.leader());
        raftNode.leader(req.leader());
    }
    raftNode.updateLastAppendEntriesTimestamp();
    if (raftNode.installSnapshot(snapshot)) {
        raftNode.send(new AppendSuccessResponse(localMember(), req.term(), snapshot.index(), req.queryRound()), req.leader());
    }
}
Also used : AppendSuccessResponse(com.hazelcast.cp.internal.raft.impl.dto.AppendSuccessResponse) RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState) SnapshotEntry(com.hazelcast.cp.internal.raft.impl.log.SnapshotEntry) AppendFailureResponse(com.hazelcast.cp.internal.raft.impl.dto.AppendFailureResponse)

Example 12 with RaftState

use of com.hazelcast.cp.internal.raft.impl.state.RaftState in project hazelcast by hazelcast.

the class AppendFailureResponseHandlerTask method handleResponse.

@Override
protected void handleResponse() {
    RaftState state = raftNode.state();
    if (state.role() != LEADER) {
        logger.warning(resp + " is ignored since we are not LEADER.");
        return;
    }
    if (resp.term() > state.term()) {
        // If RPC request or response contains term T > currentTerm: set currentTerm = T, convert to follower (§5.1)
        logger.info("Demoting to FOLLOWER after " + resp + " from current term: " + state.term());
        raftNode.toFollower(resp.term());
        return;
    }
    if (logger.isFineEnabled()) {
        logger.fine("Received " + resp);
    }
    if (updateNextIndex(state)) {
        raftNode.sendAppendRequest(resp.follower());
    }
}
Also used : RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState)

Example 13 with RaftState

use of com.hazelcast.cp.internal.raft.impl.state.RaftState in project hazelcast by hazelcast.

the class PreVoteRequestHandlerTask method innerRun.

@Override
protected void innerRun() {
    RaftState state = raftNode.state();
    RaftEndpoint localEndpoint = localMember();
    // Reply false if term < currentTerm (§5.1)
    if (state.term() > req.nextTerm()) {
        logger.info("Rejecting " + req + " since current term: " + state.term() + " is bigger");
        raftNode.send(new PreVoteResponse(localEndpoint, state.term(), false), req.candidate());
        return;
    }
    // Reply false if last AppendEntries call was received less than election timeout ago (leader stickiness)
    if (raftNode.lastAppendEntriesTimestamp() > Clock.currentTimeMillis() - raftNode.getLeaderElectionTimeoutInMillis()) {
        logger.info("Rejecting " + req + " since received append entries recently.");
        raftNode.send(new PreVoteResponse(localEndpoint, state.term(), false), req.candidate());
        return;
    }
    RaftLog raftLog = state.log();
    if (raftLog.lastLogOrSnapshotTerm() > req.lastLogTerm()) {
        logger.info("Rejecting " + req + " since our last log term: " + raftLog.lastLogOrSnapshotTerm() + " is greater");
        raftNode.send(new PreVoteResponse(localEndpoint, req.nextTerm(), false), req.candidate());
        return;
    }
    if (raftLog.lastLogOrSnapshotTerm() == req.lastLogTerm() && raftLog.lastLogOrSnapshotIndex() > req.lastLogIndex()) {
        logger.info("Rejecting " + req + " since our last log index: " + raftLog.lastLogOrSnapshotIndex() + " is greater");
        raftNode.send(new PreVoteResponse(localEndpoint, req.nextTerm(), false), req.candidate());
        return;
    }
    logger.info("Granted pre-vote for " + req);
    raftNode.send(new PreVoteResponse(localEndpoint, req.nextTerm(), true), req.candidate());
}
Also used : RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState) RaftEndpoint(com.hazelcast.cp.internal.raft.impl.RaftEndpoint) PreVoteResponse(com.hazelcast.cp.internal.raft.impl.dto.PreVoteResponse) RaftLog(com.hazelcast.cp.internal.raft.impl.log.RaftLog)

Example 14 with RaftState

use of com.hazelcast.cp.internal.raft.impl.state.RaftState in project hazelcast by hazelcast.

the class TriggerLeaderElectionHandlerTask method innerRun.

@Override
protected void innerRun() {
    if (logger.isFineEnabled()) {
        logger.fine("Received " + req);
    }
    RaftState state = raftNode.state();
    // with the leader's log.
    if (!(req.term() == state.term() && req.leader().equals(state.leader()))) {
        if (logger.isFineEnabled()) {
            logger.fine("Ignoring " + req + " since term: " + state.term() + " and leader: " + state.leader());
        }
        return;
    }
    // Verify the last log entry
    LogEntry entry = state.log().lastLogOrSnapshotEntry();
    if (!(entry.index() == req.lastLogIndex() && entry.term() == req.lastLogTerm())) {
        if (logger.isFineEnabled()) {
            logger.fine("Could not accept leadership transfer because local Raft log is not same with the current leader. " + "Last log entry: " + entry + ", request: " + req);
        }
        return;
    }
    // I will send a disruptive VoteRequest to bypass leader stickiness
    logger.info("Starting a new leader election since the current leader: " + req.leader() + " in term: " + req.term() + " asked for a leadership transfer!");
    state.leader(null);
    new LeaderElectionTask(raftNode, true).run();
}
Also used : RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState) LeaderElectionTask(com.hazelcast.cp.internal.raft.impl.task.LeaderElectionTask) LogEntry(com.hazelcast.cp.internal.raft.impl.log.LogEntry)

Example 15 with RaftState

use of com.hazelcast.cp.internal.raft.impl.state.RaftState in project hazelcast by hazelcast.

the class VoteResponseHandlerTask method handleResponse.

@Override
protected void handleResponse() {
    RaftState state = raftNode.state();
    if (state.role() != CANDIDATE) {
        logger.info("Ignored " + resp + ". We are not CANDIDATE anymore.");
        return;
    }
    if (resp.term() > state.term()) {
        logger.info("Demoting to FOLLOWER from current term: " + state.term() + " to new term: " + resp.term() + " after " + resp);
        raftNode.toFollower(resp.term());
        return;
    }
    if (resp.term() < state.term()) {
        logger.warning("Stale " + resp + " is received, current term: " + state.term());
        return;
    }
    CandidateState candidateState = state.candidateState();
    if (resp.granted() && candidateState.grantVote(resp.voter())) {
        logger.info("Vote granted from " + resp.voter() + " for term: " + state.term() + ", number of votes: " + candidateState.voteCount() + ", majority: " + candidateState.majority());
    }
    if (candidateState.isMajorityGranted()) {
        logger.info("We are the LEADER!");
        raftNode.toLeader();
    }
}
Also used : CandidateState(com.hazelcast.cp.internal.raft.impl.state.CandidateState) RaftState(com.hazelcast.cp.internal.raft.impl.state.RaftState)

Aggregations

RaftState (com.hazelcast.cp.internal.raft.impl.state.RaftState)20 RaftEndpoint (com.hazelcast.cp.internal.raft.impl.RaftEndpoint)7 NotLeaderException (com.hazelcast.cp.exception.NotLeaderException)5 RaftLog (com.hazelcast.cp.internal.raft.impl.log.RaftLog)5 LogEntry (com.hazelcast.cp.internal.raft.impl.log.LogEntry)4 CPSubsystemException (com.hazelcast.cp.exception.CPSubsystemException)3 CannotReplicateException (com.hazelcast.cp.exception.CannotReplicateException)3 MemberAlreadyExistsException (com.hazelcast.cp.internal.raft.exception.MemberAlreadyExistsException)2 MemberDoesNotExistException (com.hazelcast.cp.internal.raft.exception.MemberDoesNotExistException)2 AppendSuccessResponse (com.hazelcast.cp.internal.raft.impl.dto.AppendSuccessResponse)2 CandidateState (com.hazelcast.cp.internal.raft.impl.state.CandidateState)2 LeaderState (com.hazelcast.cp.internal.raft.impl.state.LeaderState)2 LeaderElectionTask (com.hazelcast.cp.internal.raft.impl.task.LeaderElectionTask)2 UUID (java.util.UUID)2 MismatchingGroupMembersCommitIndexException (com.hazelcast.cp.internal.raft.exception.MismatchingGroupMembersCommitIndexException)1 UpdateRaftGroupMembersCmd (com.hazelcast.cp.internal.raft.impl.command.UpdateRaftGroupMembersCmd)1 AppendFailureResponse (com.hazelcast.cp.internal.raft.impl.dto.AppendFailureResponse)1 PreVoteRequest (com.hazelcast.cp.internal.raft.impl.dto.PreVoteRequest)1 PreVoteResponse (com.hazelcast.cp.internal.raft.impl.dto.PreVoteResponse)1 TriggerLeaderElection (com.hazelcast.cp.internal.raft.impl.dto.TriggerLeaderElection)1