Skip to main content

Loopback

Struct Loopback 

Source
pub struct Loopback { /* private fields */ }
Expand description

The aggregate handle: one value implementing all twelve port traits by delegating to the six role handles it holds.

A face is built over one value implementing at least the port traits its interface needs, and a generated Client is commonly bound over SignalReader + EventSource + Caller at once, which no single role handle satisfies. That is what an aggregate is for (ADR-0021 decision 12). Pass it by value, or as &mut under the forwarding impls of ADR-0021 decision 11.

Implementations§

Source§

impl Loopback

Source

pub const SLOTS: usize = 16

The number of calls the runtime holds at once. A call holds its slot from its send until one of these reclaims it:

  • Caller::forget, or the drop of the caller handle that sent it, while it is settled or still waiting for a handler;
  • its settlement, when it was forgotten while a handler held it;
  • the drop of the handler that held it unsettled, when it was forgotten.

So a settled call keeps its slot until it is forgotten, and a claimed call keeps its slot after its forget until it is settled or its handler is dropped. With every slot taken, Caller::command and Caller::query answer SendError::Busy, on every caller handle, because the table is the runtime’s.

Sixteen is a small bound, chosen so that a test reaches it in a few sends and a program that never forgets a call finds out at once rather than after its memory grows. The loopback has no catalog descriptor to size a byte budget from (story E16.2), so the slot count is its only bound (note F-9 of the async face design).

The generated async client’s future (story E11.21) forgets its call when it leaves the waiting phase: in the poll that takes the outcome, at the call’s deadline, and on drop while the call is still waiting. So a program that calls through the generated face holds one slot per call in flight. A program that sends through the Caller port directly must forget each correlation itself once it has read the outcome, or drop the caller handle, which forgets that handle’s calls; otherwise it gets SendError::Busy from its seventeenth call on.

Source

pub fn new(catalog: CatalogRef) -> Self

A runtime attached to catalog, with an empty store and its clock at Timestamp 0.

The catalog is carried, not checked: see the crate documentation.

Source

pub fn split(self) -> Handles

Hands out the six role handles this aggregate holds. Every one of them keeps the same store, so a value published through writer is read through reader.

Source

pub fn reader(&self) -> ReaderHandle

An additional reader handle on the same store.

Source

pub fn writer(&self) -> WriterHandle

An additional writer handle on the same store, with its own staging area and its own per channel sequence counters.

Source

pub fn source(&self) -> SourceHandle

An additional event source on the same store, with its own subscription set and its own queue.

Source

pub fn sink(&self) -> SinkHandle

An additional event sink on the same store, with its own sequence counter.

Source

pub fn caller(&self) -> CallerHandle

An additional caller on the same store, with its own sequence counter. Two callers on one provider therefore never collide on a sequence number (driftsys/ridl#308).

Source

pub fn handler(&self) -> HandlerHandle

An additional handler on the same store.

Every handler draws from the one queue of waiting calls, filtered by what it has served: a handler that has served nothing is presented every waiting call, and one that has served members is presented only those. A claim belongs to the handler it was presented to.

Source

pub fn advance(&mut self, by: Duration)

Advances the clock by by.

The clock is a counter this method moves and nothing else moves. It never reads wall-clock time, so a round trip over this runtime produces the same timestamps on every run and on every machine. It saturates rather than overflowing.

§Panics

When by is negative. A clock that ran backwards would stamp an envelope before one already stamped.

Source

pub fn provision_fixed( &mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8], )

Supplies the value of a fixed (ridl §8), which is provisioned into a runtime rather than published by application code.

Until a fixed is provisioned, reading it answers ReadError::Contract(Contract::UnknownInteraction): the loopback holds no value and, having no member table, cannot say anything narrower.

Source

pub fn fail_next_settle(&mut self)

Makes the next Handler::settle on this runtime fail with SettleError::TooLarge and record no outcome.

This is the one fault this runtime injects, and the one place a SettleError other than UnknownClaim comes from. It exists because the generated dispatch counts a claim only once the handler has accepted its settlement, and nothing else in an in-process runtime can make that path fail.

Trait Implementations§

Source§

impl Attached for Loopback

Source§

fn catalog(&self) -> &CatalogRef

The catalog this port serves.
Source§

impl Caller for Loopback

Source§

fn command( &mut self, iface: InterfaceNo, ord: Ordinal, args: &[u8], ) -> Result<Correlation, SendError>

Sends a command and returns the correlation of its outcome.
Source§

fn query( &mut self, iface: InterfaceNo, ord: Ordinal, args: &[u8], ) -> Result<Correlation, SendError>

Sends a query and returns the correlation of its reply.
Source§

fn ack(&mut self, c: Correlation) -> Option<Result<(), CallError>>

