graphile_worker 0.13.3

High performance Rust/PostgreSQL job queue (also suitable for getting jobs generated by PostgreSQL triggers/functions out into a different work queue)
Documentation
# Quick Start

This page shows the smallest useful Graphile Worker RS setup: define one typed
task, register it with a worker, add a job, and start processing jobs.

## Add Dependencies

Graphile Worker RS runs against PostgreSQL. With the default Tokio runtime,
rustls TLS, and SQLx driver, a minimal application can connect with a database
URL and these dependencies:

```toml
[dependencies]
graphile_worker = "0.13"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
serde = { version = "1", features = ["derive"] }
```

## Define a Typed Task

A task is a Rust type that can be serialized into the job payload and
deserialized when the worker runs it. Implement `TaskHandler` for the payload
type and give it a stable identifier.

```rust,ignore
use graphile_worker::{IntoTaskHandlerResult, TaskHandler, WorkerContext};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
struct SendEmail {
    to: String,
    subject: String,
    body: String,
}

impl TaskHandler for SendEmail {
    const IDENTIFIER: &'static str = "send_email";

    async fn run(self, _ctx: WorkerContext) -> impl IntoTaskHandlerResult {
        println!("Sending '{}' to {}", self.subject, self.to);
        Ok::<(), String>(())
    }
}
```

The identifier is the task name stored in PostgreSQL. Jobs with this identifier
will be decoded as `SendEmail` and passed to `SendEmail::run`.

## Create and Run a Worker

Configure a PostgreSQL connection string, register the task with `define_job`,
initialize the worker, and call `run`.

```rust,ignore
use graphile_worker::WorkerOptions;

async fn run_worker() -> Result<(), Box<dyn std::error::Error>> {
    let worker = WorkerOptions::default()
        .database_url("postgres://postgres:password@localhost/mydb")
        .concurrency(5)
        .schema("graphile_worker")
        .define_job::<SendEmail>()
        .init()
        .await?;

    worker.run().await?;

    Ok(())
}
```

`init` connects to PostgreSQL, runs the worker migrations for the configured
schema, registers the task handlers, and returns a `Worker`. The schema defaults
to `graphile_worker` if you do not set one.

## Add a Job

After initialization, use `create_utils` to get `WorkerUtils`. Its `add_job`
method accepts the typed task payload and a `JobSpec`.

```rust,ignore
use graphile_worker::JobSpecBuilder;

let helpers = worker.create_utils();

helpers
    .add_job(
        SendEmail {
            to: "ada@example.com".to_string(),
            subject: "Welcome".to_string(),
            body: "Thanks for signing up.".to_string(),
        },
        JobSpecBuilder::new().build(),
    )
    .await?;
```

For scheduled jobs, set `run_at` on the job spec before building it. This
example uses `chrono`; add it to your application if you schedule from Rust
timestamps:

```rust,ignore
use chrono::{Duration, offset::Utc};
use graphile_worker::JobSpecBuilder;

helpers
    .add_job(
        SendEmail {
            to: "ada@example.com".to_string(),
            subject: "Welcome".to_string(),
            body: "Thanks for signing up.".to_string(),
        },
        JobSpecBuilder::new()
            .run_at(Utc::now() + Duration::seconds(10))
            .build(),
    )
    .await?;
```

## Complete Shape

This combines the pieces into one application shape. In a real application you
can add jobs from request handlers, services, or startup code while one or more
workers process them.

```rust,ignore
use graphile_worker::{
    IntoTaskHandlerResult, JobSpecBuilder, TaskHandler, WorkerContext, WorkerOptions,
};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
struct SendEmail {
    to: String,
    subject: String,
    body: String,
}

impl TaskHandler for SendEmail {
    const IDENTIFIER: &'static str = "send_email";

    async fn run(self, _ctx: WorkerContext) -> impl IntoTaskHandlerResult {
        println!("Sending '{}' to {}", self.subject, self.to);
        Ok::<(), String>(())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let worker = WorkerOptions::default()
        .database_url("postgres://postgres:password@localhost/mydb")
        .concurrency(5)
        .schema("graphile_worker")
        .define_job::<SendEmail>()
        .init()
        .await?;

    worker
        .create_utils()
        .add_job(
            SendEmail {
                to: "ada@example.com".to_string(),
                subject: "Welcome".to_string(),
                body: "Thanks for signing up.".to_string(),
            },
            JobSpecBuilder::new().build(),
        )
        .await?;

    worker.run().await?;

    Ok(())
}
```

For a runnable example in the repository, see `examples/simple.rs`. For more
configuration options, continue with [Configuration](../configuration/index.md).