pub trait SubscriberSettings: Declared {
// Provided methods
fn name(
self,
name: impl Into<Cow<'static, str>>,
) -> <Self::Settings as NameStep>::Out
where Self::Settings: NameStep { ... }
fn workers(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Out
where Self::Settings: WorkersStep { ... }
fn workers_by_key(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Out
where Self::Settings: WorkersStep { ... }
fn threads(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Out
where Self::Settings: WorkersStep { ... }
fn threads_by_key(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Out
where Self::Settings: WorkersStep { ... }
fn on_failure(
self,
policies: FailurePolicies,
) -> <Self::Settings as FailureStep>::Out
where Self::Settings: FailureStep { ... }
fn start_at<P>(self, position: P) -> <Self::Settings as StartAtStep<P>>::Out
where Self::Settings: StartAtStep<P> { ... }
fn batch(self, size: NonZeroUsize) -> <Self::Settings as BatchStep>::Out
where Self::Settings: BatchStep { ... }
fn map_source<F>(self, f: F) -> <Self::Settings as MapSourceStep<F>>::Out
where Self::Settings: MapSourceStep<F> { ... }
}Expand description
The declarative settings, chainable on a #[subscriber] definition and on the builder alike.
Every method is available exactly while its setting is open: the attribute fixes what it names, and the corresponding step trait is implemented only for the open state, so a second naming fails to compile with a message of its own.
The order in a chain follows from what each step does to the source: name
comes first because it constructs the source, and a broker’s own settings then transform it
through map_source - which is also where a broker’s batching options
live, after the core’s own batch has named the batch size.
§Examples
use ruststream::memory::prelude::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct Order {
id: u64,
}
/// Everything is left to the mount site: the name, the pool, the failure policy.
#[subscriber]
async fn audit(order: &Order) -> HandlerOutcome {
tracing::info!(order.id, "audited");
HandlerOutcome::ack()
}
/// One instance per shard, each reading its own subscription.
fn app(shard: u8) -> RustStream {
RustStream::new(AppInfo::new("audit", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
b.include(
audit
.name(format!("orders-{shard}"))
.workers(nonzero!(4))
.on_failure(FailurePolicies::default().with_decode(FailurePolicy::Skip)),
);
})
}Provided Methods§
Sourcefn name(
self,
name: impl Into<Cow<'static, str>>,
) -> <Self::Settings as NameStep>::Out
fn name( self, name: impl Into<Cow<'static, str>>, ) -> <Self::Settings as NameStep>::Out
Names the subscription, building the kind the attribute fixed.
Available while the attribute left the source open (#[subscriber] for the by-name
source, #[subscriber(Kind)] for a named kind); the kind is built through
FromName.
Sourcefn workers(self, count: NonZeroUsize) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
fn workers(self, count: NonZeroUsize) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
Processes up to count deliveries (or batches) of this subscriber concurrently. The
mount-site spelling of workers(n).
Sourcefn workers_by_key(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
fn workers_by_key(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
Runs count sequential lanes keyed by the message’s partition key, preserving per-key
ordering. The mount-site spelling of workers(n, by_key).
Sourcefn threads(self, count: NonZeroUsize) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
fn threads(self, count: NonZeroUsize) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
Handles the deliveries (or batches) of this subscriber on count dedicated threads of its
own, for a handler that computes. The mount-site spelling of threads(n); it fills the
same position as workers, so a subscription names one of the two.
Sourcefn threads_by_key(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
fn threads_by_key(
self,
count: NonZeroUsize,
) -> <Self::Settings as WorkersStep>::Outwhere
Self::Settings: WorkersStep,
Runs count dedicated threads as sequential lanes keyed by the message’s partition key,
preserving per-key ordering. The mount-site spelling of threads(n, by_key).
Sourcefn on_failure(
self,
policies: FailurePolicies,
) -> <Self::Settings as FailureStep>::Outwhere
Self::Settings: FailureStep,
fn on_failure(
self,
policies: FailurePolicies,
) -> <Self::Settings as FailureStep>::Outwhere
Self::Settings: FailureStep,
Sets the policies applied to a handler panic and to a delivery that fails to
materialize. The mount-site spelling of on_failure(panic = .., decode = ..).
Sourcefn start_at<P>(self, position: P) -> <Self::Settings as StartAtStep<P>>::Outwhere
Self::Settings: StartAtStep<P>,
fn start_at<P>(self, position: P) -> <Self::Settings as StartAtStep<P>>::Outwhere
Self::Settings: StartAtStep<P>,
Opens the subscription at position instead of the broker’s default. The mount-site
spelling of start_at(<position>).
Sourcefn batch(self, size: NonZeroUsize) -> <Self::Settings as BatchStep>::Out
fn batch(self, size: NonZeroUsize) -> <Self::Settings as BatchStep>::Out
Opens the subscription in batches of at most size messages: the one parameter every
batch handler names, and the only one the framework carries down to the broker.
The broker builds the batch - XREADGROUP COUNT, a pull batch, a poll limit, or the
framework’s own client-side buffer where the transport has no batching of its own - and
what the body sees is exactly what the broker delivered, never a slice of it. Everything
else about how a batch forms (a block timeout, a consumer group, a prefetch window) is the
broker’s own vocabulary, chained after this on its subscription source.
Mandatory on a batch body (&[T] and friends), whatever else its signature carries:
mounting one without it does not compile. A single-message body takes no batch, so the
step is not offered there at all - how many deliveries it handles at once is
workers.
Sourcefn map_source<F>(self, f: F) -> <Self::Settings as MapSourceStep<F>>::Outwhere
Self::Settings: MapSourceStep<F>,
fn map_source<F>(self, f: F) -> <Self::Settings as MapSourceStep<F>>::Outwhere
Self::Settings: MapSourceStep<F>,
Transforms the source under construction.
The hook a broker crate layers its own settings trait on: core cannot know that a
subscription has a JetStream stream or a consumer group, so the broker declares a trait
over SubscriberBuilder bound to its own source type and implements each method as one
map_source call. The bound means those methods simply do not exist on a builder for
another broker.
§Examples
use std::time::Duration;
use ruststream::Buffered;
use ruststream::memory::prelude::*;
use ruststream::runtime::{Declared, SubscriberBuilder};
use serde::Deserialize;
/// A broker crate's mount-site step for a transport that delivers one message at a time:
/// the batches are assembled on the client, and a partial one closes `wait` after it
/// opened.
pub trait Linger {
type Out;
fn linger(self, wait: Duration) -> Self::Out;
}
impl<Def: Declared, State, DefCodec> Linger
for SubscriberBuilder<Def, MemorySource, State, DefCodec>
{
type Out = SubscriberBuilder<Def, Buffered<MemorySource>, State, DefCodec>;
fn linger(self, wait: Duration) -> Self::Out {
self.map_source(|source| Buffered::new(source).max_wait(wait))
}
}
#[derive(Deserialize)]
struct Order {
id: u64,
}
#[subscriber(MemorySource)]
async fn settle(orders: &[Order]) -> HandlerOutcome {
tracing::info!(count = orders.len(), "settled a batch");
HandlerOutcome::ack()
}
fn app() -> RustStream {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
b.include(
settle
.name("orders")
.batch(nonzero!(64))
.linger(Duration::from_millis(20)),
);
})
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".