X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2Fbehaviors%2FCandidate.java;h=52ed26758ee26b6f9949fa1202f1a44628b82364;hp=a5def02b1f5ad3301edfdf7bca2669fc8ab2256e;hb=bad1f8b8f3c1780cd37ec8a817ef4b0f23901654;hpb=ce0c4f4fc0557aaf46a73913a18b83ec29051570 diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java index a5def02b1f..52ed26758e 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/behaviors/Candidate.java @@ -115,16 +115,37 @@ public class Candidate extends AbstractRaftActorBehavior { } if (voteCount >= votesRequired) { - return internalSwitchBehavior(RaftState.Leader); + if(context.getCommitIndex() < context.getReplicatedLog().lastIndex()) { + LOG.debug("{}: Connmit index {} is behind last index {}", logName(), context.getCommitIndex(), + context.getReplicatedLog().lastIndex()); + return internalSwitchBehavior(RaftState.PreLeader); + } else { + return internalSwitchBehavior(RaftState.Leader); + } } return this; } @Override - public RaftActorBehavior handleMessage(ActorRef sender, Object originalMessage) { + public RaftActorBehavior handleMessage(ActorRef sender, Object message) { + if (message instanceof ElectionTimeout) { + LOG.debug("{}: Received ElectionTimeout", logName()); + + if (votesRequired == 0) { + // If there are no peers then we should be a Leader + // We wait for the election timeout to occur before declare + // ourselves the leader. This gives enough time for a leader + // who we do not know about (as a peer) + // to send a message to the candidate + + return internalSwitchBehavior(RaftState.Leader); + } - Object message = fromSerializableMessage(originalMessage); + startNewTerm(); + scheduleElection(electionDuration()); + return this; + } if (message instanceof RaftRPC) { @@ -141,25 +162,14 @@ public class Candidate extends AbstractRaftActorBehavior { if (rpc.getTerm() > context.getTermInformation().getCurrentTerm()) { context.getTermInformation().updateAndPersist(rpc.getTerm(), null); - return internalSwitchBehavior(RaftState.Follower); - } - } - - if (message instanceof ElectionTimeout) { - LOG.debug("{}: Received ElectionTimeout", logName()); - - if (votesRequired == 0) { - // If there are no peers then we should be a Leader - // We wait for the election timeout to occur before declare - // ourselves the leader. This gives enough time for a leader - // who we do not know about (as a peer) - // to send a message to the candidate + // The raft paper does not say whether or not a Candidate can/should process a RequestVote in + // this case but doing so gains quicker convergence when the sender's log is more up-to-date. + if (message instanceof RequestVote) { + super.handleMessage(sender, message); + } - return internalSwitchBehavior(RaftState.Leader); + return internalSwitchBehavior(RaftState.Follower); } - startNewTerm(); - scheduleElection(electionDuration()); - return this; } return super.handleMessage(sender, message);