---
title: Jobs
description: Typed job definitions, the registry, state machine, retries, and backoff.
---

Jobs are the fundamental unit of work in Dispatch. A job definition is a typed Go function that processes a JSON payload.

## Defining a job

```go
import "github.com/xraph/dispatch/job"

type EmailInput struct {
    To      string `json:"to"`
    Subject string `json:"subject"`
    Body    string `json:"body"`
}

var SendEmail = job.NewDefinition("send_email",
    func(ctx context.Context, input EmailInput) error {
        return mailer.Send(input.To, input.Subject, input.Body)
    },
)
```

The generic type parameter `T` must be JSON-serializable. `NewDefinition` returns a `*Definition[T]` that carries both the name and the handler.

## Registering a job

Use `engine.Register` at startup:

```go
engine.Register(eng, SendEmail)
engine.Register(eng, GenerateReport)
engine.Register(eng, ProcessPayment)
```

Internally, `Register` calls `job.RegisterDefinition` on the engine's `*job.Registry`, converting the typed handler to a type-erased `HandlerFunc`.

## Enqueueing a job

```go
engine.Enqueue(ctx, eng, SendEmail, EmailInput{
    To:      "user@example.com",
    Subject: "Welcome!",
})
```

Additional enqueue options:

```go
// Schedule for the future
engine.EnqueueAt(ctx, eng, SendEmail, input, time.Now().Add(10*time.Minute))

// Set priority (higher = dequeued first)
engine.EnqueueWithPriority(ctx, eng, SendEmail, input, 10)

// Target a specific queue
engine.EnqueueOnQueue(ctx, eng, SendEmail, input, "critical")
```

## State machine

A job progresses through these states:

```
pending → running → completed
pending → running → retrying → pending → running → ...
pending → running → failed
pending → running → failed → dlq
pending → cancelled
```

| State | Meaning |
|-------|---------|
| `pending` | Waiting to be picked up |
| `running` | Currently executing |
| `completed` | Finished successfully |
| `retrying` | Failed but scheduled for retry |
| `failed` | Failed terminally (no retries remain) |
| `cancelled` | Explicitly cancelled |

## Retries and backoff

Configure retries on the job definition:

```go
var SendEmail = job.NewDefinition("send_email",
    handler,
    job.WithMaxRetries(5),
)
```

Configure the backoff strategy on the engine:

```go
eng := engine.Build(d,
    engine.WithBackoff(backoff.Exponential(
        backoff.WithBase(5*time.Second),
        backoff.WithMax(2*time.Hour),
    )),
)
```

After `MaxRetries` is exhausted, the job is moved to the DLQ.

## Job timeout

Set a per-job execution deadline:

```go
var SendEmail = job.NewDefinition("send_email",
    handler,
    job.WithTimeout(30*time.Second),
)
```

The `middleware.Timeout()` middleware enforces this via context cancellation.
