1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! `reliar-inbox` is the transactional inbox: dedup of inbound messages keyed
//! `(scope, message_id)`, inside the caller's own transaction (ADR 0042).
//!
//! The guarantee, stated once: **effectively-once for effects that live in the caller's
//! transaction; at-least-once for everything else; no exactly-once claim, no ordering
//! promise.** A bounded-retry dead state exists (ADR 0042 Amendment A), but it changes no
//! guarantee — it only stops a poison message from being redelivered forever.
//!
//! A provider (`reliar-store-postgres`) implements [`InboxStore`] against its own transaction
//! type; this crate depends on `reliar-core` only and names no storage engine.
//!
//! This crate cannot construct a store to run a doctest against (ADR 0043 §7 — there is no
//! in-memory fake), so the shape below is a **compiled, never-called generic function**: it
//! type-checks the real call shape and the real `InboxStore<Tx>` bound against any provider.
//! `reliar-store-postgres`'s own docs carry a runnable example over `PostgresInboxStore`.
//!
//! ```
//! # use reliar_inbox::{InboxHandler, InboxMessage, InboxOutcome, InboxScope, InboxStore};
//! #
//! struct RecordOrder;
//!
//! impl<Tx: Send> InboxHandler<Tx> for RecordOrder {
//! type Output = ();
//! type Error = std::convert::Infallible;
//!
//! async fn handle(&self, _tx: &mut Tx) -> Result<Self::Output, Self::Error> {
//! // Every write here shares the caller's transaction with the inbox completion.
//! Ok(())
//! }
//! }
//!
//! async fn consume<Tx: Send, S: InboxStore<Tx>>(
//! store: &S,
//! tx: &mut Tx,
//! scope: &InboxScope,
//! message: InboxMessage<'_>,
//! ) {
//! match store.process(tx, scope, message, &RecordOrder).await {
//! Ok(InboxOutcome::Processed(())) => { /* tx.commit(), then ack */ }
//! Ok(_) => { /* AlreadyCompleted, InProgress or Dead: roll back, drop `tx` */ }
//! Err(_) => { /* roll back, log, nak */ }
//! }
//! }
//! ```
pub use ;
pub use ;
pub use InboxProcessError;
pub use InboxHandler;
pub use InboxMessage;
pub use ;
pub use ;
pub use InboxRecordId;
/// Re-exported from `reliar-core`: an [`InboxStore::Error`]'s `Classify` bound and the resulting
/// `FailureKind`. New code may also name `reliar_core::` directly.
pub use ;
pub use ;
pub use InboxStore;