DocsOperations
Background jobs
Run typed named work after a request using bounded workers, retries, timeouts, graceful shutdown, and production-safe telemetry.
Define the queue during startup
let queue = rahti::jobs::Jobs::new()
.capacity(1_024)
.workers(4)
.attempts(3)
.backoff(Duration::from_millis(250), Duration::from_secs(30))
.attempt_timeout(Duration::from_secs(20))
.shutdown_grace(Duration::from_secs(30))
.handler("send-receipt", |job: SendReceipt| async move {
send_receipt(job.order_id)
.await
.map_err(|error| JobError::retry(error.to_string()))
})
.start();Start the queue inside the Tokio runtime before building the router and keep its JobQueue handle in application-owned state. Defaults are one worker, capacity 1,024, three attempts, capped exponential backoff, a 30-second attempt timeout, and a 30-second shutdown grace.
Enqueue after the write commits
let order = save_order(input).await?;
jobs::queue()
.enqueue("send-receipt", SendReceipt { order_id: order.id })
.await?;enqueue waits for bounded capacity; try_enqueue returns Full immediately. Payloads serialize in memory, so include only stable identifiers and required data—not sessions, credentials, tokens, or unnecessary personal information.
Retry and idempotency
| Handler result | Outcome |
|---|---|
| Ok(()) | The job completed. |
| JobError::retry | Retry with capped exponential backoff. |
| JobError::discard | Stop immediately for permanent input or policy failure. |
| panic or timeout | Isolate the attempt and retry within the configured limit. |
Shutdown and durability
The scaffold drains jobs with jobs::finish_shutdown().await after HTTP shutdown. Metrics and events report queue, retry, timeout, panic, failure, and abandoned work without logging payloads. The queue is still in-memory and process-local: use a durable broker when accepted work must survive a crash, deployment, or machine failure.
