process_request_vote.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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. impl<Command: Clone + serde::Serialize> Raft<Command> {
  6. pub fn process_request_vote(
  7. &self,
  8. args: RequestVoteArgs,
  9. ) -> RequestVoteReply {
  10. // Note: do not change this to `let _ = ...`.
  11. let _guard = self.daemon_env.for_scope();
  12. let mut rf = self.inner_state.lock();
  13. let term = rf.current_term;
  14. if args.prevote {
  15. let last_log = rf.log.last_index_term();
  16. let longer_log = args.last_log_term > last_log.term
  17. || (args.last_log_term == last_log.term
  18. && args.last_log_index >= last_log.index);
  19. return RequestVoteReply {
  20. term: args.term,
  21. vote_granted: args.term >= term && longer_log,
  22. };
  23. }
  24. #[allow(clippy::comparison_chain)]
  25. if args.term < term {
  26. return RequestVoteReply {
  27. term,
  28. vote_granted: false,
  29. };
  30. } else if args.term > term {
  31. rf.current_term = args.term;
  32. rf.voted_for = None;
  33. rf.state = State::Follower;
  34. self.election.reset_election_timer();
  35. self.persister.save_state(rf.persisted_state().into());
  36. }
  37. let voted_for = rf.voted_for;
  38. let last_log = rf.log.last_index_term();
  39. if (voted_for.is_none() || voted_for == Some(args.candidate_id))
  40. && (args.last_log_term > last_log.term
  41. || (args.last_log_term == last_log.term
  42. && args.last_log_index >= last_log.index))
  43. {
  44. rf.voted_for = Some(args.candidate_id);
  45. // It is possible that we have set a timer above when updating the
  46. // current term. It does not hurt to update the timer again.
  47. // We do need to persist, though.
  48. self.election.reset_election_timer();
  49. self.persister.save_state(rf.persisted_state().into());
  50. RequestVoteReply {
  51. term: args.term,
  52. vote_granted: true,
  53. }
  54. } else {
  55. RequestVoteReply {
  56. term: args.term,
  57. vote_granted: false,
  58. }
  59. }
  60. }
  61. }