@@ -385,20 +385,42 @@ impl<T: TWriteAheadLog> ClusterActor<T> {
385
385
if self . find_replica_mut ( & request_vote. candidate_id ) . is_none ( ) {
386
386
return ;
387
387
} ;
388
- REQUESTS_BLOCKED_BY_ELECTION . store ( true , Ordering :: Relaxed ) ;
389
388
390
- let grant_vote = self . logger ( ) . last_log_index <= request_vote. last_log_index
391
- && self . replication . become_follower_if_term_higher_and_votable (
392
- & request_vote. candidate_id ,
393
- request_vote. term ,
389
+ let mut grant_vote = false ;
390
+
391
+ // 1. If candidate's term is less than current term, reject
392
+ if request_vote. term < self . replication . term {
393
+ info ! (
394
+ "Rejecting vote for {} (term {}). My term is higher ({})." ,
395
+ request_vote. candidate_id, request_vote. term, self . replication. term
394
396
) ;
397
+ }
398
+ // 2. If candidate's term is greater than or equal to current term
399
+ else {
400
+ // If candidate's term is higher, update own term and step down
401
+ if request_vote. term > self . replication . term {
402
+ self . replication . term = request_vote. term ;
403
+ self . replication . vote_for ( None ) ; // Clear votedFor
404
+ self . step_down ( ) . await ; // Ensure follower mode
405
+ }
406
+
407
+ // 3. Check if log is up-to-date and if not already voted in this term or voted for this candidate
408
+ if self
409
+ . replication
410
+ . is_log_up_to_date ( request_vote. last_log_index , request_vote. last_log_term )
411
+ && self . replication . election_state . is_votable ( & request_vote. candidate_id )
412
+ {
413
+ self . replication . vote_for ( Some ( request_vote. candidate_id . clone ( ) ) ) ;
414
+ grant_vote = true ;
415
+ }
416
+ REQUESTS_BLOCKED_BY_ELECTION . store ( true , Ordering :: Relaxed ) ;
417
+ }
395
418
396
419
info ! (
397
420
"Voting for {} with term {} and granted: {grant_vote}" ,
398
421
request_vote. candidate_id, request_vote. term
399
422
) ;
400
423
401
- // ! vote may have been made for requester, maybe not. Therefore, we have to set the term for self
402
424
let vote = ElectionVote { term : self . replication . term , vote_granted : grant_vote } ;
403
425
let Some ( peer) = self . find_replica_mut ( & request_vote. candidate_id ) else {
404
426
return ;
@@ -1041,7 +1063,7 @@ impl<T: TWriteAheadLog> ClusterActor<T> {
1041
1063
/// 2) step down operation is given from user
1042
1064
async fn step_down ( & mut self ) {
1043
1065
self . replication . vote_for ( None ) ;
1044
- self . heartbeat_scheduler . turn_follower_mode ( ) . await ;
1066
+ self . heartbeat_scheduler . turn_follower_mode ( ) ;
1045
1067
}
1046
1068
1047
1069
async fn become_leader ( & mut self ) {
0 commit comments