fx_event_bus/lib.rs
1//! A reliable event bus for monolithic Rust applications.
2//!
3//! Built on PostgreSQL for durability and ACID guarantees, with support for
4//! event publishing, consumption, retry logic with exponential backoff, and
5//! dead letter queues for failed events.
6//!
7//! # Quick Start
8//!
9//! ```rust,no_run
10//! use fx_event_bus::*;
11//! use serde::{Serialize, Deserialize};
12//! use std::time::Duration;
13//! use std::sync::Arc;
14//! use chrono::{DateTime, Utc};
15//! use sqlx::PgTransaction;
16//! use futures::future::BoxFuture;
17//! use thiserror::Error;
18//!
19//! // 1. Define your event
20//! #[derive(Serialize, Deserialize, Clone)]
21//! struct OrderCreated { order_id: u64 }
22//!
23//! impl Event for OrderCreated {
24//! const NAME: &'static str = "OrderCreated";
25//! }
26//!
27//! #[derive(Error, Debug)]
28//! #[error("Order processing failed: {0}")]
29//! struct OrderError(String);
30//!
31//! // 2. Create a handler
32//! struct OrderHandler;
33//! impl Handler<OrderCreated> for OrderHandler {
34//! type Error = OrderError;
35//!
36//! fn handle<'a>(
37//! &'a self,
38//! event: Arc<OrderCreated>,
39//! polled_at: DateTime<Utc>,
40//! tx: PgTransaction<'a>,
41//! ) -> BoxFuture<'a, (PgTransaction<'a>, Result<(), Self::Error>)> {
42//! Box::pin(async move {
43//! // Handle the order creation
44//! println!("Order {} created!", event.order_id);
45//! (tx, Ok(()))
46//! })
47//! }
48//! }
49//!
50//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
51//! # let pool = sqlx::PgPool::connect("postgresql://localhost/test").await?;
52//! # let mut tx = pool.begin().await?;
53//!
54//! // 3. Set up the event bus
55//! let mut registry = EventHandlerRegistry::new();
56//! registry.with_handler::<OrderCreated, _>(OrderHandler);
57//!
58//! let listener = Listener::new(pool.clone(), registry)
59//! .with_max_attempts(3)
60//! .with_retry_duration(Duration::from_secs(30));
61//!
62//! // 4. Publish events
63//! let mut publisher = Publisher::new(tx);
64//! publisher.publish(OrderCreated { order_id: 123 }).await?;
65//! let tx: PgTransaction<'_> = publisher.into();
66//! tx.commit().await?;
67//!
68//! // 5. Start processing (in a real app)
69//! // listener.listen(None).await?;
70//! # Ok(())
71//! # }
72//! ```
73
74mod handler;
75mod listener;
76mod migrations;
77mod models;
78mod publisher;
79
80#[cfg(any(test, feature = "test-tools"))]
81pub mod test_tools;
82
83pub use handler::{EventHandlerRegistry, Handler};
84pub use listener::Listener;
85pub use migrations::run_migrations;
86pub use models::Event;
87pub use publisher::{Publisher, PublisherError};