Expand description
SQL-backed Outbox over sqlx’s driver-agnostic AnyPool.
SqlOutbox persists outbox rows in a single portable table so the same
code drives PostgreSQL, MySQL/MariaDB, or SQLite — whichever driver feature
is compiled in. The schema uses only portable column types (TEXT,
BIGINT, INTEGER boolean) so the DDL in SqlOutbox::CREATE_TABLE_SQL
applies unchanged across backends.
Timestamps are stored as RFC3339 TEXT (lexicographically sortable) and
booleans as 0/1 integers, both for maximum portability through the Any
driver layer.
§Concurrent pollers
The portable fetch_unpublished does a plain
ordered SELECT; if several relay processes poll at once they can fetch the
same rows and double-publish (the broker should dedupe on event id). On
PostgreSQL prefer SqlOutbox::fetch_unpublished_skip_locked (gated behind
the postgres feature), which claims rows with FOR UPDATE SKIP LOCKED so
each poller gets a disjoint batch.
use klauthed_data::outbox::Outbox;
use klauthed_data::outbox::SqlOutbox;
sqlx::any::install_default_drivers();
let pool = sqlx::AnyPool::connect("sqlite::memory:").await?;
let outbox = SqlOutbox::new(pool);
outbox.ensure_schema().await?;
let pending = outbox.fetch_unpublished(100).await?;