outbox_core/lib.rs
1//! Transactional outbox primitives shared by every storage and transport
2//! adapter in the workspace.
3//!
4//! The crate is split into two sides:
5//!
6//! - **Producer** — [`OutboxService`](prelude::OutboxService) persists new
7//! events into the outbox table, applying the configured
8//! [`IdempotencyStrategy`](prelude::IdempotencyStrategy) and optionally
9//! reserving the token through an external
10//! [`IdempotencyStorageProvider`](prelude::IdempotencyStorageProvider).
11//! - **Worker** — [`OutboxManager`](prelude::OutboxManager), constructed via
12//! [`OutboxManagerBuilder`](prelude::OutboxManagerBuilder), drives the
13//! processing loop: it waits for notifications, fetches pending rows,
14//! publishes each through a [`Transport`](prelude::Transport), and runs a
15//! background garbage collector on the side.
16//!
17//! Storage and transport backends live in sibling crates (`outbox-postgres`,
18//! `outbox-redis`, `outbox-kafka`). This crate only defines the traits they
19//! must satisfy.
20//!
21//! # Features
22//!
23//! - `sqlx` — derives `sqlx::Type` / `sqlx::FromRow` on the domain types so
24//! storage adapters can map rows without manual conversion.
25//! - `dlq` — enables the dead-letter-queue heap (see
26//! [`DlqHeap`](crate::dlq::storage::DlqHeap)); the worker then tracks
27//! per-event failure counts on every publish attempt.
28//! - `metrics` — emits `outbox.events_total` and
29//! `outbox.publish_duration_seconds` via the `metrics` crate.
30//! - `full` — turns on `sqlx`, `dlq`, and `metrics` together.
31//!
32//! # Getting started
33//!
34//! Import the common types via the [`prelude`] module:
35//!
36//! ```ignore
37//! use outbox_core::prelude::*;
38//! ```
39
40mod builder;
41mod config;
42mod dlq;
43mod error;
44mod gc;
45mod idempotency;
46mod manager;
47mod model;
48mod object;
49mod processor;
50mod publisher;
51mod service;
52mod storage;
53
54// Root re-exports for explicit-import users. The [`prelude`] module exposes
55// the same set as a glob-import shortcut for integrators who prefer it.
56pub use crate::builder::OutboxManagerBuilder;
57pub use crate::config::{IdempotencyDeriver, IdempotencyStrategy, OutboxConfig};
58pub use crate::error::OutboxError;
59pub use crate::idempotency::storage::IdempotencyStorageProvider;
60pub use crate::manager::OutboxManager;
61pub use crate::model::{Event, EventStatus};
62pub use crate::object::{EventId, EventType, IdempotencyToken, Payload};
63pub use crate::publisher::Transport;
64pub use crate::service::OutboxService;
65pub use crate::storage::{OutboxStorage, OutboxWriter};
66
67#[cfg(feature = "dlq")]
68pub use crate::dlq::model::DlqEntry;
69#[cfg(feature = "dlq")]
70pub use crate::dlq::storage::DlqHeap;
71
72/// Curated set of re-exports for typical integrator code.
73///
74/// Importing `outbox_core::prelude::*` brings in the types you need to build
75/// and run an outbox without having to reach into individual modules. Pulls
76/// in both the public-facing APIs (service, manager, builder, config, errors)
77/// and the traits a storage/transport adapter has to implement.
78///
79/// Every item in the prelude is also available as a direct re-export at the
80/// crate root, so explicit-import users can write
81/// `use outbox_core::{OutboxConfig, OutboxService};` instead of glob-importing.
82pub mod prelude {
83 pub use crate::{
84 Event, EventId, EventStatus, EventType, IdempotencyDeriver, IdempotencyStorageProvider,
85 IdempotencyStrategy, IdempotencyToken, OutboxConfig, OutboxError, OutboxManager,
86 OutboxManagerBuilder, OutboxService, OutboxStorage, OutboxWriter, Payload, Transport,
87 };
88
89 pub use crate::processor::OutboxProcessor;
90
91 #[cfg(feature = "dlq")]
92 pub use crate::{DlqEntry, DlqHeap};
93}