Skip to main content

Conversations

Struct Conversations 

Source
pub struct Conversations {
    held: Mutex<HashMap<SessionSlot, Arc<Held>>>,
    seeded: Notify,
    consumed: Mutex<HashMap<SessionSlot, Sender<u64>>>,
    fills: Mutex<HashMap<SessionSlot, Arc<Mutex<()>>>>,
    fold_held: AtomicBool,
    seed_hold: Mutex<Option<Arc<SeedHold>>>,
}
Expand description

The conversations the transport is holding, one per seat it has heard of.

Every live seat, not only the watched ones, and no seat is let go. A conversation has no read behind it any more, so releasing one is not a bound - nothing could rebuild it, and the next ask for that seat would have no answer. What it holds is therefore proportional to what is RUNNING plus the sleeping seats someone has opened: a sleeping seat’s copy is seeded from its transcript and kept, which is what makes the read land before any spawn. What one seat costs is the window the ceilings keep rather than its transcript, and the window is the bound.

Fields§

§held: Mutex<HashMap<SessionSlot, Arc<Held>>>§seeded: Notify

Fires when a seat’s copy is first held or reseeded, so a read waiting for it to become current knows it moved.

§consumed: Mutex<HashMap<SessionSlot, Sender<u64>>>

The newest number the fold loop has consumed for each seat, in a watch so an encode can wait on it.

What an answer’s copy is measured against. A subscribe’s answer carries the number its seat’s stream will continue from, and every frame numbered below that must be inside the copy it carries - because the client adopts seq - 1 and treats a later delivery of anything at or below it as already drawn. The copy is filled by the fold loop, which consumes the fanout in a task of its own, so “the frame was emitted before the counter was read” does not yet mean “the copy has it”: this is where that is known.

§fills: Mutex<HashMap<SessionSlot, Arc<Mutex<()>>>>

The lock a seat’s fill runs under.

What makes “applied once” a fact rather than a hope. The fold loop and an encode’s catch-up can both apply the same frames, and the watermark between them is read and written by both; the lock spans each side’s check, applies and mark, so a frame crosses exactly once whichever path got there first.

§fold_held: AtomicBool

A test’s hold on the fold loop, so the window above can be driven rather than raced: while it is set, the loop does not consume.

§seed_hold: Mutex<Option<Arc<SeedHold>>>

A test’s hold on the next transcript seed, so a stream copy that lands inside the seed’s window is driven rather than raced.

Implementations§

Source§

impl Conversations

Source

pub fn new() -> Self

Source

pub fn consumed_for(&self, slot: &SessionSlot) -> u64

The newest number the fold loop has consumed for slot.

Source

pub fn consumed(&self, slot: &SessionSlot, seq: u64)

Say the fold loop has consumed seq for slot.

send_replace, not send. The watch is created with its receiver dropped, so consumed_for can read the watermark with nobody waiting - and send is a no-op when a channel has no receivers, which would leave the watermark at 0 forever and make every read of it wrong.

Source

pub async fn await_consumed( &self, slot: &SessionSlot, want: u64, within: Duration, ) -> bool

Wait, up to within, for the fold to have consumed want for slot, answering whether it did.

Bounded, because the caller has a fallback and a stuck fold must not become a stall: the caller fills the gap from the seat’s own window and refuses only if that cannot reach either.

Source

pub fn fill_lock(&self, slot: &SessionSlot) -> Arc<Mutex<()>> ⓘ

The lock one seat’s fill runs under: taken by the fold loop and by an encode’s catch-up, so their watermark checks and applies cannot interleave.

Source

pub fn hold_the_fold(&self, held: bool)

Hold the fold loop, or let it go. Test-only: it is the seam that makes the copy’s lag deterministic instead of a race.

Source

pub fn fold_is_held(&self) -> bool

Whether a test is holding the fold loop.

Source

pub fn hold_the_seed(&self, hold: Arc<SeedHold>)

Hold the next transcript seed before its read, so a test can land the seat’s own copy inside that window. Test-only.

Source

pub async fn pass_the_seed_hold(&self)

Park at a test’s seed hold, when one is set: say it has arrived, then wait to be let go.

Source

pub fn get(&self, slot: &SessionSlot) -> Option<Arc<Held>>

The seat’s conversation if one is held.

Source

pub fn live_of(&self, slot: &SessionSlot) -> bool

Whether the seat’s turn is in flight right now, from its own frames.

false for a seat this transport has not heard of: nothing holds a turn there, and a reader folding its transcript is reading a settled conversation.

Source

pub fn insert( &self, slot: &SessionSlot, conversation: Conversation, ) -> Arc<Held> ⓘ

Hold conversation for slot, unless the stream got there first.

Source

pub fn replace( &self, slot: &SessionSlot, conversation: Conversation, ) -> Arc<Held> ⓘ

Replace a seat’s copy outright.

What a copy built from a ring stretch needs: insert keeps what is there, and the stretch replaces it so the frames after it apply to the copy the read is served from.

Source

pub fn seeded_notice(&self) -> Notified<'_> ⓘ

A future that resolves when some seat’s copy is first held or reseeded.

Enable it before looking the seat up, or a seat seeded between the lookup and the wait leaves the caller waiting for something that has already happened - and bound the wait, because a seat whose session is gone never answers at all.

A reseed counts: a seal the header has already moved on from lands on the copy the seat holds, in place, so a reader waiting for that copy to become current is woken by it rather than by the seat’s first hold.

Source

pub fn apply(&self, update: &SessionUpdate, seq: Option<u64>)

Fold one update into the seat it names.

seq is the number the frame was minted under; the copy records it as the newest it reflects.

Source

fn reseed( &self, slot: &SessionSlot, history: &[Message], compaction_count: u32, carried: usize, occupant: Option<&SessionId>, )

Put history on slot, materialising the seat when this is the first word about it.

Held means reseed and NOT insert: insert keeps what is there, so a connect on a seat already carrying a conversation would leave that conversation in place and the new history discarded.

The watermark goes to zero: a seal opens a new epoch, whose frame count starts at 1.

Source

pub fn len(&self) -> usize

How many seats are held.

Source

pub fn is_empty(&self) -> bool

Trait Implementations§

Source§

impl Default for Conversations

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send> ⓘ

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more