---
title: Extensions
description: Lifecycle hooks for jobs, workflows, cron, and shutdown events.
---

Extensions are notified of lifecycle events and can react to them — recording metrics, emitting webhooks, writing audit logs, etc.

Each lifecycle hook is a **separate interface**. Extensions only implement the interfaces they care about, and the `ext.Registry` fans events out to all registered extensions.

## Implementing an extension

```go
import (
    "github.com/xraph/dispatch/ext"
    "github.com/xraph/dispatch/job"
)

type AuditExtension struct {
    logger *slog.Logger
}

func (e *AuditExtension) Name() string { return "audit" }

// Job hooks (opt in by implementing the interface)
func (e *AuditExtension) OnJobCompleted(ctx context.Context, j *job.Job, elapsed time.Duration) error {
    e.logger.Info("job completed", "name", j.Name, "elapsed", elapsed)
    return nil
}

func (e *AuditExtension) OnJobFailed(ctx context.Context, j *job.Job, err error) error {
    e.logger.Error("job failed", "name", j.Name, "error", err)
    return nil
}
```

## Registering an extension

```go
eng := engine.Build(d,
    engine.WithExtension(&AuditExtension{logger: slog.Default()}),
    engine.WithExtension(observability.NewMetricsExtension()),
)
```

Multiple extensions can be registered. They are called in registration order for each event.

## Available hooks

### Job lifecycle

| Interface | Method | Triggered when |
|-----------|--------|----------------|
| `ext.JobEnqueued` | `OnJobEnqueued` | Job is accepted into the queue |
| `ext.JobStarted` | `OnJobStarted` | Worker begins executing |
| `ext.JobCompleted` | `OnJobCompleted` | Job finishes successfully |
| `ext.JobFailed` | `OnJobFailed` | Job fails with no retries remaining |
| `ext.JobRetrying` | `OnJobRetrying` | Job fails and is scheduled for retry |
| `ext.JobDLQ` | `OnJobDLQ` | Job is moved to the DLQ |

### Workflow lifecycle

| Interface | Method | Triggered when |
|-----------|--------|----------------|
| `ext.WorkflowStarted` | `OnWorkflowStarted` | Workflow run begins |
| `ext.WorkflowStepCompleted` | `OnWorkflowStepCompleted` | A step completes |
| `ext.WorkflowStepFailed` | `OnWorkflowStepFailed` | A step fails |
| `ext.WorkflowCompleted` | `OnWorkflowCompleted` | Workflow finishes successfully |
| `ext.WorkflowFailed` | `OnWorkflowFailed` | Workflow fails terminally |

### Other hooks

| Interface | Method | Triggered when |
|-----------|--------|----------------|
| `ext.CronFired` | `OnCronFired` | A cron entry fires and a job is enqueued |
| `ext.Shutdown` | `OnShutdown` | The dispatcher shuts down gracefully |

## Built-in extensions

| Extension | Package | Purpose |
|-----------|---------|---------|
| `MetricsExtension` | `observability` | OpenTelemetry counters for every lifecycle event |
| `RelayHookExtension` | `relay_hook` | Emit typed webhook events via Relay |
