Documentation
¶
Overview ¶
Package interceptorcore holds the framework-agnostic resilience decisions shared by the gRPC and Connect interceptor stacks. The two stacks keep their own packages — the two-stack split is intentional and stays — and each becomes a thin adapter that translates its framework's call signature and status codes to/from the primitives here. The retry classification, the circuit-breaker gate, the bulkhead load-shed decision, and the timeout classification therefore live once instead of being re-implemented per stack.
The framework-specific pieces stay in the adapters: the call closure (which invokes the framework's next/invoker/streamer), the code map that decides which errors are permanent, and the construction of the framework's error (gRPC status vs Connect error). This package depends only on core/interfaces and the stdlib, so it sits cleanly in the clients tier below both stacks.
Index ¶
- func Bulkhead(bh interfaces.Bulkhead, call func() error) (ran bool, err error)
- func CircuitBreak(cb interfaces.CircuitBreaker, call func() error) (rejected bool, innerErr error)
- func Retry(ctx context.Context, retrier interfaces.Retrier, isPermanent func(error) bool, ...) (permanent, exhausted error)
- type TimeoutClass
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bulkhead ¶
func Bulkhead(bh interfaces.Bulkhead, call func() error) (ran bool, err error)
Bulkhead runs call under bh only when a concurrency slot is free. It returns ran=false when load was shed (call never ran), with err the bulkhead's rejection error — the adapter maps that to ResourceExhausted; otherwise ran=true and err is the call's own error. The ran flag keeps the adapter on the Bulkhead interface, not its internal full-sentinel.
func CircuitBreak ¶
func CircuitBreak( cb interfaces.CircuitBreaker, call func() error, ) (rejected bool, innerErr error)
CircuitBreak runs call under cb. It returns rejected=true when the breaker refused the call before it ran (circuit open) — the adapter maps that to Unavailable; otherwise innerErr carries the call's own error (nil on success). The internal ran flag distinguishes an open-circuit rejection from the call's own error without depending on the breaker's internal full-sentinel, keeping the adapter on the CircuitBreaker interface rather than its implementation.
func Retry ¶
func Retry( ctx context.Context, retrier interfaces.Retrier, isPermanent func(error) bool, call func() error, ) (permanent, exhausted error)
Retry runs call under retrier, treating an error for which isPermanent reports true as terminal: it is captured and returned as permanent (never retried) and the retry loop stops. A retryable error is retried until the retrier gives up, whereupon the retrier's error is returned as exhausted. On success both are nil.
permanent and exhausted are mutually exclusive — a permanent error makes the retry closure report success to the retrier (so retryErr is nil), and an exhausted retry never sets permanent. The adapter maps permanent to a verbatim return and exhausted to its framework's Unavailable code. This is the exact classification both stacks' retry interceptors performed inline.
Types ¶
type TimeoutClass ¶
type TimeoutClass int
TimeoutClass classifies why a deadline-bounded call failed.
const ( // TimeoutNone means the failure was not a deadline or cancellation; the // adapter returns the call's original error unchanged. TimeoutNone TimeoutClass = iota // TimeoutDeadline means the interceptor's own deadline elapsed; the adapter // reports the actual elapsed time, not the nominal timeout. TimeoutDeadline // TimeoutCanceled means ctx was canceled by the caller or a shorter parent // deadline — a fast-fail that must NOT be relabeled as a full timeout wait. TimeoutCanceled )
func ClassifyTimeout ¶
func ClassifyTimeout(ctx context.Context) TimeoutClass
ClassifyTimeout inspects ctx after a failed deadline-bounded call and reports whether the failure was the interceptor's own deadline, an upstream cancellation, or neither. Distinguishing the deadline from a cancellation prevents a fast-fail on an already-cancelled (or shorter-parent) context from being mislabeled as a full timeout wait, which would corrupt latency diagnosis. The adapter builds its framework error from the returned class and the elapsed time.