struct Shared {
subscribers: Vec<Registration>,
sequences: HashMap<SessionSlot, u64>,
rings: HashMap<SessionSlot, VecDeque<Kept>>,
ring_bytes: HashMap<SessionSlot, usize>,
unringed: HashMap<SessionSlot, VecDeque<u64>>,
sealed_with_rows: HashSet<SessionSlot>,
ring_cap: usize,
ring_cap_bytes: usize,
}Fields§
§subscribers: Vec<Registration>§sequences: HashMap<SessionSlot, u64>Where each seat’s stream has got to: the number its newest frame was minted under. Absent for a seat that has not emitted yet, and for one whose last frame opened a new epoch.
Per seat, keyed by the frame’s own slot, so a frame for one seat can neither advance another’s counter nor leave a hole in it.
rings: HashMap<SessionSlot, VecDeque<Kept>>The newest frames each seat’s stream has emitted, oldest first, for a client that read a gap in the numbers and asks for what it missed.
Held here rather than on the session task because here is where every frame of the seat crosses, whichever site emitted it - and the number a repair hands back is the one minted here.
ring_bytes: HashMap<SessionSlot, usize>What each seat’s ring weighs, beside the frames themselves, so the byte ceiling is a running total rather than a walk of the ring.
unringed: HashMap<SessionSlot, VecDeque<u64>>The numbers each seat has minted that the ring does NOT hold: the frames that close an epoch. A reader measuring whether a copy covers a stretch needs them, because a window can never serve them and a gap holding only one of them costs the copy nothing.
Per epoch, not per seat. An occupant change mints from 1 again, so the numbers a seal’s epoch carried are re-minted by the run after it - and the record of them goes with the ring. Bounded to a ring’s frame count: a number older than that lies beyond any window a fill could serve, where the count it underwrites is a refusal rather than a hole.
sealed_with_rows: HashSet<SessionSlot>The seats whose latest epoch-opening seal carried rows.
A seal’s history is not in the ring, so a reader filling a copy from the window cannot rebuild what the epoch opened on (#2446). An empty-history seal opens its epoch with nothing to miss, so each mint REPLACES this rather than adding to it. The value standing between an occupant change and its seal’s mint is the previous seal’s, which is what notices that gap.
ring_cap: usizeHow many frames a ring keeps. SEAT_RING in production; a test
drives it down so the transcript fallback is reachable without
emitting thousands of frames.
ring_cap_bytes: usizeHow many bytes a ring keeps. SEAT_RING_BYTES in production; a test
drives it down so the ceiling is reachable without a giant tree.
Implementations§
Sourcefn numbered(&mut self, update: SessionUpdate, charge: usize) -> SeatUpdate
fn numbered(&mut self, update: SessionUpdate, charge: usize) -> SeatUpdate
Number update on its seat’s counter, or leave it unnumbered when it
belongs to no seat.
An occupant change closes its epoch. Connected and
SessionReplaced are numbered on the run they end and the seat’s
counter starts over, so the frame after one opens the new epoch at 1:
the client learns the occupant from that frame itself and wipes to
expect 1, never a gap.
One lock serializes numbering and delivery. UpdateFanout::deliver
mints and fans out under the same guard, so the numbers a seat’s
subscribers receive are in the order they were minted. Lifting the mint
out of that guard - or fanning out around it - reorders a seat’s stream
against its own numbers.
Sourcefn frames_between(
&self,
slot: &SessionSlot,
from: u64,
to: u64,
) -> Vec<SeatUpdate>
fn frames_between( &self, slot: &SessionSlot, from: u64, to: u64, ) -> Vec<SeatUpdate>
The frames of slot’s ring that carry the numbers in from..=to,
oldest first.
Sourcefn oldest_kept(&self, slot: &SessionSlot) -> Option<u64>
fn oldest_kept(&self, slot: &SessionSlot) -> Option<u64>
The oldest number slot’s ring still holds, None for a seat that
has emitted nothing.
Sourcefn unringed_between(&self, slot: &SessionSlot, from: u64, to: u64) -> u64
fn unringed_between(&self, slot: &SessionSlot, from: u64, to: u64) -> u64
How many of the numbers in from..=to on slot’s stream the ring
holds no frame for.
Sourcefn next_seq(&self, slot: &SessionSlot) -> u64
fn next_seq(&self, slot: &SessionSlot) -> u64
The number slot’s next frame will be minted under.
A seat that has emitted nothing - and one whose last frame opened a new epoch - is at 1, so this never answers 0: a client reads it as the number to expect, and 0 would have it expect a frame that cannot exist.
Sourcefn epoch_opened_with_rows(&self, slot: &SessionSlot) -> bool
fn epoch_opened_with_rows(&self, slot: &SessionSlot) -> bool
Whether slot’s latest epoch-opening seal carried rows.
Trait Implementations§
Auto Trait Implementations§
Blanket Implementations§
§impl<T> AnySync for T
impl<T> AnySync for T
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> 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 more