pub struct RaftNode { /* private fields */ }Expand description
A Raft consensus node
Implementations§
Source§impl RaftNode
impl RaftNode
Sourcepub fn new(config: RaftConfig) -> RaftResult<Self>
pub fn new(config: RaftConfig) -> RaftResult<Self>
Create a new Raft node
Sourcepub fn with_persistence(
config: RaftConfig,
persistence: Arc<dyn RaftPersistence>,
) -> RaftResult<Self>
pub fn with_persistence( config: RaftConfig, persistence: Arc<dyn RaftPersistence>, ) -> RaftResult<Self>
Create a new Raft node with an explicit persistence backend.
Recovers state from the given persistence backend and uses it for all subsequent state and log mutations.
Sourcepub fn current_term(&self) -> Term
pub fn current_term(&self) -> Term
Get the current term
Sourcepub fn commit_index(&self) -> LogIndex
pub fn commit_index(&self) -> LogIndex
Get the commit index
Sourcepub fn last_log_index(&self) -> LogIndex
pub fn last_log_index(&self) -> LogIndex
Get the last log index
Sourcepub fn propose(&self, command: Command) -> RaftResult<LogIndex>
pub fn propose(&self, command: Command) -> RaftResult<LogIndex>
Append a command to the log (leader only)
Sourcepub fn is_recovering(&self) -> bool
pub fn is_recovering(&self) -> bool
Return true if the node is currently replaying its WAL on startup.
Sourcepub fn handle_request_vote(
&self,
req: RequestVoteRequest,
) -> RequestVoteResponse
pub fn handle_request_vote( &self, req: RequestVoteRequest, ) -> RequestVoteResponse
Handle a RequestVote RPC
Sourcepub fn handle_append_entries(
&self,
req: AppendEntriesRequest,
) -> AppendEntriesResponse
pub fn handle_append_entries( &self, req: AppendEntriesRequest, ) -> AppendEntriesResponse
Handle an AppendEntries RPC
Sourcepub fn start_election(&self) -> Vec<RequestVoteRequest>
pub fn start_election(&self) -> Vec<RequestVoteRequest>
Start an election (transition to candidate)
Sourcepub fn handle_vote_response(
&self,
from: NodeId,
resp: RequestVoteResponse,
) -> bool
pub fn handle_vote_response( &self, from: NodeId, resp: RequestVoteResponse, ) -> bool
Handle a vote response during election
Sourcepub fn issue_fencing_token(&self) -> Option<FencingToken>
pub fn issue_fencing_token(&self) -> Option<FencingToken>
Issue a new fencing token for the current leader term.
Returns None if the node is not the current leader.
Sourcepub fn validate_fencing_token(&self, token: &FencingToken) -> RaftResult<()>
pub fn validate_fencing_token(&self, token: &FencingToken) -> RaftResult<()>
Validate that token is not stale relative to the current Raft term.
Returns Ok(()) if the token’s term matches the current Raft term.
Returns Err(RaftError::StaleTerm) if the token predates the current term.
Sourcepub fn create_heartbeats(&self) -> Vec<(NodeId, AppendEntriesRequest)>
pub fn create_heartbeats(&self) -> Vec<(NodeId, AppendEntriesRequest)>
Create heartbeat messages for all peers
Sourcepub fn create_replication_requests(&self) -> Vec<(NodeId, AppendEntriesRequest)>
pub fn create_replication_requests(&self) -> Vec<(NodeId, AppendEntriesRequest)>
Create replication messages for all peers
Sourcepub fn replicate_to_followers(&self) -> Vec<(NodeId, AppendEntriesRequest)>
pub fn replicate_to_followers(&self) -> Vec<(NodeId, AppendEntriesRequest)>
Replicate log entries to all followers that need them.
This is a convenience method that combines create_replication_requests()
with the information the caller needs to actually send the RPCs.
Returns a list of (peer_id, request) pairs. If a follower is fully
caught up (its next_index > last_log_index), it is omitted – use
create_heartbeats() for idle keep-alive messages.
Typical usage in a replication loop:
let requests = leader.replicate_to_followers();
for (peer, req) in requests {
let resp = rpc_send(peer, req);
leader.handle_replication_response(peer, resp)?;
}Sourcepub fn create_replication_request_for(
&self,
peer: NodeId,
) -> Option<AppendEntriesRequest>
pub fn create_replication_request_for( &self, peer: NodeId, ) -> Option<AppendEntriesRequest>
Create an AppendEntries request for a specific follower.
Returns None if this node is not the leader, if the follower is
already fully caught up, or if leader state is unavailable.
Sourcepub fn handle_replication_response(
&self,
from: NodeId,
resp: AppendEntriesResponse,
) -> RaftResult<()>
pub fn handle_replication_response( &self, from: NodeId, resp: AppendEntriesResponse, ) -> RaftResult<()>
Handle a replication response
Sourcepub fn maybe_create_snapshot(
&self,
state_machine_data: Vec<u8>,
) -> RaftResult<bool>
pub fn maybe_create_snapshot( &self, state_machine_data: Vec<u8>, ) -> RaftResult<bool>
Attempt to create a snapshot if the log has grown past the threshold
Call this after advancing the commit index. If a snapshot is created, the log is compacted up to the snapshot point.
state_machine_data is the serialized state of the application state machine
at the current applied index.
Sourcepub fn auto_snapshot_if_needed<F>(
&self,
policy: &SnapshotPolicy,
state_machine_data_fn: F,
) -> RaftResult<bool>
pub fn auto_snapshot_if_needed<F>( &self, policy: &SnapshotPolicy, state_machine_data_fn: F, ) -> RaftResult<bool>
Automatically create a snapshot if the log has grown past the configured threshold.
Unlike maybe_create_snapshot, this method uses a SnapshotPolicy to decide
whether to snapshot and takes a closure that produces state machine data on demand
(avoiding the cost of serialization when no snapshot is needed).
Call this after applying committed entries.
Sourcepub fn handle_install_snapshot(
&self,
req: InstallSnapshotRequest,
) -> RaftResult<InstallSnapshotResponse>
pub fn handle_install_snapshot( &self, req: InstallSnapshotRequest, ) -> RaftResult<InstallSnapshotResponse>
Handle an InstallSnapshot RPC from the leader
Used when a follower is too far behind and the leader sends a snapshot instead of individual log entries.
Sourcepub fn prepare_install_snapshot(
&self,
target_peer: NodeId,
) -> RaftResult<Option<InstallSnapshotRequest>>
pub fn prepare_install_snapshot( &self, target_peer: NodeId, ) -> RaftResult<Option<InstallSnapshotRequest>>
Prepare an InstallSnapshot request for a follower that is too far behind
This is called by the leader when a follower’s next_index falls behind the snapshot point and log entries are no longer available.
Sourcepub fn follower_needs_snapshot(&self, peer: NodeId) -> bool
pub fn follower_needs_snapshot(&self, peer: NodeId) -> bool
Check if a follower needs a snapshot instead of normal log replication
Returns true if the follower’s next_index is at or before the snapshot point.
Sourcepub fn add_node(&self, node_id: NodeId, address: String) -> RaftResult<()>
pub fn add_node(&self, node_id: NodeId, address: String) -> RaftResult<()>
Add a node to the cluster via joint consensus.
If this node is the leader the change is proposed immediately. Returns an error if a membership change is already in progress or the node is already a member.
Sourcepub fn remove_node(&self, node_id: NodeId) -> RaftResult<()>
pub fn remove_node(&self, node_id: NodeId) -> RaftResult<()>
Remove a node from the cluster via joint consensus.
If the removed node is this node, it will step down after the configuration change commits.
Sourcepub fn cluster_members(&self) -> Vec<(NodeId, String)>
pub fn cluster_members(&self) -> Vec<(NodeId, String)>
Get the current list of cluster members as (node_id, address) pairs.
Sourcepub fn is_in_joint_consensus(&self) -> bool
pub fn is_in_joint_consensus(&self) -> bool
Check whether the cluster is currently in joint consensus.
Sourcepub fn membership_version(&self) -> u64
pub fn membership_version(&self) -> u64
Get the current membership configuration version.
Sourcepub fn propose_membership_change(
&self,
change: MembershipChange,
) -> RaftResult<()>
pub fn propose_membership_change( &self, change: MembershipChange, ) -> RaftResult<()>
Propose a membership change (leader only).
Implements the simplified Raft joint consensus protocol (Section 6):
- Leader creates joint config C_{old,new} and replicates it.
- Once C_{old,new} is committed the leader creates C_{new}.
- During the joint state, decisions require a majority of both the old and new configurations.
Sourcepub fn commit_membership_change(&self) -> RaftResult<()>
pub fn commit_membership_change(&self) -> RaftResult<()>
Commit the joint consensus transition: move from C_{old,new} to C_{new}.
Call this once the joint config entry has been committed (i.e. acknowledged by a quorum of both old and new configs).
Sourcepub fn has_quorum(&self, responding_nodes: &HashSet<NodeId>) -> bool
pub fn has_quorum(&self, responding_nodes: &HashSet<NodeId>) -> bool
Calculate whether a set of nodes forms a quorum under the current membership config (handles both stable and joint states).
Sourcepub fn is_stepping_down(&self) -> bool
pub fn is_stepping_down(&self) -> bool
Check if this node is stepping down (has been removed from the cluster).
Sourcepub fn election_timeout_elapsed(&self) -> bool
pub fn election_timeout_elapsed(&self) -> bool
Check if election timeout has elapsed
Sourcepub fn reset_election_timer(&self)
pub fn reset_election_timer(&self)
Reset election timer
Sourcepub fn get_leader_hint(&self) -> Option<NodeId>
pub fn get_leader_hint(&self) -> Option<NodeId>
Get a hint about the current leader (for client redirection)
Sourcepub fn trigger_failover_election(&self) -> Vec<RequestVoteRequest>
pub fn trigger_failover_election(&self) -> Vec<RequestVoteRequest>
Trigger a failover election if this node is a follower. Returns the vote requests to send to peers, or an empty vec if the node is not in follower state.