A command’s delivery acknowledgment (ridl §6.1), once it is known: Ok(()) when accepted, Err(CallError::Contract(_)) when rejected, Err(CallError::Transport(Transport::Corrupt)) when the provider could not read the command’s argument bytes, Err(CallError::Transport(Transport::Busy)) when the providing runtime refused the command at admission, and Err(CallError::Transport(Transport::Undelivered)) when no acknowledgment came within the bound. None while unknown, and always None for a query’s correlation. Read more
Source§

fn reply( &mut self, c: Correlation, out: &mut [u8], ) -> Result<Option<Result<usize, CallError>>, ReadError>

A query’s reply, once it is known: the reply bytes copied into the front of out and their length, or the error. Ok(None) while unknown. ReadError::Short does not consume the reply. Read more
Source§

fn forget(&mut self, c: Correlation)

Releases a correlation whose outcome the caller no longer needs.
Source§

impl Clock for Loopback

Source§

fn now(&self) -> Timestamp

The current time in the platform time base.
Source§

impl CoherentSignals for Loopback

Source§

fn read_coherent( &self, iface: InterfaceNo, ords: &[Ordinal], out: &mut [u8], samples: &mut [RawSample], ) -> Result<usize, ReadError>

Answers every ordinal in ords from one publication. Copies the values into out one after another, writes one RawSample for each ordinal into samples in the order of ords, and returns the number of bytes written to out. Read more
Source§

impl EventSink for Loopback

Source§

fn raise( &mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8], ) -> Result<(), RaiseError>

Raises one occurrence.
Source§

impl EventSource for Loopback

Source§

fn subscribe( &mut self, iface: InterfaceNo, ords: &[Ordinal], ) -> Result<(), SubscribeError>

Starts delivery of the listed events.
Source§

fn unsubscribe(&mut self, iface: InterfaceNo, ords: &[Ordinal])

Stops delivery of the listed events.
Source§

fn next(&mut self, out: &mut [u8]) -> Result<Option<RawOccurrence>, ReadError>

Copies the next occurrence into the front of out. Ok(None) when no occurrence is waiting. Read more
Source§

impl FixedReader for Loopback

Source§

fn read_fixed( &self, iface: InterfaceNo, ord: Ordinal, out: &mut [u8], ) -> Result<usize, ReadError>

Copies the provisioned value into the front of out and returns its length.
Source§

impl Handler for Loopback

Source§

fn serve( &mut self, iface: InterfaceNo, ords: &[Ordinal], ) -> Result<(), ServeError>

Starts presenting calls to the listed members.
Source§

fn next_claim(&mut self, out: &mut [u8]) -> Result<Option<Claim>, ReadError>

Copies the next call’s arguments into the front of out. Ok(None) when no call is waiting. ReadError::Short does not consume the call.
Source§

fn settle( &mut self, claim: ClaimId, outcome: Result<&[u8], CallError>, ) -> Result<(), SettleError>

Settles a claim with the reply bytes (empty for a command) or the outcome the caller sees. A provider settles CallError::Contract when the arguments break their typl constraints, a require clause fails, or an ensure clause fails, and CallError::Transport(Transport::Corrupt) when the argument bytes fail the structure check.
Source§

impl ScannableSignals for Loopback

Source§

fn generation(&self, iface: InterfaceNo) -> u64

The interface’s generation: a counter that each commit to the interface increments. Read more
Source§

fn scan(&self, marks: &mut [Watermark], out: &mut [Changed]) -> usize

Writes the changes into out, interface by interface, in the order of marks, and updates marks. An interface’s changes are written all together or not at all: when they do not fit in the rest of out, none of them is written, that interface’s mark is not updated, and scan returns the number of entries written so far. Read more
Source§

impl SignalReader for Loopback

Source§

fn read( &self, iface: InterfaceNo, ord: Ordinal, out: &mut [u8], ) -> Result<RawSample, ReadError>

Copies the signal’s current value into the front of out and returns its provenance, its freshness and its envelope. The runtime resolves both the provenance and the freshness. Read more
Source§

impl SignalWriter for Loopback

Source§

fn set( &mut self, iface: InterfaceNo, ord: Ordinal, bytes: &[u8], ) -> Result<(), WriteError>

Stages a new value.
Source§

fn invalidate( &mut self, iface: InterfaceNo, ord: Ordinal, ) -> Result<(), WriteError>

Stages the invalid state (ridl §4.5), with Cause::Declared.
Source§

fn touch(&mut self, iface: InterfaceNo, ord: Ordinal) -> Result<(), WriteError>

Stages a re-affirmation of the current value, without a new value.
Source§

fn commit(&mut self)

Publishes everything staged. It cannot fail, so it reports nothing — including that the runtime behind the port is gone. A caller learns that from WriteError::Detached on a later set, invalidate or touch, never from that commit. What becomes of the changes staged before a commit whose runtime has already detached is not fixed here.
Source§

impl Wakeable for Loopback

Each key goes to the handle that observes it: Outcome and Slot to the caller, Event to the source, and Claim to the handler.

Source§

fn wake_on(&self, what: Interest, waker: &Waker)

Wakes waker when the thing what names may have changed, under the contract above.

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, 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.