pub struct RaftLoop<A: CommitApplier, P: PlanExecutor = NoopPlanExecutor> { /* private fields */ }Expand description
Raft event loop coordinator.
Owns the MultiRaft state (behind Arc<Mutex>) and drives it via periodic
ticks. Implements crate::transport::RaftRpcHandler (in
super::handle_rpc) so it can be passed directly to
NexarTransport::serve for incoming RPC dispatch.
The F: RequestForwarder generic parameter was removed in C-δ.6 when the
SQL-string forwarding path was retired. Cross-node SQL routing now goes
through gateway.execute / ExecuteRequest (C-β path).
Implementations§
Source§impl<A: CommitApplier> RaftLoop<A>
impl<A: CommitApplier> RaftLoop<A>
pub fn new( multi_raft: MultiRaft, transport: Arc<NexarTransport>, topology: Arc<RwLock<ClusterTopology>>, applier: A, ) -> Self
Source§impl<A: CommitApplier, P: PlanExecutor> RaftLoop<A, P>
impl<A: CommitApplier, P: PlanExecutor> RaftLoop<A, P>
Sourcepub fn set_snapshot_quarantine_hook(
&mut self,
hook: Arc<dyn SnapshotQuarantineHook>,
)
pub fn set_snapshot_quarantine_hook( &mut self, hook: Arc<dyn SnapshotQuarantineHook>, )
Install the snapshot quarantine hook (mutable setter variant).
Prefer with_snapshot_quarantine_hook on the builder chain unless you
need to set the hook after construction.
Sourcepub fn with_plan_executor<P2: PlanExecutor>(
self,
executor: Arc<P2>,
) -> RaftLoop<A, P2>
pub fn with_plan_executor<P2: PlanExecutor>( self, executor: Arc<P2>, ) -> RaftLoop<A, P2>
Install a custom plan executor (for cluster mode — C-β path).
Sourcepub fn with_group_watchers(self, watchers: Arc<GroupAppliedWatchers>) -> Self
pub fn with_group_watchers(self, watchers: Arc<GroupAppliedWatchers>) -> Self
Replace the per-group apply watcher registry.
The host crate calls this with the same Arc it stores on
SharedState so proposers and consistent-read paths share
one registry with the tick loop’s bump points. Defaults to a
fresh empty registry when not set.
Sourcepub fn with_snapshot_quarantine_hook(
self,
hook: Arc<dyn SnapshotQuarantineHook>,
) -> Self
pub fn with_snapshot_quarantine_hook( self, hook: Arc<dyn SnapshotQuarantineHook>, ) -> Self
Attach the snapshot quarantine hook (builder chain variant).
The supplied implementation is called by the InstallSnapshotRequest
handler to check for, record, and short-circuit quarantined chunks.
Sourcepub fn with_data_dir(self, data_dir: PathBuf) -> Self
pub fn with_data_dir(self, data_dir: PathBuf) -> Self
Set the data directory for partial-snapshot persistence and GC.
When set, the InstallSnapshotRequest handler writes chunks to
<data_dir>/recv_snapshots/<group_id>.partial and the GC sweeper
removes stale partials on startup. When None (the default, used by
unit tests), disk writes are skipped — the receiver operates in-memory
only with empty chunk data.
Sourcepub fn with_snapshot_chunk_bytes(self, chunk_bytes: u64) -> Self
pub fn with_snapshot_chunk_bytes(self, chunk_bytes: u64) -> Self
Override the snapshot chunk byte size (default: 4 MiB).
Sourcepub fn with_orphan_partial_max_age_secs(self, secs: u64) -> Self
pub fn with_orphan_partial_max_age_secs(self, secs: u64) -> Self
Override the orphan-partial max age for the GC sweeper (default: 300 s).
Sourcepub fn group_watchers(&self) -> Arc<GroupAppliedWatchers> ⓘ
pub fn group_watchers(&self) -> Arc<GroupAppliedWatchers> ⓘ
Shared handle to the per-group apply watcher registry.
Sourcepub fn loop_metrics(&self) -> Arc<LoopMetrics> ⓘ
pub fn loop_metrics(&self) -> Arc<LoopMetrics> ⓘ
Shared handle to this loop’s standardized metrics.
Sourcepub fn pending_groups(&self) -> usize
pub fn pending_groups(&self) -> usize
Count of Raft groups currently mounted on this node — used to
render the raft_tick_loop_pending_groups gauge.
Sourcepub fn begin_shutdown(&self)
pub fn begin_shutdown(&self)
Signal cooperative shutdown to every detached task spawned
inside [super::tick::do_tick].
This is the entry point for test harnesses that want to
tear down a RaftLoop without waiting for the external
run() shutdown watch channel to propagate. In production
the same signal is emitted automatically by run() when
its external shutdown receiver fires.
Idempotent: calling this multiple times is a no-op after the first.
Sourcepub fn subscribe_ready(&self) -> Receiver<bool>
pub fn subscribe_ready(&self) -> Receiver<bool>
Subscribe to the boot-time readiness signal.
The returned receiver starts at false and flips to true
exactly once, after the first [super::tick::do_tick]
completes phase 4 (apply committed entries). Used by the
host crate to gate client-facing listener startup until the
metadata raft group has produced its first applied entry.
Sourcepub fn with_vshard_handler(self, handler: VShardEnvelopeHandler) -> Self
pub fn with_vshard_handler(self, handler: VShardEnvelopeHandler) -> Self
Set a handler for incoming VShardEnvelope messages.
Sourcepub fn with_metadata_applier(self, applier: Arc<dyn MetadataApplier>) -> Self
pub fn with_metadata_applier(self, applier: Arc<dyn MetadataApplier>) -> Self
Install the metadata applier used for group-0 commits.
The host crate (nodedb) calls this with a production applier that
wraps an in-memory MetadataCache and additionally persists to
redb / broadcasts catalog change events. The default
NoopMetadataApplier is kept only for tests that don’t care.
pub fn with_tick_interval(self, interval: Duration) -> Self
Sourcepub fn with_catalog(self, catalog: Arc<ClusterCatalog>) -> Self
pub fn with_catalog(self, catalog: Arc<ClusterCatalog>) -> Self
Attach a cluster catalog — used by the join flow to persist the updated topology + routing after a conf-change commits.
Sourcepub async fn run(&self, shutdown: Receiver<bool>)
pub async fn run(&self, shutdown: Receiver<bool>)
Run the event loop until shutdown.
This drives Raft elections, heartbeats, and message dispatch.
Call NexarTransport::serve separately with Arc<Self> as the handler.
When the externally-supplied shutdown receiver fires,
the loop also propagates the signal to the internal
cooperative-shutdown channel so every detached task
spawned inside do_tick exits promptly and drops its
Arc<Mutex<MultiRaft>> clone.
Sourcepub fn multi_raft_handle(&self) -> Arc<Mutex<MultiRaft>> ⓘ
pub fn multi_raft_handle(&self) -> Arc<Mutex<MultiRaft>> ⓘ
Returns the inner multi-raft handle. Exposed for tests and for the host crate’s metadata proposer so it can hold a second reference to the same underlying mutex without pulling the whole raft loop into the caller’s lifetime.
Sourcepub fn group_statuses(&self) -> Vec<GroupStatus>
pub fn group_statuses(&self) -> Vec<GroupStatus>
Snapshot all Raft group states for observability (SHOW RAFT GROUPS).
Source§impl<A: CommitApplier, P: PlanExecutor> RaftLoop<A, P>
impl<A: CommitApplier, P: PlanExecutor> RaftLoop<A, P>
Sourcepub fn propose(&self, vshard_id: u32, data: Vec<u8>) -> Result<(u64, u64)>
pub fn propose(&self, vshard_id: u32, data: Vec<u8>) -> Result<(u64, u64)>
Propose a command to the Raft group owning the given vShard.
Returns (group_id, log_index) on success.
Sourcepub fn propose_to_metadata_group(&self, data: Vec<u8>) -> Result<u64>
pub fn propose_to_metadata_group(&self, data: Vec<u8>) -> Result<u64>
Propose a command directly to the metadata Raft group (group 0).
Used by the host crate’s metadata proposer and by integration
tests that exercise the replicated-catalog path without a
pgwire client. Fails with ClusterError::GroupNotFound if
group 0 does not exist on this node, and with
ClusterError::Raft(NotLeader) if this node is not the
current leader of group 0.
Sourcepub async fn propose_to_metadata_group_via_leader(
&self,
data: Vec<u8>,
) -> Result<u64>
pub async fn propose_to_metadata_group_via_leader( &self, data: Vec<u8>, ) -> Result<u64>
Propose to the metadata Raft group, transparently forwarding to the current leader if this node is not it.
Tries a local propose first. On
ClusterError::Raft(NotLeader { leader_hint }), looks up the
hinted leader’s address in cluster topology and sends a
crate::rpc_codec::MetadataProposeRequest over QUIC. The
receiving leader applies the proposal locally and returns
the log index.
On NotLeader { leader_hint: None } (election in progress,
no observed leader yet) the call returns the original
NotLeader error so the caller can decide whether to retry.
We deliberately do not implement a wait-and-retry loop here
because the caller (the host-side proposer) may have a
shorter deadline than any reasonable retry budget.
The leader-side path through this function is identical to
the bare propose_to_metadata_group — the only extra cost is
an is_leader_locally check before the local propose.
Sourcepub async fn propose_via_data_leader(
&self,
vshard_id: u32,
data: Vec<u8>,
) -> Result<(u64, u64)>
pub async fn propose_via_data_leader( &self, vshard_id: u32, data: Vec<u8>, ) -> Result<(u64, u64)>
Propose a command to the data Raft group owning the given vShard, transparently forwarding to the group leader if this node is not it.
Tries a local propose first. On NotLeader { leader_hint: Some(id) },
looks up the hinted leader’s address in the cluster topology and sends
a DataProposeRequest over QUIC. The receiving leader applies the
proposal locally and returns (group_id, log_index).
On NotLeader { leader_hint: None } (election in progress) the call
returns the original NotLeader error so the caller can retry.
Sourcepub fn propose_conf_change(
&self,
group_id: u64,
change: &ConfChange,
) -> Result<(u64, u64)>
pub fn propose_conf_change( &self, group_id: u64, change: &ConfChange, ) -> Result<(u64, u64)>
Propose a configuration change to a Raft group.
Returns (group_id, log_index) on success.
Trait Implementations§
Source§impl<A, P> GroupStatusProvider for RaftLoop<A, P>where
A: CommitApplier,
P: PlanExecutor,
impl<A, P> GroupStatusProvider for RaftLoop<A, P>where
A: CommitApplier,
P: PlanExecutor,
Source§fn group_statuses(&self) -> Vec<GroupStatus>
fn group_statuses(&self) -> Vec<GroupStatus>
Source§impl<A: CommitApplier, P: PlanExecutor> RaftRpcHandler for RaftLoop<A, P>
impl<A: CommitApplier, P: PlanExecutor> RaftRpcHandler for RaftLoop<A, P>
Auto Trait Implementations§
impl<A, P = NoopPlanExecutor> !Freeze for RaftLoop<A, P>
impl<A, P = NoopPlanExecutor> !RefUnwindSafe for RaftLoop<A, P>
impl<A, P> Send for RaftLoop<A, P>
impl<A, P> Sync for RaftLoop<A, P>
impl<A, P> Unpin for RaftLoop<A, P>where
A: Unpin,
impl<A, P> UnsafeUnpin for RaftLoop<A, P>where
A: UnsafeUnpin,
impl<A, P = NoopPlanExecutor> !UnwindSafe for RaftLoop<A, P>
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.