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());
}
}
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());
}
}
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());
}
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();
}
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();
}
}
Aggregations