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}