Expand description
reliar-store-postgres is Reliar’s PostgreSQL provider: the schema, the explicit
migrate API, and PostgresOutboxStore — the only crate where an sqlx/Postgres type
appears (SRS §20–§26, §35, ADR 0002).
§MSRV
This crate declares rust-version = "1.94", six releases above the workspace floor
(1.88): sqlx 0.9 requires it. Pure crates (reliar-core, reliar-outbox) stay reachable
on 1.88 for hosts bringing their own store (ADR 0025).
§Features
json(default) —PostgresOutboxStore<JsonSerializer>’s default type parameter and thePostgresOutboxStore::new/PostgresOutboxStore::with_settingsconvenience constructors (forwardsreliar-core/json). Not hard-enabled: a deployment supplying its ownreliar_core::Serializershould not have to pull inserde_json. Under--no-default-features,PostgresOutboxStore::connectis the only constructor.serde(off by default) —Serialize/DeserializeonPostgresOutboxSettings,#[serde(default, deny_unknown_fields)]so a typo’d config key is a hard error, durations as integer milliseconds.serdeitself is always a dependency regardless of this feature — it also drives the crate’s privateMetadataRestJSONB contract (ADR 0012), which is not feature-gated.
§search_path setup
Every Reliar object lives in one configurable schema, reliar by default, with
unprefixed table names (outbox). sqlx::query! checks SQL at compile time, so every
identifier in every statement is a static, unqualified literal — the schema is resolved at
connection time through search_path, never compiled in (ADR 0017).
- The host puts
reliarfirst on the connection URL:?options=-c%20search_path%3Dreliar,public. - Behind a transaction-mode pooler that drops startup
options(some reject the parameter outright with08P01), use a server-side default instead:ALTER ROLE <app> SET search_path = reliar, public. This is the portable mechanism — verify it against your own pooler build/version rather than assuming:PgDog(ghcr.io/pgdogdev/pgdog:v0.1.46, the pooler this crate’s suite runs behind) was found to pass theoptionsparameter through to the upstream server instead of dropping it, so the URL-optionspath above works unmodified behind it too, with noALTER ROLErequired — but a different pooler, or a differentPgDogconfiguration, could behave either way (§43.A.35). PostgresOutboxStore::connect/PostgresOutboxStore::newverify once at construction that the unqualified nameoutboxresolves to the configured schema, and fail fast — naming the configured schema, the observedsearch_path, and theALTER ROLEremedy — rather than surprise-failing on the firstacquire.migratedoes not depend on the caller’ssearch_path: it creates the schema itself and qualifies its own bookkeeping table name (ADR 0018).
§Guarantees
- Migrations never run implicitly.
migrateis the only entry point, and it is idempotent and safe under concurrent callers (SRS §35). - The claim is one statement.
PostgresOutboxStore’sacquire(viareliar_outbox::OutboxStore) uses aFOR UPDATE SKIP LOCKEDclaim that commits before the call returns; no network I/O ever happens while a Reliar transaction is open (ADR 0006). enqueuejoins the caller’s own transaction — atomicity is visible in the signature — and performs no I/O beyond the oneINSERT(plus, opt-in, asearch_pathwrap).
Structs§
- Enqueue
Options - Options specific to one
enqueuecall (contract §4 #9): the application-suppliedordering_key, which is deliberately not part ofMetadata(§22.2). - Json
Serializer - The default
Serializer: JSON viaserde_json. Ships behind the defaultjsonfeature; disable it to supply a different wire format (ADR 0010). - Migrate
Options - Where
migratecreates Reliar’s schema and its bookkeeping table. - Postgres
Outbox Settings - What is provider-specific about the outbox (contract §4). Everything portable lives in
reliar_outbox::OutboxSettings. - Postgres
Outbox Store - Reliar’s PostgreSQL outbox provider. Cheap to clone into an
AppState— it wraps aPgPool; no outerArcrequired. The connection pool stays the host’s: Reliar never owns or reads aDATABASE_URL.
Enums§
- Enqueue
Error crate::PostgresOutboxStore::enqueue/enqueue_withfailures.enqueueruns on the host’s write path, where the host decides whether to retry its own transaction, so this implementsClassifyon the same rules asPostgresStoreErrorrather than making the host re-derive which SQLSTATEs are worth retrying (contract §4).- Migrate
Error migrate’s failure. Provider-owned, not a re-export ofsqlx::migrate::MigrateError(contract §7 J3/J4): a rejected schema identifier has no variant insqlx’s own type to report it as, since that check happens before anysqlx::migratecode runs at all.- Postgres
Store Error - A failure of a
crate::PostgresOutboxStoreOutboxStore/OutboxDeadLetterscall — never a property of one row’s content. Row-content problems surface asreliar_outbox::PoisonedRows instead (ADR 0008). - Settings
Error - Why a
*Settings::from_envcall failed.OutboxSettings::from_env(reliar-outbox) was the first caller; every provider’s ownfrom_envreturns this same type (contract §7 I3).
Functions§
- migrate
- Applies Reliar’s migrations. Never invoked implicitly (SRS §35).