Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewRoundTripper ¶
func NewRoundTripper(endpoints []Endpoint, fo Options, defaultBase http.RoundTripper) http.RoundTripper
NewRoundTripper creates a RoundTripper that cycles through endpoints according to fo when a request fails. Slices in fo are copied so callers can safely mutate the originals.
For each endpoint, a dedicated http.Transport is created when SkipTLSVerify or CertificateAuthData are set; otherwise defaultBase is used.
When the strategy is "none" or empty, RoundTrip passes through to defaultBase with no retry overhead.
Types ¶
type Endpoint ¶
Endpoint represents a server endpoint with optional per-endpoint TLS configuration. When SkipTLSVerify or CertificateAuthData are set, a dedicated http.Transport is created for that endpoint at construction time, otherwise the default base transport is shared.
type ExponentialBackoffOptions ¶
type ExponentialBackoffOptions struct {
// InitialInterval is the initial interval between retries. If zero, it defaults to 500ms.
InitialInterval time.Duration `json:"initialInterval,omitempty" yaml:"initialInterval,omitempty"`
// MaxInterval is the maximum interval between retries. If zero, it defaults to 60s.
MaxInterval time.Duration `json:"maxInterval,omitempty" yaml:"maxInterval,omitempty"`
// Multiplier is the factor by which the interval increases after each retry. If nil, it defaults to 1.5.
Multiplier *float64 `json:"multiplier,omitempty" yaml:"multiplier,omitempty"`
// RandomizationFactor is the factor used to randomize the backoff intervals. If nil, it defaults to 0.5.
RandomizationFactor *float64 `json:"randomizationFactor,omitempty" yaml:"randomizationFactor,omitempty"`
}
ExponentialBackoffOptions controls the backoff parameters for exponential backoff. By configuring Multiplier and RandomizationFactor, it is possible to achieve a constant backoff or a linear backoff as well.
func (*ExponentialBackoffOptions) NewExponentialBackoff ¶
func (b *ExponentialBackoffOptions) NewExponentialBackoff() boff.BackOff
NewExponentialBackoff creates a new exponential backoff instance configured with the options in b. If b is nil, defaults from cenkalti/backoff are used.
type Options ¶
type Options struct {
Strategy Strategy `json:"strategy,omitempty" yaml:"strategy,omitempty"`
// RetryableMethods controls which HTTP methods are eligible for transport-level
// failover retries. If empty/nil, the default is safe/idempotent methods.
RetryableMethods []string `json:"retryableMethods,omitempty" yaml:"retryableMethods,omitempty"`
// RetryOnTimeout controls whether failover retries should also happen when
// the underlying transport experiences a timeout (for example, a network
// timeout such as net.OpError.Timeout() / ETIMEDOUT). It does not apply to
// context cancellation or deadline-exceeded errors (ctx.Err() != nil), which
// always stop retries.
RetryOnTimeout bool `json:"retryOnTimeout,omitempty" yaml:"retryOnTimeout,omitempty"`
// FailoverOnStatusCodes controls whether the transport should fail over to the
// next server when it receives one of these HTTP status codes.
FailoverOnStatusCodes []int `json:"failoverOnStatusCodes,omitempty" yaml:"failoverOnStatusCodes,omitempty"`
// MaxRetries controls how many times the transport will attempt a request using the set strategy before giving up
// and returning the last error. If zero, it defaults to 3.
MaxRetries int `json:"maxRetries,omitempty" yaml:"maxRetries,omitempty"`
ExponentialBackoff *ExponentialBackoffOptions `json:"exponentialBackoff,omitempty" yaml:"exponentialBackoff,omitempty"`
}
Options controls transport-level endpoint failover behaviour. It is nested under Configuration so it can be grouped cleanly in JSON/YAML.
This layer only applies when a multiserver strategy is active (currently only RoundRobin). With None/empty or a single server, the transport passes through directly to the base http.RoundTripper.
Interaction with product-level callAPI retry loop ¶
Product-level callAPI wraps HTTPClient.Do(), which invokes RoundTrip(). Each callAPI retry triggers a fresh RoundTrip() call that cycles through all servers from the beginning. Worst-case total attempts:
callAPI.MaxRetries × Options.MaxRetries
FailoverOnStatusCodes behaviour ¶
Status codes listed in FailoverOnStatusCodes are handled at the transport level: the response body is drained, and the request is retried against the next server with exponential backoff. Response headers (e.g. Retry-After) are not inspected. If all servers return a listed code, RoundTrip returns an error (not an HTTP response), so callAPI receives err != nil and returns immediately — its own status-code retry logic is never reached.
Status codes NOT listed here pass through as a normal HTTP response to callAPI, which has its own retry logic for 502/503/504 (fixed backoff, no POST retry) and 429 (honors Retry-After).
type RoundTripper ¶
type RoundTripper struct {
// contains filtered or unexported fields
}
RoundTripper is an http.RoundTripper wrapper that retries the request against multiple configured servers when the underlying transport returns a network-level error or an HTTP status code listed in Options.FailoverOnStatusCodes.
Notes:
- Network errors trigger retries with exponential backoff, cycling to the next server.
- Status codes in FailoverOnStatusCodes also trigger retries: the response body is drained and the request is sent to the next server. Response headers (e.g. Retry-After) are not inspected at this layer.
- If the request carries a body, the request must have GetBody set (the SDK generates requests in a way that supports this).
- For non-idempotent requests (POST, PATCH, etc.), enabling failover on timeouts can produce duplicates when RetryOnTimeout is set. Context cancellation always stops retries immediately.
The request URL is rewritten by swapping scheme/host with each server URL, preserving path and query.
Endpoints, transports, and options are snapshotted at construction time; subsequent changes to the original slices or struct do not affect this instance.
func (*RoundTripper) RoundTrip ¶
RoundTrip implements http.RoundTripper. It validates preconditions and dispatches to a strategy-specific method based on the configured Strategy:
- RoundRobin: delegates to orderedRoundTrip, which cycles through servers sequentially.
- None / empty: passes through to the base transport with no retry logic.
- Unknown strategy: returns an error immediately (configuration error).
New strategies extend the switch in this method — each case builds its own server-selection function (or calls an entirely different method).
This method is called by HTTPClient.Do() inside product-level callAPI. Each callAPI retry triggers a fresh RoundTrip invocation that cycles through all servers from the beginning.
type Strategy ¶
type Strategy string
Strategy selects the endpoint failover behaviour. It is a string type so it serializes nicely to JSON/YAML config files.
Supported values:
- None ("none") or "": default behaviour (no endpoint failover)
- RoundRobin ("roundRobin"): on network-level errors, retry the request against the next server in Servers
Note: comparisons should be case-insensitive.
func NormalizeStrategy ¶
NormalizeStrategy returns the strategy in lower-case with surrounding whitespace removed, so comparisons are case-insensitive.