Skip to main content

TransportLadder

Struct TransportLadder 

Source
pub struct TransportLadder<S> { /* private fields */ }
Expand description

An ordered set of transports backed by an offline buffer.

Rungs are tried in the order they are added, so the cheapest, most-preferred link is added first. A send that no rung accepts is buffered in the [Store] and replayed by flush. The ladder is itself a [Transport] and a [Receive]: a subscription goes onto every rung that listens, and a receive takes whichever rung delivers first.

Implementations§

Source§

impl<S: Store> TransportLadder<S>

Source

pub fn new(buffer: S) -> Self

Creates an empty ladder that buffers into buffer.

§Arguments
  • buffer - the durable queue that holds messages while no rung is reachable.
§Returns

A ladder with no rungs; add them with rung and uplink.

Source

pub fn rung(self, transport: impl Transport + Receive + Send + 'static) -> Self

Adds a rung that sends and listens, lowest-cost first.

§Arguments
  • transport - a link to try. Rungs added earlier are preferred, so add the cheapest link first and the costliest fallback last. The ladder subscribes on it and listens to it as well as sending over it.
§Returns

The ladder, for chaining.

Adds a rung that only sends, lowest-cost first.

This is the shape of a LoRa uplink, a satellite messenger, or any link that carries readings out but never a command back. The ladder sends over it in turn with the other rungs and never subscribes or listens on it.

§Arguments
  • transport - a send-only link to try, in the same cheapest-first order as rung.
§Returns

The ladder, for chaining.

Source

pub async fn connect(&mut self) -> Result<()>

Connects every rung that is not connected, best-effort.

A rung that fails to connect is left unreachable rather than failing the whole ladder; sends simply fall through to the next rung or the buffer, and the next call tries it again. A rung that connects receives every filter the ladder has been asked to subscribe to, so a subscription placed while a link was down takes effect when it returns.

§Returns

Ok(()) once every rung has been given the chance to connect.

§Errors

This call is best-effort and currently always returns Ok(()).

Source

pub async fn send(&mut self, topic: &str, payload: &[u8]) -> Result<Delivery>

Sends a payload, falling back down the rungs and then to the buffer.

If the buffer is empty, each connected rung is tried in order and the first to accept the message delivers it. If every rung fails, or the buffer already holds a backlog, the message is buffered to preserve order, and only flush drains a backlog. A rung that answers [Error::Closed] is treated as down until the next connect.

§Arguments
  • topic - the destination topic.
  • payload - the bytes to send.
§Returns

Delivery::Sent if a rung delivered the message, or Delivery::Buffered if it was queued for a later flush.

§Errors

Returns [Error::Io] if the message must be buffered but the store cannot be written.

Source

pub async fn send_text(&mut self, topic: &str, text: &str) -> Result<Delivery>

Sends text down the ladder: a reading or a command written out.

This is send with the text’s UTF-8 bytes, so a reading that is already a number in words needs no encoding step; the far side reads it back with Message::text or Message::number.

§Arguments
  • topic - the destination topic.
  • text - the text to send.
§Returns

Delivery::Sent if a rung delivered the message, or Delivery::Buffered if it was queued for a later flush.

§Errors

Whatever send returns.

Source

pub async fn flush(&mut self) -> Result<usize>

Drains the buffer across the rungs, oldest record first.

Each record is sent before it is removed, so the first record no rung can deliver halts the drain and leaves it, and everything after it, buffered in order for a later retry.

§Returns

The number of records forwarded before the buffer emptied or a rung refused one.

§Errors

Returns [Error::Io] if the store cannot be read or written, or [Error::Codec] if a buffered record cannot be decoded.

Source

pub async fn buffered(&mut self) -> Result<usize>

Returns how many messages are currently buffered.

Takes the ladder mutably, like the rest of its surface. Reading through a shared borrow would hold one across the await, which would in turn oblige every rung to be Sync rather than only Send, and that is a heavier requirement than a transport should have to meet.

§Returns

The number of records waiting for a flush.

§Errors

Returns [Error::Io] if the store length cannot be read.

Source

pub async fn subscribe(&mut self, topic: &str) -> Result<()>

Subscribes to a topic on every rung that listens.

The filter is kept for the life of the ladder: a rung that is down when it is placed, or that later drops and reconnects, receives it on its next connect. Subscribing while no rung is up therefore succeeds, in the same way a send with no rung up is buffered rather than refused.

§Arguments
  • topic - the topic filter, in the syntax the rungs’ links understand.
§Returns

Ok(()) once the filter is live on at least one rung, or is held for the rungs to pick up as they connect.

§Errors

Returns the rung’s own [Error::Transport] if every connected rung refused the filter. A rung that answers [Error::Closed] is treated as down rather than as refusing.

Source

pub async fn recv(&mut self) -> Result<Option<Message>>

Awaits the next message from any rung that listens.

Every connected, listening rung is polled together and the first to deliver wins, starting from a different rung each call so a busy link cannot starve a quiet one. A rung whose link ends, or that answers [Error::Closed], is treated as down until the next connect, and the wait continues on the rungs that remain.

The wait is cancel-safe when every rung’s receive is, as the receives of the links pamoja ships are: a wait given up, by a timeout or a select!, takes no message. That is how a node that both listens and reports shares one ladder, waiting with a limit and sending between waits.

§Returns

Some(message) for the next message any rung delivers. None is never returned: a ladder’s links come back with connect, so it reports a closed state rather than an ended one.

§Errors

Returns [Error::Closed] if no connected rung listens: none was added with rung, connect has not been called, or every listening link has since ended. Returns a rung’s own [Error::Transport] if its link fails while waiting.

Trait Implementations§

Source§

impl<S: Store + Send> Receive for TransportLadder<S>

Source§

async fn recv(&mut self) -> Result<Option<Message>>

Awaits the next message from any subscribed topic. Read more
Source§

impl<S: Store + Send> Transport for TransportLadder<S>

Source§

async fn send(&mut self, topic: &str, payload: &[u8]) -> Result<()>

Sends through the ladder; a buffered message counts as accepted for delivery, which is what the buffer is for.

Source§

async fn connect(&mut self) -> Result<()>

Establishes the connection to the broker, peer, or bus. Read more
Source§

async fn subscribe(&mut self, topic: &str) -> Result<()>

Subscribes to a topic so that matching payloads are routed to this transport. Read more
§

fn send_text( &mut self, topic: &str, text: &str, ) -> impl Future<Output = Result<(), Error>> + Send

Publishes text to a topic: words, or a number written out. Read more

Auto Trait Implementations§

§

impl<S> !RefUnwindSafe for TransportLadder<S>

§

impl<S> !Sync for TransportLadder<S>

§

impl<S> !UnwindSafe for TransportLadder<S>

§

impl<S> Freeze for TransportLadder<S>
where S: Freeze,

§

impl<S> Send for TransportLadder<S>
where S: Send,

§

impl<S> Unpin for TransportLadder<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for TransportLadder<S>
where S: UnsafeUnpin,

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.