pub struct RaftNode { /* private fields */ }Expand description
A single Raft participant: a deterministic, I/O-free state machine.
Implementations§
Source§impl RaftNode
impl RaftNode
Sourcepub fn new(
id: NodeId,
members: impl IntoIterator<Item = NodeId>,
config: Config,
) -> Self
pub fn new( id: NodeId, members: impl IntoIterator<Item = NodeId>, config: Config, ) -> Self
Create a node whose initial voting set is members (including id).
Sourcepub fn with_membership(
id: NodeId,
membership: Membership,
config: Config,
) -> Self
pub fn with_membership( id: NodeId, membership: Membership, config: Config, ) -> Self
Create a node with an explicit initial Membership (voters +
learners), used to bootstrap clusters that grow from a subset.
Sourcepub fn restore(
id: NodeId,
members: impl IntoIterator<Item = NodeId>,
config: Config,
term: Term,
voted_for: Option<NodeId>,
entries: impl IntoIterator<Item = LogEntry>,
) -> Self
pub fn restore( id: NodeId, members: impl IntoIterator<Item = NodeId>, config: Config, term: Term, voted_for: Option<NodeId>, entries: impl IntoIterator<Item = LogEntry>, ) -> Self
Rebuild a node from durably persisted state after a restart (backlog
B4). term/voted_for come from the stored HardState and entries
are the stored log (ascending, contiguous from index 1 — no snapshot
support yet). The node comes back as a Follower with
commit_index/last_applied at 0: it re-learns its commit index from
the current leader (or re-derives it after winning an election) and the
application state machine is rebuilt by replaying the recovered log.
members is the bootstrap voter set, used only when the recovered log
carries no membership entry (a cluster that never reconfigured).
Sourcepub fn restore_with_snapshot(
id: NodeId,
members: impl IntoIterator<Item = NodeId>,
config: Config,
term: Term,
voted_for: Option<NodeId>,
snapshot: SnapshotState,
entries: impl IntoIterator<Item = LogEntry>,
) -> Self
pub fn restore_with_snapshot( id: NodeId, members: impl IntoIterator<Item = NodeId>, config: Config, term: Term, voted_for: Option<NodeId>, snapshot: SnapshotState, entries: impl IntoIterator<Item = LogEntry>, ) -> Self
Rebuild a node from a durable snapshot plus the live log suffix after a
restart (backlog A6). Used when the stored log was compacted: snapshot
summarizes everything through snapshot.last_included, and entries are
the remaining log entries (indices strictly greater than the boundary,
ascending and contiguous).
The application state machine must be restored from snapshot.data
before the node is driven; the node comes back as a
Follower with commit_index/last_applied at the
snapshot boundary (which is durably committed), then re-learns any higher
commit index from the current leader and replays the suffix.
Sourcepub fn current_term(&self) -> Term
pub fn current_term(&self) -> Term
Current term.
Sourcepub fn commit_index(&self) -> LogIndex
pub fn commit_index(&self) -> LogIndex
Highest committed index.
Sourcepub fn last_applied(&self) -> LogIndex
pub fn last_applied(&self) -> LogIndex
Highest applied index.
Sourcepub fn last_log_index(&self) -> LogIndex
pub fn last_log_index(&self) -> LogIndex
Index of the last log entry.
Sourcepub fn term_at(&self, idx: LogIndex) -> Option<Term>
pub fn term_at(&self, idx: LogIndex) -> Option<Term>
Term stored at idx, if present (for tests/introspection).
Sourcepub fn committed_membership(&self) -> Membership
pub fn committed_membership(&self) -> Membership
The committed membership as a wire Membership value.
Sourcepub fn snapshot_index(&self) -> LogIndex
pub fn snapshot_index(&self) -> LogIndex
Highest index covered by this node’s snapshot (0 if none).
Sourcepub fn compactable_entries(&self) -> u64
pub fn compactable_entries(&self) -> u64
Applied entries not yet compacted into a snapshot.
Sourcepub fn compactable_log_bytes(&self) -> u64
pub fn compactable_log_bytes(&self) -> u64
Estimated byte size of applied log entries not yet compacted.
Sourcepub fn stored_snapshot(&self) -> Option<SnapshotState>
pub fn stored_snapshot(&self) -> Option<SnapshotState>
The most recent snapshot this node holds (its boundary, configuration,
and application bytes), or None if nothing has been compacted or
installed. A runtime persists this via a SnapshotStore after a
compact or a leader-shipped install so it survives
a restart (backlog A6).
Sourcepub fn log_entries_from(&self, from: LogIndex) -> Vec<LogEntry>
pub fn log_entries_from(&self, from: LogIndex) -> Vec<LogEntry>
Live log entries from from through the last index (inclusive).
Sourcepub fn is_joint(&self) -> bool
pub fn is_joint(&self) -> bool
Whether the active configuration is a joint (transitional) config.
Sourcepub fn take_outputs(&mut self) -> Vec<Output>
pub fn take_outputs(&mut self) -> Vec<Output>
Drain accumulated effects. The runtime calls this after every event.
Sourcepub fn take_persist(&mut self) -> Option<Persist>
pub fn take_persist(&mut self) -> Option<Persist>
Take the durable state delta accumulated since the previous call, or
None if neither the hard state nor the log changed (backlog B4). The
runtime persists the returned Persist before dispatching any
Output from take_outputs for the same
step, so a follower never ack’s an entry it has not fsync’d and a node
never reveals a vote it has not recorded (Raft §5.1–§5.3).
Sourcepub fn campaign(&mut self)
pub fn campaign(&mut self)
Force a real election immediately, skipping the pre-vote round (used for tests and leadership transfer, which bypass pre-vote by design).
Sourcepub fn receive_reply(&mut self, from: NodeId, reply: RaftRpcReply)
pub fn receive_reply(&mut self, from: NodeId, reply: RaftRpcReply)
Handle an inbound reply RPC from from.
Sourcepub fn propose(&mut self, command: Vec<u8>) -> Result<LogIndex, NotLeader>
pub fn propose(&mut self, command: Vec<u8>) -> Result<LogIndex, NotLeader>
Propose a new command. Succeeds only on the leader; effects (log append
and replication) are drained via RaftNode::take_outputs.
§Errors
Returns NotLeader with a redirect hint if this node is not leader.
Sourcepub fn read_index(&mut self, id: ReadId) -> Result<(), NotLeader>
pub fn read_index(&mut self, id: ReadId) -> Result<(), NotLeader>
Request a linearizable read (ReadIndex, read-consistency). The leader captures
its commit index and confirms it still leads by a heartbeat round to a
quorum; once confirmed and applied, an Output::ReadReady is emitted.
If leadership is lost first, an Output::ReadFailed is emitted.
§Errors
Returns NotLeader with a redirect hint if this node is not leader.
Sourcepub fn compact(&mut self, up_to: LogIndex, data: Vec<u8>) -> bool
pub fn compact(&mut self, up_to: LogIndex, data: Vec<u8>) -> bool
Compact the log up to and including up_to, replacing that prefix with
a snapshot whose application state is data (Raft §7). The runtime
supplies data from its state machine after applying through up_to.
Returns false if up_to is not a compactable applied index
(snapshot_index < up_to <= last_applied).
Sourcepub fn propose_membership(
&mut self,
new_voters: impl IntoIterator<Item = NodeId>,
learners: impl IntoIterator<Item = NodeId>,
) -> Result<LogIndex, MembershipError>
pub fn propose_membership( &mut self, new_voters: impl IntoIterator<Item = NodeId>, learners: impl IntoIterator<Item = NodeId>, ) -> Result<LogIndex, MembershipError>
Begin a joint-consensus membership change to new_voters (+ optional
learners). Only the leader may call this, and only when no other
change is in flight (membership-early).
§Errors
Returns MembershipError if not leader, a change is in progress, or
the new voter set is empty.
Sourcepub fn propose_catalog(
&mut self,
command: CatalogCommand,
) -> Result<LogIndex, CatalogProposeError>
pub fn propose_catalog( &mut self, command: CatalogCommand, ) -> Result<LogIndex, CatalogProposeError>
Append a catalog metadata entry to the log (group 0 only, Tier 2).
§Errors
Returns CatalogProposeError::NotLeader when this node is not leader.
Sourcepub fn propose_saga_journal(
&mut self,
command: SagaJournalCommand,
) -> Result<LogIndex, CatalogProposeError>
pub fn propose_saga_journal( &mut self, command: SagaJournalCommand, ) -> Result<LogIndex, CatalogProposeError>
Append a saga journal metadata entry to the log (group 0 only, Tier 2 v2).
§Errors
Returns CatalogProposeError::NotLeader when this node is not leader.
Sourcepub fn propose_two_phase_prepare(
&mut self,
command: TwoPhasePrepareCommand,
) -> Result<LogIndex, CatalogProposeError>
pub fn propose_two_phase_prepare( &mut self, command: TwoPhasePrepareCommand, ) -> Result<LogIndex, CatalogProposeError>
Append a durable 2PC prepare entry to the log (any Raft group leader).
§Errors
Returns CatalogProposeError::NotLeader when this node is not leader.
Sourcepub fn propose_two_phase_abort(
&mut self,
command: TwoPhaseAbortCommand,
) -> Result<LogIndex, CatalogProposeError>
pub fn propose_two_phase_abort( &mut self, command: TwoPhaseAbortCommand, ) -> Result<LogIndex, CatalogProposeError>
Append a durable 2PC abort entry to the log (any Raft group leader).
§Errors
Returns CatalogProposeError::NotLeader when this node is not leader.
Sourcepub fn propose_two_phase_journal(
&mut self,
command: TwoPhaseJournalCommand,
) -> Result<LogIndex, CatalogProposeError>
pub fn propose_two_phase_journal( &mut self, command: TwoPhaseJournalCommand, ) -> Result<LogIndex, CatalogProposeError>
Append a 2PC client journal metadata entry to the log (group 0 / Meta-Raft).
§Errors
Returns CatalogProposeError::NotLeader when this node is not leader.
Sourcepub fn propose_queue_autoscale_policy(
&mut self,
command: QueueAutoscalePolicyCommand,
) -> Result<LogIndex, CatalogProposeError>
pub fn propose_queue_autoscale_policy( &mut self, command: QueueAutoscalePolicyCommand, ) -> Result<LogIndex, CatalogProposeError>
Append a queue autoscale policy metadata entry to the log (Meta-Raft / group 0).
§Errors
Returns CatalogProposeError::NotLeader when this node is not leader.
Sourcepub fn lease_valid(&self) -> bool
pub fn lease_valid(&self) -> bool
Whether this node currently holds a valid leadership lease (leader, and within the lease window). Observability / test hook.
Sourcepub fn lease_read(&self) -> Result<Option<LogIndex>, NotLeader>
pub fn lease_read(&self) -> Result<Option<LogIndex>, NotLeader>
Attempt a lease read (read-consistency): if this leader holds a valid lease and
has committed an entry in its current term, return Ok(Some(index)) — the
read may be served by running query once the state machine has applied
through index, with no ReadIndex round-trip. Returns Ok(None) when
no valid lease is held (the caller should fall back to
read_index).
§Errors
Returns NotLeader with a redirect hint if this node is not the leader.
Sourcepub fn reachable(&self, window: u64) -> Vec<NodeId>
pub fn reachable(&self, window: u64) -> Vec<NodeId>
The voters this node currently considers reachable — a liveness signal distinct from committed membership (liveness-vs-membership).
On the leader this is itself plus every voter that acked an
AppendEntries within the last window logical ticks; a voter silent for
longer is treated as crashed/partitioned even though it is still a
committed voter. A non-leader has no first-hand ack data, so it
conservatively reports the full voter set and leaves crash detection to
the leader (which is where reconcile runs anyway, supervisor-leader).
window should comfortably exceed the heartbeat interval so a healthy
follower is never flagged; reachable_now applies
a sensible default derived from the election timeout.