Add getPeerIds to RaftActorContext
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / behaviors / Candidate.java
index b36c41abf262b8c24d05f354091f7c4ec92a0827..8baf0d8e815d96957c1d4e6cee3ad55b1bd21f07 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.cluster.raft.behaviors;
 
 import akka.actor.ActorRef;
 import akka.actor.ActorSelection;
-import java.util.Set;
+import java.util.Collection;
 import org.opendaylight.controller.cluster.raft.RaftActorContext;
 import org.opendaylight.controller.cluster.raft.RaftState;
 import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
@@ -44,12 +44,12 @@ public class Candidate extends AbstractRaftActorBehavior {
 
     private final int votesRequired;
 
-    private final Set<String> peers;
+    private final Collection<String> peers;
 
     public Candidate(RaftActorContext context) {
         super(context, RaftState.Candidate);
 
-        peers = context.getPeerAddresses().keySet();
+        peers = context.getPeerIds();
 
         if(LOG.isDebugEnabled()) {
             LOG.debug("{}: Election: Candidate has following peers: {}", logName(), peers);
@@ -58,7 +58,14 @@ public class Candidate extends AbstractRaftActorBehavior {
         votesRequired = getMajorityVoteCount(peers.size());
 
         startNewTerm();
-        scheduleElection(electionDuration());
+
+        if(peers.isEmpty()){
+            actor().tell(ELECTION_TIMEOUT, actor());
+        } else {
+            scheduleElection(electionDuration());
+        }
+
+
     }
 
     @Override protected RaftActorBehavior handleAppendEntries(ActorRef sender,
@@ -68,6 +75,14 @@ public class Candidate extends AbstractRaftActorBehavior {
             LOG.debug("{}: handleAppendEntries: {}", logName(), appendEntries);
         }
 
+        // Some other candidate for the same term became a leader and sent us an append entry
+        if(currentTerm() == appendEntries.getTerm()){
+            LOG.debug("{}: New Leader sent an append entry to Candidate for term {} will switch to Follower",
+                    logName(), currentTerm());
+
+            return switchBehavior(new Follower(context));
+        }
+
         return this;
     }
 
@@ -88,7 +103,7 @@ public class Candidate extends AbstractRaftActorBehavior {
         }
 
         if (voteCount >= votesRequired) {
-            return switchBehavior(new Leader(context));
+            return internalSwitchBehavior(RaftState.Leader);
         }
 
         return this;
@@ -114,7 +129,7 @@ public class Candidate extends AbstractRaftActorBehavior {
             if (rpc.getTerm() > context.getTermInformation().getCurrentTerm()) {
                 context.getTermInformation().updateAndPersist(rpc.getTerm(), null);
 
-                return switchBehavior(new Follower(context));
+                return internalSwitchBehavior(RaftState.Follower);
             }
         }
 
@@ -128,7 +143,7 @@ public class Candidate extends AbstractRaftActorBehavior {
                 // who we do not know about (as a peer)
                 // to send a message to the candidate
 
-                return switchBehavior(new Leader(context));
+                return internalSwitchBehavior(RaftState.Leader);
             }
             startNewTerm();
             scheduleElection(electionDuration());