pub struct PostgresTaskStore { /* private fields */ }Expand description
PostgreSQL durable-task attribution with atomic, once-only claims.
Implementations§
Source§impl PostgresTaskStore
impl PostgresTaskStore
Sourcepub fn new(pool: PgPool, ttl: Duration) -> Result<Self, StoreConfigError>
pub fn new(pool: PgPool, ttl: Duration) -> Result<Self, StoreConfigError>
Construct a store from an application-owned connection pool.
ttl must outlive the longest task the upstream server can run, not
the client’s polling interval. A task that outlives it bills zero. See
the crate-level notes.
§Errors
Returns StoreConfigError::InvalidTtl when the TTL is zero or cannot
be represented by PostgreSQL’s signed interval input.
Sourcepub fn with_timeout(
pool: PgPool,
ttl: Duration,
operation_timeout: Duration,
) -> Result<Self, StoreConfigError>
pub fn with_timeout( pool: PgPool, ttl: Duration, operation_timeout: Duration, ) -> Result<Self, StoreConfigError>
Construct a store with an explicit bound for every database operation.
§Errors
Returns a configuration error for an invalid TTL or zero timeout.
Sourcepub async fn install(&self) -> Result<(), StoreConfigError>
pub async fn install(&self) -> Result<(), StoreConfigError>
Install the idempotent table and expiry index.
Safe to call concurrently from every instance of a horizontally scaled
application, which is the situation this store exists for. CREATE TABLE IF NOT EXISTS is not atomic in PostgreSQL: racing sessions check the
catalog, all decide the table is absent, and every loser fails with a
duplicate key violation on pg_type_typname_nsp_index. A transaction
scoped advisory lock serializes the check so late arrivals simply find
the table already present and do nothing.
Applications with migration-controlled schemas can apply
schema/postgres.sql themselves and skip this operation.
§Errors
Returns a sanitized schema error without exposing connection details.
Sourcepub async fn prune_expired(&self) -> Result<u64, TaskStoreError>
pub async fn prune_expired(&self) -> Result<u64, TaskStoreError>
Delete expired task origins and return the affected row count.
The application must call this on a timer. Unlike Redis, Postgres
has no native expiry: every read filters on expires_at, so nothing is
served stale, but the rows themselves stay until something deletes
them and the table otherwise grows without bound.
§Errors
Returns a sanitized backend error.
Trait Implementations§
Source§impl Clone for PostgresTaskStore
impl Clone for PostgresTaskStore
Source§impl Debug for PostgresTaskStore
impl Debug for PostgresTaskStore
Source§impl TaskAttributionStore for PostgresTaskStore
impl TaskAttributionStore for PostgresTaskStore
Source§fn insert<'a>(
&'a self,
tenant_id: &'a str,
task_id: &'a str,
attribution: TaskAttribution,
) -> TaskStoreFuture<'a, ()>
fn insert<'a>( &'a self, tenant_id: &'a str, task_id: &'a str, attribution: TaskAttribution, ) -> TaskStoreFuture<'a, ()>
Source§fn get<'a>(
&'a self,
tenant_id: &'a str,
task_id: &'a str,
) -> TaskStoreFuture<'a, Option<TaskAttribution>>
fn get<'a>( &'a self, tenant_id: &'a str, task_id: &'a str, ) -> TaskStoreFuture<'a, Option<TaskAttribution>>
Source§fn claim<'a>(
&'a self,
tenant_id: &'a str,
task_id: &'a str,
) -> TaskStoreFuture<'a, Option<TaskAttribution>>
fn claim<'a>( &'a self, tenant_id: &'a str, task_id: &'a str, ) -> TaskStoreFuture<'a, Option<TaskAttribution>>
Auto Trait Implementations§
impl !RefUnwindSafe for PostgresTaskStore
impl !UnwindSafe for PostgresTaskStore
impl Freeze for PostgresTaskStore
impl Send for PostgresTaskStore
impl Sync for PostgresTaskStore
impl Unpin for PostgresTaskStore
impl UnsafeUnpin for PostgresTaskStore
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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