Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Apalis: Orientation

Background jobsTower + runtime injectionRevision 70f1109

Apalis turns an ordinary async function into the center of a durable job worker. Around that small function it composes a backend, typed extraction, Tower middleware, readiness, bounded concurrency, acknowledgement, retry, events, and cooperative shutdown.

async fn send_email(job: Email, state: Data<Arc<App>>) -> Result<(), MailError> {
    state.mailer.send(job).await
}

let worker = WorkerBuilder::new("email")
    .backend(storage)
    .data(app)
    .concurrency(16)
    .parallelize(tokio::spawn)
    .build(send_email);

The architectural center is not the syntax of send_email. It is this admission rule:

A backend may release the next durable task only when the composed service is ready to own it.

That connects storage semantics to Tower backpressure without making either side implement the other.

Design thesis

Apalis keeps application handlers ordinary while concentrating durable job policy in typed backend and Tower middleware boundaries.

  • Payloads move into handlers so their futures can run independently.
  • Service readiness is checked before durable work is claimed.
  • Backends own encoding, polling, locking, and acknowledgement semantics.
  • Generics describe the hot path; type erasure appears at heterogeneous edges.

We will preserve ordinary async handlers, owned task payloads, typed context extraction, backend-independent execution, readiness before dequeue, middleware-defined policy, tracked completion, and graceful drain.