Skip to main content

EosPipeline

Struct EosPipeline 

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

An exactly-once pipeline over one transactional producer.

Wiring, all three naming the same id:

  1. The publisher: broker.publisher().transactional_id("pipeline-1").
  2. Each source subscription: Commit::Transactional("pipeline-1".into()) - its consumer stops committing offsets on its own and registers with the pipeline instead.
  3. The pipeline: EosPipeline::new(publisher), held in the application state; handlers call publish with the delivery’s SourceOffset.

Every commit_interval the pipeline closes the window: it waits until every delivery that published into it has settled (the shared watermark reached the enrolled offsets), adds the settled source positions and their group metadata to the transaction, and commits. On any failure - a failed publish, a settle stall (a handler hanging or retry()-ing past the publisher’s transaction timeout), a rebalance revoking an enrolled partition, a commit error - the window aborts and the consumers seek back, so the whole window redelivers and republishes into a fresh transaction; committed output still never duplicates.

Works best over the default LaneKey::Partition worker lanes: a partition processes in order on one lane, so the settle condition follows the lane head and windows close promptly. Clones share the pipeline.

Implementations§

Source§

impl EosPipeline

Source

pub fn new(publisher: KafkaPublisher) -> Self

Builds the pipeline over publisher, which must carry a transactional_id - it doubles as the pipeline id that Commit::Transactional subscriptions register under. A publisher without one fails the first publish with a clear error.

Source

pub fn commit_interval(self, interval: Duration) -> Self

How long a window stays open before committing; defaults to 100ms (the Kafka Streams exactly-once default). Longer intervals amortize the commit over more records at the cost of end-to-end latency (records become visible only at the commit). Configure before handing the pipeline out.

Source

pub async fn publish( &self, source: &SourceOffset, msg: OutgoingMessage<'_>, ) -> Result<(), KafkaError>

Publishes msg into the pipeline’s open window on behalf of the delivery at source.

The record joins the window’s transaction and becomes visible at its commit, atomically with the source position. Publish, then return Ack: the settled watermark is what releases the window’s commit.

§Errors

Returns KafkaError::InvalidOptions when the publisher carries no transactional id, KafkaError::NotConnected before Broker::connect, and KafkaError::Publish when opening the transaction or producing the record fails - the window aborts and redelivers, so failing the handler (retry()) is the right response.

§Cancel safety

Not cancel safe: dropping the future may leave the record in the window’s transaction.

§Panics

Panics when the internal window mutex is poisoned, which requires a prior panic inside the pipeline (an invariant violation, not an operational failure).

Source§

impl EosPipeline

Source

pub fn replies( &self, ) -> TypedPublisher<Self, DefaultCodec, PublishTransformStack<PublishTransformIdentity, EosReplies>>

A reply publisher for #[subscriber(.., publish("replies"))] handlers: every reply joins the pipeline’s open window paired with its delivery’s consumed offset, making the publishing-handler form exactly-once end to end - the handler just returns the value.

Pairs only with subscriptions in Commit::Transactional mode naming this pipeline’s id (they stamp the source coordinates the reply path relays); a reply from any other subscription fails with a clear error. The retry_after deferred-republish fallback does not apply to these replies: a delayed copy would break the offset-record pairing.

Equivalent explicit form: TypedPublisher::new(pipeline.clone()).transform(EosReplies).

§Examples
use ruststream_rdkafka::{EosPipeline, KafkaBroker};

let broker = KafkaBroker::new(["localhost:9092"]);
let pipeline = EosPipeline::new(broker.publisher().transactional_id("enrich-1"));
let replies = pipeline.replies();
// b.include_publishing(enrich, replies);
Source

pub fn replies_with<C: Codec>( &self, codec: C, ) -> TypedPublisher<Self, C, PublishTransformStack<PublishTransformIdentity, EosReplies>>

Like replies, with an explicit codec instead of the default one.

Trait Implementations§

Source§

impl Clone for EosPipeline

Source§

fn clone(&self) -> EosPipeline

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for EosPipeline

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Publisher for EosPipeline

Source§

async fn publish(&self, msg: OutgoingMessage<'_>) -> Result<(), Self::Error>

Publishes a reply into the pipeline’s open window, paired with the source coordinates the EOS_SOURCE_HEADER carries (stripped before the record is produced).

§Errors

Returns KafkaError::InvalidOptions when the header is missing or malformed - the originating subscription is not in Commit::Transactional mode for this pipeline, or the reply publisher was wired without EosReplies (use replies); otherwise as EosPipeline::publish.

§Cancel safety

Not cancel safe: dropping the future may leave the record in the window’s transaction.

Source§

type Error = KafkaError

The error type returned by publish.

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<P> ErasedPublisher for P
where P: Publisher,

Source§

fn publish_bytes<'a>( &'a self, name: &'a str, payload: &'a [u8], ) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Sync + Send>>> + Send + 'a>>

Publishes payload to name, with no headers. Read more
Source§

fn publish_message<'a>( &'a self, name: &'a str, payload: &'a [u8], headers: &'a Headers, ) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Sync + Send>>> + Send + 'a>>

Publishes payload to name with headers. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
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