Skip to main content

BackgroundConfig

Struct BackgroundConfig 

Source
pub struct BackgroundConfig {
    pub num_shards: usize,
    pub linger_time: IggyDuration,
    pub error_callback: Arc<Box<dyn ErrorCallback + Send + Sync>>,
    pub sharding: Box<dyn Sharding + Send + Sync>,
    pub batch_size: usize,
    pub batch_length: usize,
    pub failure_mode: BackpressureMode,
    pub max_buffer_size: IggyByteSize,
    pub max_in_flight: usize,
}
Expand description

The Apache Iggy producer/consumer escape hatch: same types Topic::iggy_producer/Topic::iggy_consumer/Topic::iggy_consumer_group return, and the stored message a failed publish hands back, re-exported so reaching for them doesn’t need an iggy dependency of your own. Configuration for a producer that sends messages in the background.

A background producer passes every non-empty send to a ProducerDispatcher. The dispatcher returns once the batch is queued, and one of its worker Shards writes the batch later. This type controls how many workers exist, which worker receives a batch, when workers flush, how many bytes may be queued or in flight, and where write failures are reported.

§Defaults

FieldDefaultControls
num_shards1how many worker queues exist
shardingOrderedShardingwhich worker a batch is queued on
batch_size1 MiBflush once a worker holds this many bytes
batch_length1000flush once a worker holds this many queued sends
linger_time1 mshow long a worker holds a non-empty buffer before flushing it
max_buffer_size32 MiBbytes the whole producer may hold
failure_modeBackpressureMode::Blockwhat a send does when that budget is full
max_in_flight1requests being written at once
error_callbackLogErrorCallbackwhat happens to a failed write

The default OrderedSharding strategy preserves dispatch order for each stream/topic pair by routing that pair to one worker. That worker awaits each request, including its retries, before starting the next. BalancedSharding can route consecutive batches for one destination to different workers and therefore gives up that ordering. max_in_flight only controls how many workers may write concurrently. It does not make a single worker process more than one request at a time.

§Zero values

0 disables the batch_size and batch_length flush thresholds. A zero linger_time flushes as soon as the worker picks up a send. A zero max_buffer_size is treated as unbounded. A zero max_in_flight uses Semaphore::MAX_PERMITS, and a zero num_shards is read as one worker.

§Examples

use iggy::clients::producer_config::BackpressureMode;
use iggy::prelude::*;
use std::time::Duration;

// Ordered and bounded, as described above.
let ordered = BackgroundConfig::builder().build();

// Throughput: four workers share one topic, flushing at 4 MiB, with a 256 MiB byte budget.
// Up to 4 requests can be in flight at the same time, one per worker.
let fast = BackgroundConfig::builder()
    .num_shards(4)
    .sharding(Box::new(BalancedSharding::default()))
    .batch_size(4 * 1024 * 1024)
    .max_buffer_size(IggyByteSize::from(256 * 1024 * 1024))
    .max_in_flight(4)
    .build();

// Latency: flush within 5 ms or after 50 queued sends. Do not wait for byte-budget capacity.
// The bounded per-worker channel can still make dispatch wait when its 256 slots are occupied.
let responsive = BackgroundConfig::builder()
    .linger_time(IggyDuration::new(Duration::from_millis(5)))
    .batch_length(50)
    .failure_mode(BackpressureMode::FailImmediately)
    .build();

Fields§

§num_shards: usize

Number of worker Shards the dispatcher runs, each with a queue of its own.

Every batch is routed to exactly one worker by sharding, and each worker buffers and writes independently.

0 is read as one worker.

§linger_time: IggyDuration

Upper bound on how long a worker holds a non-empty buffer before flushing it.

The window starts when a send enters an empty buffer, so an idle worker does not wake up. A worker flushes as soon as any of linger_time, batch_length or batch_size is reached. Lowering it reduces the time the write is delayed at the price of smaller writes. 0 flushes as soon as the worker picks up a send.

Note that IggyDuration::from reads a plain number as microseconds, so the default of 1000 is 1 ms.

§error_callback: Arc<Box<dyn ErrorCallback + Send + Sync>>

Where a background write that failed ends up.

The dispatcher runs one task that owns this callback. A worker invokes it with an ErrorCtx when its backend returns IggyError::ProducerSendFailed. Other error variants from a custom backend are logged by the worker without invoking this callback. The context contains the cause, destination, unconfirmed tail, and confirmations returned for earlier chunks.

The default LogErrorCallback logs the failure and drops the messages with the context. Implement ErrorCallback with your own logic to keep them.

§sharding: Box<dyn Sharding + Send + Sync>

Picks the worker a batch is queued on, out of num_shards.

The default OrderedSharding hashes stream and topic, so every batch for one topic queues on one worker and keeps the order it was dispatched in. BalancedSharding hands them out round-robin, which lets a single topic occupy all workers but gives up that order. Implement Sharding to build your own logic for picking a Shard.

§batch_size: usize

Flush threshold in bytes buffered on one worker.

Sends accumulate until their reported sizes reach or exceed this value. The threshold is checked after a send is added, so it is a flush trigger rather than a hard size ceiling. 0 disables the threshold and leaves batch_length and linger_time to trigger the flush.

This is a per-worker flush trigger. It is separate from max_buffer_size, which caps the producer as a whole.

§batch_length: usize

Flush threshold in number of queued batches on one worker.

Counts the queued sends a worker holds, not the individual messages inside them. A worker flushes after this many dispatches have been routed to it. 0 disables the threshold.

§failure_mode: BackpressureMode

What a send does once max_buffer_size is exhausted.

§max_buffer_size: IggyByteSize

Upper bound for the bytes buffered or in flight across all shards. Bytes remain charged until the corresponding write completes. IggyByteSize::from(0) means unlimited. A nonzero value greater than Semaphore::MAX_PERMITS makes ProducerDispatcher::new panic.

§max_in_flight: usize

Upper bound on the requests being written concurrently, shared by all workers.

A worker takes one permit before each request and holds it until the write returns. This bounds write concurrency across the producer rather than per worker, and it does not bound queued bytes.

Each worker still sends sequentially regardless of this value. Raising it only lets different workers write concurrently. Per-destination order is therefore governed by sharding: OrderedSharding keeps one destination on one sequential worker, while strategies that spread a destination across workers may reorder it. A nonzero value greater than Semaphore::MAX_PERMITS makes ProducerDispatcher::new panic.

Implementations§

Source§

impl BackgroundConfig

Source

pub fn builder() -> BackgroundConfigBuilder

Create an instance of BackgroundConfig using the builder syntax

Trait Implementations§

Source§

impl Debug for BackgroundConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. 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
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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

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

Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

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

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

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> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

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

Source§

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

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

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

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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

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

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