Expand description
§rainier-queue
Deferred work: the Job contract, the Queue port and its drivers, and
the Worker that runs them.
use rainier_queue::{Job, JobContext, JobRegistry, MemoryQueue, Queue, QueueManager};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Serialize, Deserialize)]
struct SendWelcomeEmail { user_id: u64 }
#[async_trait::async_trait]
impl Job for SendWelcomeEmail {
const NAME: &'static str = "mail.welcome";
const QUEUE: &'static str = "mail";
async fn handle(&self, _context: &JobContext) -> rainier_support::Result<()> {
Ok(())
}
}
let registry = Arc::new(JobRegistry::new().with::<SendWelcomeEmail>());
let queue = Arc::new(MemoryQueue::new());
let dispatcher = QueueManager::new(queue.clone(), registry);
dispatcher.dispatch(SendWelcomeEmail { user_id: 1 }).await?;
assert_eq!(queue.size("mail").await?, 1);§A job crosses a process boundary
Everything about the design follows from that. A job is written by a web
request and read, later, by a worker that may be a different process on a
different machine — so a job is a serialisable payload plus a stable
name, not a closure, and the worker needs a JobRegistry to turn the
name back into code. Dependencies cannot be captured either, so a running
job resolves them from the container through its JobContext.
§Drivers
| Driver | Survives a restart | For |
|---|---|---|
SyncQueue | — runs inline | development, and tests that want the side effect |
MemoryQueue | no | tests, single-process development |
DatabaseQueue | yes | production, on the database you already have |
SqsQueue | yes | production, managed — needs the sqs feature |
§Testing
QueueManager::fake records dispatches instead of performing them:
let queue = QueueManager::fake();
queue.dispatch(SendInvoice).await?;
queue.assert_pushed_times::<SendInvoice>(1);Re-exports§
pub use database::DatabaseQueue;pub use database::FailedJobRow;pub use database::JobRow;pub use driver::QueueDriver;pub use job::Job;pub use job::JobContext;pub use job::JobRegistry;pub use job::QueuedJob;pub use manager::PendingDispatch;pub use manager::QueueManager;pub use manager::SyncQueue;pub use queue::FailedJob;pub use queue::MemoryQueue;pub use queue::Queue;pub use worker::JobFailed;pub use worker::JobProcessed;pub use worker::JobProcessing;pub use worker::JobReleased;pub use worker::Outcome;pub use worker::Worker;pub use worker::WorkerOptions;pub use worker::WorkerStats;
Modules§
- database
- The
DatabaseQueuedriver — jobs that survive a restart. - driver
- Where queued jobs wait —
QueueDriver. - job
- Jobs — the
Jobcontract, the serialisedQueuedJobpayload, and theJobRegistrythat turns one back into the other. - manager
- Dispatching — the
QueueManagerfacade accessor and theSyncQueuedriver. - queue
- The
Queueport and its in-process drivers. - worker
- The
Workerloop, and the events it fires.