Quickstart
Run the server, enqueue a job and watch a worker process it.
Start the server
First install sepp with one of the methods described in the install guide. Then run the server with:
./seppor with Docker:
docker run --rm \
-p 50051:50051 \
-v sepp-data:/sepp/sepp-data \
ghcr.io/sepp-org/sepp:latestThis starts sepp with the default configuration, listening on 0.0.0.0:50051 (all interfaces, no authentication — see security before exposing it) and persisting data to a sepp-data directory in the current working directory.
You can generate a config file to edit with sepp config example > sepp.toml. Sepp will pick it up automatically
as long as it is named sepp.toml and in the working directory the server is started from, or you can specify a custom path with the SEPP_CONFIG environment variable.
Talk to the server
First you need a client library. There are official clients for Rust, Python and Node.js. Sepp has a fairly simple gRPC line protocol, so you can also roll your own client in any language you want. See build your own client for more.
Enqueue a job
This simple example enqueues a single job with type job type onto the queue name queue. For more details and options, see the producer docs.
use sepp_rs::client::SeppClient;
use sepp_rs::EnqueueRequest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = SeppClient::connect("http://localhost:50051").await?;
let request = EnqueueRequest::new("queue name", "job type")?;
let response = client.enqueue(request).await?;
println!("Enqueued job with ID: {}", response.job_id);
Ok(())
}import asyncio
from sepp import SeppClient, EnqueueRequest
async def main() -> None:
client = await SeppClient.connect("http://localhost:50051")
request = EnqueueRequest("queue name", "job type")
response = await client.enqueue(request)
print(f"Enqueued job with ID: {response.job_id}")import { SeppClient, EnqueueRequest } from "sepp";
const client = await SeppClient.connect("http://localhost:50051");
const request: EnqueueRequest = {
queue: "queue name",
jobType: "job type",
};
const response: EnqueueAck = await client.enqueue(request);
console.log(`Enqueued job with ID: ${response.jobId}`);Reserve, process and ack
Getting a job from a queue is called reserving a job. Each reserved job has a lease attached to it. If the lease expires before the job is acknowledged, the server will consider this attempt as failed and makes the job available for reservation again. A successful job completion is acknowledged by sending an ack message to the server and a failed one by sending a nack.
The easiest way of processing jobs is to use the Worker abstraction which will automatically handle the reservation, processing and acknowledgment logic for you. For more details and options, see the worker docs.
use std::time::Duration;
use sepp_rs::client::SeppClient;
use sepp_rs::worker::Worker;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = SeppClient::connect("http://localhost:50051").await?;
let worker = Worker::new(client, ["queue name"], Duration::from_secs(30))?
.handle("job type", |payload, ctx| async move {
println!("Processing job with ID: {}", ctx.id);
// Do the work here
// Return Err(HandlerError) to nack and Ok(()) to ack.
Ok(())
})?;
worker.run().await;
Ok(())
}import asyncio
from datetime import timedelta
from sepp import SeppClient, Worker
async def main() -> None:
client = await SeppClient.connect("http://localhost:50051")
worker = Worker(client, ["queue name"], timedelta(seconds=30))
@worker.handler("job type")
async def handle(payload, ctx) -> None:
print(f"Processing job with ID: {ctx.id}")
# Do the work here
# Raise HandlerError to nack and return normally to ack.
await worker.run()import { SeppClient, Worker } from "sepp";
const client = await SeppClient.connect("http://localhost:50051");
const worker = new Worker(client, {
queues: ["queue name"],
leaseDuration: 30_000,
}).handle("job type", async (payload, ctx) => {
console.log(`Processing job with ID: ${ctx.id}`);
// Do the work here
// Throw HandlerError to nack and return normally to ack.
});
await worker.run();Watch it in the admin UI
The server you just started also serves a built-in web UI on http://localhost:9465. Open it to watch queue depths and rates update live as your producer and worker run,
inspect the jobs you just enqueued or enqueue more from the browser. When running in Docker, add -p 9465:9465 and log in with the demo key; see the admin UI guide for details.