Documentation
¶
Overview ¶
Package decorator provides one generic implementation of the cross-cutting decorator stack (timeout, circuit breaker, metrics, tracing, logging, recovery) shared by every tier whose unit of work has the shape Execute(ctx, In) (Out, error) — pipelines and workflows today. Each tier keeps its own fluent builder (and therefore its own wrap order (ARCHITECTURE.md#decorator-order) and its tier-specific labels/recovery behavior); this package holds the decorator implementations those builders compose, so a decorator fix is made once instead of once per tier.
The constructors take a caller-supplied inner Executor and return a decorated Executor — the builder chooses the order, this package does not hardcode one. Every returned decorator also implements Unwrapper so a test can reach the underlying handler through the stack.
Index ¶
- Variables
- type Executor
- func CircuitBreaker[In, Out any](inner Executor[In, Out], cb interfaces.CircuitBreaker, ...) Executor[In, Out]
- func Logging[In, Out any](inner Executor[In, Out], logger interfaces.Logger, tier, name string) Executor[In, Out]
- func Metrics[In, Out any](inner Executor[In, Out], tier, name string, m interfaces.Metrics, ...) Executor[In, Out]
- func Recovery[In, Out any](inner Executor[In, Out], logger interfaces.Logger, tier, name string, ...) Executor[In, Out]
- func Timeout[In, Out any](inner Executor[In, Out], d time.Duration) Executor[In, Out]
- func Tracing[In, Out any](inner Executor[In, Out], tracer interfaces.Tracer, tier, name string) Executor[In, Out]
- type Unwrapper
Constants ¶
This section is empty.
Variables ¶
var DefaultBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
DefaultBuckets are the default histogram bucket boundaries (in seconds) for execution-duration metrics.
Functions ¶
This section is empty.
Types ¶
type Executor ¶
type Executor[In any, Out any] interface { // Execute runs the wrapped unit of work for input, returning its result or an error. Execute(ctx context.Context, input In) (Out, error) }
Executor is the single-method shape the decorators wrap. interfaces.Pipeline and interfaces.Workflow have the identical method set, so one decorator set serves both tiers (and any future Execute(ctx, In) (Out, error) tier).
interface-composition exemption — decoration mechanism primitive: the generic Execute(ctx, In) (Out, error) shape the decorators wrap, not an id-CRUD data-access surface, so it embeds no foundation generic.
func CircuitBreaker ¶ added in v0.3.2
func CircuitBreaker[In, Out any](inner Executor[In, Out], cb interfaces.CircuitBreaker, onOpen func(error) error) Executor[In, Out]
CircuitBreaker returns inner run through cb. When cb rejects the call without running inner (an open breaker), Execute returns onOpen(err) so the tier can code the rejection; an error from inner itself passes through unchanged.
func Logging ¶
func Logging[In, Out any]( inner Executor[In, Out], logger interfaces.Logger, tier, name string, ) Executor[In, Out]
Logging returns inner wrapped with entry/failure logging at Debug level (the error is logged once at the transport layer in staging/prod). tier is both the log-message prefix (tier+".Execute") and the field key; name is the field value.
func Metrics ¶
func Metrics[In, Out any]( inner Executor[In, Out], tier, name string, m interfaces.Metrics, buckets []float64, ) Executor[In, Out]
Metrics returns inner wrapped with execution-count, error-count, and duration-histogram metrics. tier prefixes the metric names (tier+"_executions_total" etc.) and is the label key (e.g. "pipeline"); name is the label value — the per-instance pipeline/workflow name — so each instance is its own time series (passing tier as the value would collapse every instance into one mislabeled series).
func Recovery ¶
func Recovery[In, Out any]( inner Executor[In, Out], logger interfaces.Logger, tier, name string, onPanic func(name string, r any) error, ) Executor[In, Out]
Recovery returns inner wrapped with panic recovery (always outermost in the tier builders' order, ARCHITECTURE.md#decorator-order). A recovered panic is logged as tier+" panic recovered" and the returned error is produced by onPanic, so each tier keeps its own recovery-error contract (a coded error, a plain wrap, …). A nil onPanic falls back to a generic wrapped error, so the recovery path never itself panics on a missing contract.
func Timeout ¶
Timeout returns inner wrapped with a per-execution context deadline. A slow execution is cancelled via context when the deadline elapses.
func Tracing ¶
func Tracing[In, Out any]( inner Executor[In, Out], tracer interfaces.Tracer, tier, name string, ) Executor[In, Out]
Tracing returns inner wrapped with a trace span per execution, named name+".Execute" and carrying the tier+".name" attribute, so the request cascade is visible in Tempo.
type Unwrapper ¶
type Unwrapper[In any, Out any] interface { // Unwrap returns the inner Executor this decorator wraps. Unwrap() Executor[In, Out] }
Unwrapper exposes the inner Executor a decorator wraps, so a test can reach the underlying handler through the decorator stack (the Unwrap seam). Every decorator constructed here implements it.
interface-composition exemption — decoration mechanism primitive: a single Unwrap() → Executor introspection port, not an id-CRUD data-access surface, so it embeds no foundation generic.