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:
[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.
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.
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.
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:
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.
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.