Documentation
¶
Overview ¶
Package middleware provides composable handlers that wrap Bus.Subscribe and Bus.Invoke calls with cross-cutting concerns: panic recovery, structured logging, trace propagation, retry, etc.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConstantBackoff ¶
ConstantBackoff returns a backoff function that always sleeps d.
func ExponentialBackoff ¶
ExponentialBackoff returns a backoff function that doubles the delay on every attempt, capped at max.
func IsRetryableError ¶
IsRetryableError reports whether err (or any error in its chain) was created with Retryable.
Types ¶
type DLQSink ¶
DLQSink receives a failed envelope together with the last error. Implementations typically clone the envelope, stamp DLQ metadata, and publish it to a dead-letter subject. Returning an error from the sink does not swallow the original failure; the middleware wraps both errors so callers still observe the handler error.
type Handler ¶
Handler is the inner handler type middleware operates on. It mirrors bus.Handler but is duplicated here to avoid an import cycle (bus imports middleware, not the other way around).
func Chain ¶
func Chain(h Handler, mws ...Middleware) Handler
Chain composes mws around h. The returned Handler runs middlewares in the order they were supplied (mws[0] is outer-most).
type Middleware ¶
Middleware wraps a Handler with cross-cutting behavior. The outer-most middleware in a chain runs first.
func DeadLetter ¶
func DeadLetter(sink DLQSink) Middleware
DeadLetter wraps a handler so that any returned error is forwarded to sink before being propagated upward. If sink itself fails, the original error is preserved and wrapped with the DLQ publish error.
func Logging ¶
func Logging(logger *slog.Logger) Middleware
Logging emits a structured log line per handler invocation. nil logger falls back to slog.Default.
func Recover ¶
func Recover() Middleware
Recover catches panics in downstream handlers, converts them to errors, and logs the stack trace. It is the recommended outer-most middleware on every chain.
func Retry ¶
func Retry(policy RetryPolicy) Middleware
Retry wraps a handler so that transient failures are retried according to policy. On each attempt the envelope metadata key "acp.retry.attempt" is updated so downstream observers can see the current attempt count.
func Trace ¶
func Trace() Middleware
Trace injects the envelope into ctx so downstream handlers (and any nested Bus calls) can propagate trace_id / session_id without re-parsing the message. v0.2 will add an OTelTrace middleware that additionally bridges to OpenTelemetry SpanContext via the envelope's traceparent field.
type RetryPolicy ¶
type RetryPolicy struct {
// MaxAttempts is the total number of times the handler may be invoked.
// Defaults to 1 if ≤ 0.
MaxAttempts int
// Backoff returns the delay to wait before attempt N (1-based).
// If nil, retries happen immediately.
Backoff func(attempt int) time.Duration
// IsRetryable decides whether an error warrants a retry.
// If nil, all errors are considered retryable.
IsRetryable func(error) bool
}
RetryPolicy configures how many times a handler may be retried and with what backoff strategy. A zero-value policy is usable: it defaults to one attempt (no retry) and zero backoff.