d_engine_core/election/mod.rs
1//! Raft leader election protocol implementation (Section 5.2)
2//!
3//! Handles leader election mechanics including:
4//! - Vote request broadcasting
5//! - Candidate vote collection
6//! - Voter eligibility validation
7mod election_handler;
8pub use election_handler::*;
9
10#[cfg(test)]
11mod election_handler_test;
12
13use std::sync::Arc;
14
15use d_engine_proto::server::election::VoteRequest;
16use d_engine_proto::server::election::VotedFor;
17#[cfg(any(test, feature = "test-utils"))]
18use mockall::automock;
19use tonic::async_trait;
20
21use crate::RaftNodeConfig;
22use crate::Result;
23use crate::TypeConfig;
24use crate::alias::MOF;
25use crate::alias::ROF;
26use crate::alias::TROF;
27
28/// State transition data for election outcomes
29#[derive(Debug)]
30pub struct StateUpdate {
31 /// Updated term if election term changed
32 pub term_update: Option<u64>,
33 /// New vote assignment if granted
34 pub new_voted_for: Option<VotedFor>,
35}
36
37#[cfg_attr(any(test, feature = "test-utils"), automock)]
38#[async_trait]
39pub trait ElectionCore<T>: Send + Sync + 'static
40where
41 T: TypeConfig,
42{
43 /// Sends vote requests to all voting members. Returns Ok() if majority
44 /// votes are received, otherwise returns Err. Initiates RPC calls via
45 /// transport and evaluates collected responses.
46 ///
47 /// A vote can be granted only if all the following conditions are met:
48 /// - The requests term is greater than the current_term.
49 /// - The candidates log is sufficiently up-to-date.
50 /// - The current node has not voted in the current term or has already
51 /// voted for the candidate.
52 async fn broadcast_vote_requests(
53 &self,
54 term: u64,
55 membership: Arc<MOF<T>>,
56 raft_log: &Arc<ROF<T>>,
57 transport: &Arc<TROF<T>>,
58 settings: &Arc<RaftNodeConfig>,
59 ) -> Result<()>;
60
61 /// Processes incoming vote requests: validates request legality via
62 /// check_vote_request_is_legal, updates node state if valid, triggers
63 /// role transition to Follower when granting vote.
64 ///
65 /// If there is a state update, we delegate the update to the parent
66 /// RoleState instead of updating it within this function.
67 async fn handle_vote_request(
68 &self,
69 request: VoteRequest,
70 current_term: u64,
71 voted_for_option: Option<VotedFor>,
72 raft_log: &Arc<ROF<T>>,
73 ) -> Result<StateUpdate>;
74
75 /// Validates vote request against Raft rules:
76 /// 1. Requester's term must be ≥ current term
77 /// 2. Requester's log must be at least as recent as local log
78 /// 3. Node hasn't voted for another candidate in current term
79 fn check_vote_request_is_legal(
80 &self,
81 request: &VoteRequest,
82 current_term: u64,
83 last_log_index: u64,
84 last_log_term: u64,
85 voted_for_option: Option<VotedFor>,
86 ) -> bool;
87}