#[non_exhaustive]pub struct PostgresInboxStore { /* private fields */ }Expand description
Reliar’s PostgreSQL inbox provider (inbox contract §3). A separate type from
crate::PostgresOutboxStore: the inbox stores no payload, so it needs no Serializer type
parameter and none of the outbox’s lease/ordering/retention settings. Same crate, same schema,
same crate::migrate. Cheap to clone — wraps a sqlx::PgPool; no outer Arc required.
Implementations§
Source§impl PostgresInboxStore
impl PostgresInboxStore
Sourcepub fn new(pool: PgPool) -> Self
pub fn new(pool: PgPool) -> Self
Wraps pool with PostgresInboxSettings::default. Performs no I/O: it issues no
query, opens no connection and verifies nothing about the database. The pool stays the
host’s.
Call crate::migrate (or apply the published SQL through your own pipeline) before
the first store call, and make sure the connection’s search_path resolves the
unqualified name inbox to the migrated schema — see the crate docs. An un-migrated or
unreachable table surfaces at the first statement as
PostgresInboxError::NotMigrated, never here.
use reliar_store_postgres::PostgresInboxStore;
use sqlx::postgres::PgPoolOptions;
let pool = PgPoolOptions::new()
.connect(&std::env::var("DATABASE_URL")?)
.await?;
let store = PostgresInboxStore::new(pool);Sourcepub fn with_settings(
pool: PgPool,
settings: PostgresInboxSettings,
) -> Result<Self, PostgresInboxError>
pub fn with_settings( pool: PgPool, settings: PostgresInboxSettings, ) -> Result<Self, PostgresInboxError>
As Self::new, with explicit settings. Performs no I/O beyond the settings’ own
validation, which never touches the database.
§Errors
PostgresInboxError::InvalidSettings when settings.max_attempts == 0 — the one
rejection this crate can make without asking the database (ADR 0042 A.2.4).
use reliar_store_postgres::{PostgresInboxSettings, PostgresInboxStore};
use sqlx::postgres::PgPoolOptions;
let pool = PgPoolOptions::new()
.connect(&std::env::var("DATABASE_URL")?)
.await?;
let store = PostgresInboxStore::with_settings(
pool,
PostgresInboxSettings::default().max_attempts(5),
)?;Trait Implementations§
Source§impl Clone for PostgresInboxStore
impl Clone for PostgresInboxStore
Source§fn clone(&self) -> PostgresInboxStore
fn clone(&self) -> PostgresInboxStore
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PostgresInboxStore
impl Debug for PostgresInboxStore
Source§impl InboxDeadLetters for PostgresInboxStore
impl InboxDeadLetters for PostgresInboxStore
Source§fn list_dead(
&self,
query: InboxDeadQuery,
) -> impl Future<Output = Result<Vec<InboxRecord>, Self::Error>> + Send
fn list_dead( &self, query: InboxDeadQuery, ) -> impl Future<Output = Result<Vec<InboxRecord>, Self::Error>> + Send
ORDER BY dead_at, id is normative: database-authored death time is the keyset’s leading
column, and the unique row id breaks ties.
Source§type Error = PostgresInboxError
type Error = PostgresInboxError
Source§fn retry_dead(
&self,
ids: &[InboxRecordId],
) -> impl Future<Output = Result<u64, Self::Error>> + Send
fn retry_dead( &self, ids: &[InboxRecordId], ) -> impl Future<Output = Result<u64, Self::Error>> + Send
dead_at, resets attempts to 0, keeps last_error for audit, sets
updated_at = now(). Affects only rows with dead_at IS NOT NULL. Returns the number of
rows affected. Read moreSource§fn purge_dead(
&self,
ids: &[InboxRecordId],
) -> impl Future<Output = Result<u64, Self::Error>> + Send
fn purge_dead( &self, ids: &[InboxRecordId], ) -> impl Future<Output = Result<u64, Self::Error>> + Send
Source§impl<'c> InboxStore<Transaction<'c, Postgres>> for PostgresInboxStore
impl<'c> InboxStore<Transaction<'c, Postgres>> for PostgresInboxStore
Source§fn claim(
&self,
tx: &mut Transaction<'c, Postgres>,
scope: &InboxScope,
message: InboxMessage<'_>,
) -> impl Future<Output = Result<InboxClaim, Self::Error>> + Send
fn claim( &self, tx: &mut Transaction<'c, Postgres>, scope: &InboxScope, message: InboxMessage<'_>, ) -> impl Future<Output = Result<InboxClaim, Self::Error>> + Send
The three-statement claim (inbox contract §3.1): the in-flight advisory-lock guard, the
INSERT … ON CONFLICT DO NOTHING claim, and — only when nothing was inserted — the state
read that decides AlreadyCompleted/Dead vs. Claimed. The three statements themselves
live in claim_locked, below.
Source§fn complete(
&self,
tx: &mut Transaction<'c, Postgres>,
scope: &InboxScope,
id: MessageId,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn complete( &self, tx: &mut Transaction<'c, Postgres>, scope: &InboxScope, id: MessageId, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Marks the row completed in the caller’s transaction. Zero rows affected ⇒ NotClaimed
(including a row that has since gone dead — the guard is completed_at IS NULL AND dead_at IS NULL).
Source§fn fail(
&self,
scope: &InboxScope,
message: InboxMessage<'_>,
error: &(dyn Error + 'static),
) -> impl Future<Output = Result<InboxFailure, Self::Error>> + Send
fn fail( &self, scope: &InboxScope, message: InboxMessage<'_>, error: &(dyn Error + 'static), ) -> impl Future<Output = Result<InboxFailure, Self::Error>> + Send
Records a failed attempt on this store’s own pool, guarded by completed_at IS NULL, and
bounds it at settings.max_attempts atomically with the increment (ADR 0042 A.2.4).
Source§async fn find(
&self,
scope: &InboxScope,
id: MessageId,
) -> Result<Option<InboxRecord>, PostgresInboxError>
async fn find( &self, scope: &InboxScope, id: MessageId, ) -> Result<Option<InboxRecord>, PostgresInboxError>
Reads a row for diagnostics. No Reliar code path calls it. No span — the inbox contract’s
observability table (§4) does not list find, since no Reliar code path calls it.
Source§fn purge(
&self,
request: InboxPurgeRequest,
) -> impl Future<Output = Result<InboxPurgeReport, Self::Error>> + Send
fn purge( &self, request: InboxPurgeRequest, ) -> impl Future<Output = Result<InboxPurgeReport, Self::Error>> + Send
One bounded pass, three statements, each capped at request.batch_size: the
completed-row, incomplete-row and dead-row deletes.
Source§type Error = PostgresInboxError
type Error = PostgresInboxError
Classify so a caller can log a permanent failure
differently from a transient one without a downcast.Source§fn process<H>(
&self,
tx: &mut Tx,
scope: &InboxScope,
message: InboxMessage<'_>,
handler: &H,
) -> impl Future<Output = Result<InboxOutcome<<H as InboxHandler<Tx>>::Output>, InboxProcessError<Self::Error, <H as InboxHandler<Tx>>::Error>>> + Send
fn process<H>( &self, tx: &mut Tx, scope: &InboxScope, message: InboxMessage<'_>, handler: &H, ) -> impl Future<Output = Result<InboxOutcome<<H as InboxHandler<Tx>>::Output>, InboxProcessError<Self::Error, <H as InboxHandler<Tx>>::Error>>> + Send
handler, complete. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for PostgresInboxStore
impl !UnwindSafe for PostgresInboxStore
impl Freeze for PostgresInboxStore
impl Send for PostgresInboxStore
impl Sync for PostgresInboxStore
impl Unpin for PostgresInboxStore
impl UnsafeUnpin for PostgresInboxStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more