process_request_vote.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use crate::{Raft, RequestVoteArgs, RequestVoteReply, State};
  2. // Command must be
  3. // 1. clone: they are copied to the persister.
  4. // 2. serialize: they are converted to bytes to persist.
  5. // 3. default: a default value is used as the first element of the log.
  6. impl<Command> Raft<Command>
  7. where
  8. Command: Clone + serde::Serialize + Default,
  9. {
  10. pub fn process_request_vote(
  11. &self,
  12. args: RequestVoteArgs,
  13. ) -> RequestVoteReply {
  14. // Note: do not change this to `let _ = ...`.
  15. let _guard = self.daemon_env.for_scope();
  16. let mut rf = self.inner_state.lock();
  17. let term = rf.current_term;
  18. #[allow(clippy::comparison_chain)]
  19. if args.term < term {
  20. return RequestVoteReply {
  21. term,
  22. vote_granted: false,
  23. };
  24. } else if args.term > term {
  25. rf.current_term = args.term;
  26. rf.voted_for = None;
  27. rf.state = State::Follower;
  28. self.election.reset_election_timer();
  29. self.persister.save_state(rf.persisted_state().into());
  30. }
  31. let voted_for = rf.voted_for;
  32. let last_log = rf.log.last_index_term();
  33. if (voted_for.is_none() || voted_for == Some(args.candidate_id))
  34. && (args.last_log_term > last_log.term
  35. || (args.last_log_term == last_log.term
  36. && args.last_log_index >= last_log.index))
  37. {
  38. rf.voted_for = Some(args.candidate_id);
  39. // It is possible that we have set a timer above when updating the
  40. // current term. It does not hurt to update the timer again.
  41. // We do need to persist, though.
  42. self.election.reset_election_timer();
  43. self.persister.save_state(rf.persisted_state().into());
  44. RequestVoteReply {
  45. term: args.term,
  46. vote_granted: true,
  47. }
  48. } else {
  49. RequestVoteReply {
  50. term: args.term,
  51. vote_granted: false,
  52. }
  53. }
  54. }
  55. }