pub struct CascadeRelay { /* private fields */ }Expand description
Tracks the sub-replica slots an intermediate holds and the frontiers that must propagate through the chain. Pure bookkeeping — the forwarding transport calls into it to decide what to send and what to advertise upstream.
All LSN updates are monotonic: a stale ack or a duplicate forward can never rewind a frontier, which keeps retention safe under reordering and retries.
Implementations§
Source§impl CascadeRelay
impl CascadeRelay
pub fn new(node_id: impl Into<String>) -> Self
pub fn node_id(&self) -> &str
Sourcepub fn record_self_applied(&mut self, lsn: u64)
pub fn record_self_applied(&mut self, lsn: u64)
Record how far this intermediate has applied from its own upstream. Monotonic — a late report never rewinds the forward bound.
pub fn self_applied_lsn(&self) -> u64
Sourcepub fn register_downstream(
&mut self,
id: impl Into<String>,
start_lsn: u64,
) -> u64
pub fn register_downstream( &mut self, id: impl Into<String>, start_lsn: u64, ) -> u64
Hold a sub-replica’s slot, resuming it at start_lsn.
Idempotent on reconnect (issue #812 semantics): if the slot already
exists its progress is preserved — only a forward start_lsn can
advance confirmed_lsn, never rewind it — so a reconnecting
sub-replica is not pushed backwards. Returns the LSN the sub-replica
should resume streaming from (its retained confirmed position).
Sourcepub fn unregister_downstream(&mut self, id: &str) -> bool
pub fn unregister_downstream(&mut self, id: &str) -> bool
Release a sub-replica’s slot. Returns true if it was held. After
this, the released sub-replica no longer pins the chain’s retention
frontier.
Sourcepub fn record_downstream_ack(&mut self, id: &str, lsn: u64)
pub fn record_downstream_ack(&mut self, id: &str, lsn: u64)
Record a sub-replica’s confirmation that it has durably applied up to
lsn. Monotonic. No-op for an unknown id.
Sourcepub fn note_forwarded(&mut self, id: &str, lsn: u64)
pub fn note_forwarded(&mut self, id: &str, lsn: u64)
Note that records up to lsn were forwarded to a sub-replica.
Monotonic. No-op for an unknown id.
pub fn downstream_ids(&self) -> Vec<String>
pub fn downstream_slot(&self, id: &str) -> Option<&DownstreamSlot>
pub fn downstream_count(&self) -> usize
Sourcepub fn upstream_confirmed_lsn(&self) -> u64
pub fn upstream_confirmed_lsn(&self) -> u64
The retention frontier this intermediate reports to its own upstream (the primary, or a further intermediate).
This is the crux of chain correctness: it is the minimum of what the intermediate has itself applied and what every sub-replica has confirmed. The upstream retains WAL at or above this point, so a slow leaf keeps the whole chain’s slot open — the primary never prunes a record some downstream node still needs.
With no sub-replicas the frontier is simply the intermediate’s own applied position (it behaves like an ordinary direct replica).
Sourcepub fn upstream_confirmed_bookmark(&self, term: u64) -> CausalBookmark
pub fn upstream_confirmed_bookmark(&self, term: u64) -> CausalBookmark
The retention frontier as a causal bookmark, stamped with term.
Lets the chain advertise its safe-to-prune point in the same token
vocabulary causal reads use (ADR 0031).
Sourcepub fn downstream_visible_frontier(&self, id: &str) -> Option<u64>
pub fn downstream_visible_frontier(&self, id: &str) -> Option<u64>
The highest LSN a given sub-replica can currently serve for a causal
read — the minimum of the intermediate’s applied frontier and the
sub-replica’s own confirmed position. Down the chain this is
monotonically non-increasing, so a bookmark read routes to a node only
if that node’s visible frontier covers the bookmark’s commit_lsn.
Returns None for an unknown sub-replica.
Sourcepub fn downstream_can_serve(&self, id: &str, bookmark: &CausalBookmark) -> bool
pub fn downstream_can_serve(&self, id: &str, bookmark: &CausalBookmark) -> bool
Whether a sub-replica can satisfy a read at bookmark. True only when
its visible frontier covers the bookmark’s commit LSN.
Sourcepub fn records_to_forward<'a, T>(
&self,
requested_since_lsn: u64,
available: &'a [(u64, T)],
) -> Vec<&'a (u64, T)>
pub fn records_to_forward<'a, T>( &self, requested_since_lsn: u64, available: &'a [(u64, T)], ) -> Vec<&'a (u64, T)>
Select the records to forward to a sub-replica from a batch the intermediate has on hand.
available is a slice of (lsn, payload) the intermediate has
received from its own upstream, assumed ascending by LSN. The result
keeps every record with requested_since_lsn < lsn <= self_applied_lsn
— newer than what the sub-replica has, and not beyond what the
intermediate itself holds. Records the intermediate has buffered but
not yet applied are withheld, so a sub-replica never sees data ahead of
its feeder.
Trait Implementations§
Source§impl Clone for CascadeRelay
impl Clone for CascadeRelay
Source§fn clone(&self) -> CascadeRelay
fn clone(&self) -> CascadeRelay
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for CascadeRelay
impl RefUnwindSafe for CascadeRelay
impl Send for CascadeRelay
impl Sync for CascadeRelay
impl Unpin for CascadeRelay
impl UnsafeUnpin for CascadeRelay
impl UnwindSafe for CascadeRelay
Blanket Implementations§
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<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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request