Documentation
¶
Overview ¶
Package call provides a resilient HTTP client with retry, circuit breaker, and timeout support using a composable builder pattern.
Index ¶
- Variables
- func RemoveBreaker(name string)
- type Breaker
- type CachedToken
- type CircuitBreaker
- type Client
- type Option
- func WithBreaker(b Breaker) Option
- func WithCircuitBreaker(name string, threshold int, resetTimeout time.Duration) Option
- func WithHTTPClient(hc *http.Client) Option
- func WithRetry(maxAttempts int, baseDelay time.Duration) Option
- func WithTimeout(d time.Duration) Option
- func WithTokenSource(source TokenSource) Option
- type Retrier
- type State
- type TokenOption
- type TokenSource
Constants ¶
This section is empty.
Variables ¶
var ErrBodyNotRewindable = errors.New("call: request body is not rewindable")
ErrBodyNotRewindable is returned when a retry would need to resend a request body that cannot be recreated through Request.GetBody.
var ErrCircuitOpen = errors.New("circuit breaker is open")
ErrCircuitOpen is returned when a circuit breaker is in the Open state and rejects requests.
Functions ¶
func RemoveBreaker ¶
func RemoveBreaker(name string)
RemoveBreaker removes a named circuit breaker from the global registry, allowing its memory to be reclaimed. Safe to call even if the name does not exist. Use this when a downstream service is decommissioned or when breaker names contain dynamic data.
Types ¶
type Breaker ¶
type Breaker interface {
// Allow checks whether a request may proceed. Returns ErrCircuitOpen
// (or similar) when the circuit is open.
Allow() error
// Record reports the outcome of a request so the breaker can update state.
Record(success bool)
}
Breaker defines the circuit breaker behavior. Consumers can provide their own implementation (e.g., wrapping sony/gobreaker) via WithBreaker.
type CachedToken ¶
type CachedToken struct {
// contains filtered or unexported fields
}
CachedToken caches a token and refreshes it when within Leeway of expiry.
func NewCachedToken ¶
func NewCachedToken(fetchFn func(ctx context.Context) (string, time.Time, error), opts ...TokenOption) *CachedToken
NewCachedToken creates a TokenSource that caches tokens from fetchFn.
type CircuitBreaker ¶
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker implements the circuit breaker pattern. It tracks consecutive failures and short-circuits requests when the failure threshold is reached, giving the downstream service time to recover.
func GetBreaker ¶
func GetBreaker(name string, threshold int, resetTimeout time.Duration) *CircuitBreaker
GetBreaker returns an existing circuit breaker for the given name or creates a new one with the provided threshold and reset timeout. Breakers are singletons keyed by name.
func (*CircuitBreaker) Allow ¶
func (cb *CircuitBreaker) Allow() error
Allow checks whether a request is permitted through the breaker. It returns nil when the request may proceed or ErrCircuitOpen when it must be rejected.
func (*CircuitBreaker) Record ¶
func (cb *CircuitBreaker) Record(success bool)
Record reports the outcome of a request to the breaker so it can update its internal state accordingly.
func (*CircuitBreaker) State ¶
func (cb *CircuitBreaker) State() State
State returns the current state of the circuit breaker. The internal probing state is reported as StateHalfOpen to external consumers.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a resilient HTTP client that wraps the standard http.Client with optional retry, circuit breaker, and timeout middleware. Construct one using New with functional options.
func New ¶
New creates a Client with the given options applied. Without options it behaves like a default http.Client with a 30-second timeout.
func (*Client) Batch ¶
func (c *Client) Batch(ctx context.Context, requests []*http.Request, opts ...work.Option) ([]*http.Response, error)
Batch executes multiple requests concurrently with bounded concurrency using work.Map. Results are returned in the same order as the input requests.
func (*Client) Do ¶
Do executes an HTTP request with all configured middleware applied. The middleware order is: circuit breaker check, retry loop, execute.
If the request does not carry a context, one is created with the configured timeout. If a context is already present its deadline is respected.
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithBreaker ¶
WithBreaker sets a custom circuit breaker implementation.
func WithCircuitBreaker ¶
WithCircuitBreaker protects the client with a named circuit breaker that opens after threshold consecutive failures and resets after resetTimeout.
func WithHTTPClient ¶
WithHTTPClient replaces the underlying *http.Client used by the call Client. This is useful when you need a custom Transport (e.g., proxy routing, SSRF-safe dialer) or a custom CheckRedirect policy. The timeout set by WithTimeout is applied via a per-request context and does not override the http.Client.Timeout field — set that to zero or remove it if you want the call-level timeout to be authoritative.
func WithRetry ¶
WithRetry enables automatic retries for transient (5xx) errors using exponential backoff with jitter. MaxAttempts is clamped to a minimum of 1.
Note: retries re-send the same *http.Request. Requests with a non-nil Body must be rewindable through Request.GetBody. If a retry is required and the body cannot be recreated, Do returns ErrBodyNotRewindable instead of sending an empty or partially consumed body. Requests with nil Body (GET, DELETE, HEAD) are always safe to retry.
func WithTimeout ¶
WithTimeout sets the maximum duration for a single HTTP request attempt.
func WithTokenSource ¶
func WithTokenSource(source TokenSource) Option
WithTokenSource configures a TokenSource that provides a Bearer token injected into the Authorization header of every outbound request.
type Retrier ¶
Retrier provides retry logic with exponential backoff and jitter for transient server errors (5xx). It never retries client errors (4xx).
func (*Retrier) Do ¶
func (r *Retrier) Do(ctx context.Context, fn func() (*http.Response, error)) (*http.Response, error)
Do executes fn up to MaxAttempts times, retrying only when a 5xx status code is returned. Between attempts it sleeps with exponential backoff plus random jitter of up to 50% of the calculated delay. It respects context cancellation and deadline, stopping immediately when the context is done.
If the request has a GetBody function, it is called before each retry to rewind the request body. Requests with a body but no working GetBody fail with ErrBodyNotRewindable instead of sending an empty/consumed body.