Skip to main content

reliar_core/
publisher.rs

1//! Publication (SRS §19.4, §24.1, ADR 0008, ADR 0032).
2
3use crate::SerializedEnvelope;
4use crate::failure::Classify;
5
6/// The wire side of the outbox. One provider implements this per transport.
7///
8/// A publish **timeout** classifies as [`crate::FailureKind::Transient`]. A payload the broker
9/// rejects as too large classifies as [`crate::FailureKind::Permanent`] — retrying forever
10/// cannot help (SRS §24.1).
11pub trait Publisher: Send + Sync {
12    /// The error a publish attempt can fail with. Must self-classify via [`Classify`] so the
13    /// dispatcher can decide retry vs. dead without inspecting transport internals.
14    type Error: std::error::Error + Send + Sync + 'static + Classify;
15
16    /// Publishes one envelope. Never retried by the publisher itself — retry is the
17    /// dispatcher's and `RetryPolicy`'s job (`reliar-outbox`).
18    fn publish(
19        &self,
20        envelope: &SerializedEnvelope,
21    ) -> impl Future<Output = Result<(), Self::Error>> + Send;
22
23    /// Publishes a batch. Results are **positional** — one per envelope, in the same order, so
24    /// a partial batch failure never loses a per-message verdict.
25    ///
26    /// The default loops over [`Self::publish`]; a transport with a native batch API overrides
27    /// it and owns proving its positional results. **v0.1's dispatcher calls [`Self::publish`],
28    /// not this method** — it needs a per-message outcome and a per-message timeout.
29    fn publish_batch(
30        &self,
31        envelopes: &[SerializedEnvelope],
32    ) -> impl Future<Output = Vec<Result<(), Self::Error>>> + Send {
33        async move {
34            let mut out = Vec::with_capacity(envelopes.len());
35            for envelope in envelopes {
36                out.push(self.publish(envelope).await);
37            }
38            out
39        }
40    }
41}