- if (message instanceof ElectionTimeout) {
- if(canStartElection()) {
- LOG.debug("{}: Received ElectionTimeout - switching to Candidate", logName());
+ return super.handleMessage(sender, rpc);
+ }
+
+ private RaftActorBehavior handleElectionTimeout(Object message) {
+ // If the message is ElectionTimeout, verify we haven't actually seen a message from the leader
+ // during the election timeout interval. It may that the election timer expired b/c this actor
+ // was busy and messages got delayed, in which case leader messages would be backed up in the
+ // queue but would be processed before the ElectionTimeout message and thus would restart the
+ // lastLeaderMessageTimer.
+ long lastLeaderMessageInterval = lastLeaderMessageTimer.elapsed(TimeUnit.MILLISECONDS);
+ long electionTimeoutInMillis = context.getConfigParams().getElectionTimeOutInterval().toMillis();
+ boolean noLeaderMessageReceived = !lastLeaderMessageTimer.isRunning() ||
+ lastLeaderMessageInterval >= electionTimeoutInMillis;
+
+ if(canStartElection()) {
+ if(message instanceof TimeoutNow) {
+ LOG.debug("{}: Received TimeoutNow - switching to Candidate", logName());