Skip to main content

CarriesBatch

Trait CarriesBatch 

Source
pub trait CarriesBatch<T> {
    // Required method
    fn carried(&self) -> &[T];
}
Expand description

A batch that lends the values its deliveries carry, as one slice it already holds.

A broker that fetches a page of values (a page of rows read through a database driver) keeps them in one buffer beside the deliveries that settle them. The broker implements this on its BatchSubscriber::Batch, and a handler taking &[T] reads the slice where it lies: no codec, no copy, and no vector of the runtime’s own.

The value at index i belongs to the i-th delivery the batch yields when it is iterated. A delivery past the end of the slice carries no value: the runtime settles it by the subscription’s decode-failure policy (on_failure(decode = ..)), as it settles a single delivery whose Carries::carried answers None. A broker puts such deliveries last. A delivery whose row it could not read goes there too, and reports the error through decode_error, which the runtime logs.

The batch’s context (BuildBatchContext) is built from the batch itself on this lane, because the batch stays whole while the handler reads its slice; the copies a retry publishes still build theirs from each delivery.

§Examples

A page of rows, the rows in one vector and the claims that settle them in another:

use ruststream::{AckError, CarriesBatch, HeaderMap, IncomingMessage};

/// One row of the queue table.
struct SendEmail {
    to: String,
}

/// The claim that settles one row, with the bytes the table stores for it.
struct Claim {
    bytes: Vec<u8>,
    headers: HeaderMap,
}

impl IncomingMessage for Claim {
    fn payload(&self) -> &[u8] {
        &self.bytes
    }
    fn headers(&self) -> &HeaderMap {
        &self.headers
    }
    async fn ack(self) -> Result<(), AckError> {
        Ok(())
    }
    async fn nack(self, _requeue: bool) -> Result<(), AckError> {
        Ok(())
    }
}

/// One fetched page.
struct Page {
    rows: Vec<SendEmail>,
    claims: Vec<Claim>,
}

impl CarriesBatch<SendEmail> for Page {
    fn carried(&self) -> &[SendEmail] {
        &self.rows
    }
}

impl IntoIterator for Page {
    type Item = Claim;
    type IntoIter = std::vec::IntoIter<Claim>;

    fn into_iter(self) -> Self::IntoIter {
        self.claims.into_iter()
    }
}

let page = Page {
    rows: vec![SendEmail { to: "ops@example.com".to_owned() }],
    claims: vec![Claim {
        bytes: b"ops@example.com".to_vec(),
        headers: HeaderMap::new(),
    }],
};
assert_eq!(page.carried()[0].to, "ops@example.com");
assert_eq!(page.into_iter().count(), 1);

Required Methods§

Source

fn carried(&self) -> &[T]

The values the batch’s deliveries carry, in the order the batch yields its deliveries.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§