Documentation
¶
Overview ¶
Package middleware provides composable middleware for job execution.
A Middleware is a function that wraps a job handler. Middleware are composed into a chain using Chain and applied before each job executes. They are applied right-to-left: the first middleware in the slice is the outermost wrapper.
// logging → recover → handler chain := middleware.Chain(middleware.Logging(logger), middleware.Recover())
Built-in Middleware ¶
- Logging — logs job name, queue, duration, and outcome at each execution
- Recover — catches panics and converts them to errors
- Timeout — cancels the job context after a configured duration
- Tracing — wraps execution in an OpenTelemetry span
- Metrics — records per-job duration and outcome counters
- Scope — extracts Forge app/org IDs from the job and injects them into context
Writing Custom Middleware ¶
func MyMiddleware() middleware.Middleware {
return func(ctx context.Context, j *job.Job, next middleware.Handler) error {
// pre-processing
err := next(ctx)
// post-processing
return err
}
}
Middleware MUST call next to continue the chain unless intentionally short-circuiting (e.g., circuit breaker, rate limiting).
Package middleware provides composable middleware for job execution. Middleware wraps handler calls synchronously and can modify execution (recover from panics, inject scope, log, add tracing, etc.).
Index ¶
- type Handler
- type Middleware
- func Chain(mws ...Middleware) Middleware
- func Logging(logger log.Logger) Middleware
- func Metrics() Middleware
- func MetricsWithFactory(factory gu.MetricFactory) Middleware
- func Recover(logger log.Logger) Middleware
- func Scope() Middleware
- func Timeout(logger log.Logger) Middleware
- func Tracing() Middleware
- func TracingWithTracer(tracer trace.Tracer) Middleware
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Middleware ¶
Middleware wraps a Handler with cross-cutting logic. It receives the current context, the job being executed, and the next handler to call. Middleware MUST call next to continue the chain (unless short-circuiting on error).
func Chain ¶
func Chain(mws ...Middleware) Middleware
Chain composes multiple middleware into a single Middleware. Middleware are applied right-to-left: the first middleware in the list is the outermost wrapper.
Example: Chain(logging, recover, scope) executes as:
logging → recover → scope → handler
func Logging ¶
func Logging(logger log.Logger) Middleware
Logging returns middleware that logs job start and completion.
func Metrics ¶
func Metrics() Middleware
Metrics returns middleware that records per-job execution metrics using a default metrics collector. For forge-managed dispatch instances, prefer MetricsWithFactory(fapp.Metrics()) so metrics are reported through forge.
Instruments:
- dispatch.job.duration (Histogram): execution time in seconds
- dispatch.job.executions (Counter): total executions
func MetricsWithFactory ¶
func MetricsWithFactory(factory gu.MetricFactory) Middleware
MetricsWithFactory returns metrics middleware using the provided MetricFactory. This variant allows injecting a specific factory for testing or forge integration.
func Recover ¶
func Recover(logger log.Logger) Middleware
Recover returns middleware that recovers from panics in the handler chain. Panics are converted to errors and logged with a stack trace.
func Scope ¶
func Scope() Middleware
Scope returns middleware that restores multi-tenant scope from the job's ScopeAppID/ScopeOrgID fields into the context. This ensures handlers see the same forge.Scope as the original enqueue caller.
func Timeout ¶
func Timeout(logger log.Logger) Middleware
Timeout returns middleware that enforces a per-job execution deadline. If the job has a non-zero Timeout, a context.WithTimeout wraps the handler call. When the deadline is exceeded the context is cancelled and the handler should return context.DeadlineExceeded.
func Tracing ¶
func Tracing() Middleware
Tracing returns middleware that wraps the rest of the chain, and the handler, in an OpenTelemetry span named "run job handler". If no TracerProvider is configured globally, the default noop tracer is used and this middleware becomes a pass-through with zero overhead.
Inside an engine the worker pool already gives every attempt a root "process job" span, and this span is its child. Span attributes include: dispatch.job.id, dispatch.job.name, dispatch.queue, dispatch.retry_count, dispatch.scope.app_id, dispatch.scope.org_id. When the handler fails the span gets an Error status with a fixed description and an exception event carrying only exception.type. The error's message is never recorded: a handler error can quote its payload. A handler that panics gets the status class "panic" and exception.type "panic", and the panic continues to the Recover middleware.
func TracingWithTracer ¶
func TracingWithTracer(tracer trace.Tracer) Middleware
TracingWithTracer returns tracing middleware using the provided tracer. This variant allows injecting a specific TracerProvider for testing or when multiple providers are in use.