pub struct PersistentJobQueue { /* private fields */ }jobs and (crate features model-mysql or model-postgres or model-sqlite) only.Expand description
A job queue backed by the model layer (model-sqlite / model-postgres /
model-mysql): jobs are written to a rws_jobs table before being
acknowledged, so pending and retrying jobs survive a process crash or
restart.
Unlike JobQueue, a job here can’t be an arbitrary closure — a closure
can’t be serialized to disk. Instead the queue stores (job_type, payload) as plain text and dispatches to a handler registered for that
job_type at execution time. Register every handler you enqueue before
calling start, including after a restart — unprocessed
rows from a previous run (and any row left running when the process
crashed) are picked up automatically.
CREATE TABLE IF NOT EXISTS rws_jobs (
id TEXT PRIMARY KEY,
job_type TEXT NOT NULL,
payload TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'pending', -- pending | running | failed
attempts INTEGER NOT NULL DEFAULT 0,
max_retries INTEGER NOT NULL DEFAULT 3,
next_run_at INTEGER NOT NULL,
created_at INTEGER NOT NULL,
last_error TEXT
)Completed jobs are deleted; a job that exhausts its retries is left with
status = 'failed' for inspection instead of being deleted.
Implementations§
Source§impl PersistentJobQueue
impl PersistentJobQueue
Sourcepub async fn new(pool: DbPool) -> Result<Self, DbError>
pub async fn new(pool: DbPool) -> Result<Self, DbError>
Creates the queue and its backing rws_jobs table if absent, then
resets any row left running (interrupted by a previous crash) back
to pending so it gets picked up again.
Sourcepub fn max_retries(self, n: u32) -> Self
pub fn max_retries(self, n: u32) -> Self
Override the default retry count applied to jobs enqueued via
enqueue (default: 3). Use
enqueue_with_retries for a per-job override.
Sourcepub fn poll_interval(self, interval: Duration) -> Self
pub fn poll_interval(self, interval: Duration) -> Self
Override how often idle workers poll for due jobs (default: 500 ms).
Sourcepub fn backoff(self, initial: Duration, multiplier: u32) -> Self
pub fn backoff(self, initial: Duration, multiplier: u32) -> Self
Override the backoff policy applied between retries: initial delay
before the first retry, doubled (or scaled by multiplier) on each
subsequent attempt. Default: 500 ms initial, 2x multiplier.
Sourcepub fn register(
&self,
job_type: &str,
handler: impl Fn(&str) -> Result<(), String> + Send + Sync + 'static,
)
pub fn register( &self, job_type: &str, handler: impl Fn(&str) -> Result<(), String> + Send + Sync + 'static, )
Register the function that executes jobs of job_type. Call before
start — jobs enqueued for an unregistered job_type
fail immediately (and retry, same as any other handler error).
Sourcepub async fn enqueue(
&self,
job_type: &str,
payload: &str,
) -> Result<String, DbError>
pub async fn enqueue( &self, job_type: &str, payload: &str, ) -> Result<String, DbError>
Persist a new job using the queue’s default retry count. Returns the generated job id.
Sourcepub async fn enqueue_with_retries(
&self,
job_type: &str,
payload: &str,
max_retries: u32,
) -> Result<String, DbError>
pub async fn enqueue_with_retries( &self, job_type: &str, payload: &str, max_retries: u32, ) -> Result<String, DbError>
Persist a new job with a per-job retry override.
Sourcepub async fn tick(&self) -> Result<bool, DbError>
pub async fn tick(&self) -> Result<bool, DbError>
Run one poll-claim-execute cycle. Returns Ok(true) if a job was
claimed (whether it succeeded, failed, or is retrying), Ok(false) if
none was due. Exposed for tests and for embedding in a caller-owned
loop; most applications should use start instead.
Sourcepub fn start(self: Arc<Self>, workers: usize) -> Vec<JoinHandle<()>>
pub fn start(self: Arc<Self>, workers: usize) -> Vec<JoinHandle<()>>
Spawn workers background OS threads, each running its own
single-threaded Tokio runtime, polling for due jobs at
poll_interval (default: 500 ms) whenever the
queue is empty. Returns the thread handles; call
stop then join them for a graceful shutdown.
Auto Trait Implementations§
impl !Freeze for PersistentJobQueue
impl !RefUnwindSafe for PersistentJobQueue
impl !UnwindSafe for PersistentJobQueue
impl Send for PersistentJobQueue
impl Sync for PersistentJobQueue
impl Unpin for PersistentJobQueue
impl UnsafeUnpin for PersistentJobQueue
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> 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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ServiceExt for T
impl<T> ServiceExt for T
Source§fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
map-response-body only.Source§fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
trace only.Source§fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
trace only.