Documentation
¶
Overview ¶
Package chain composes an ordered list of origins into a single fallback origin. A Chain is itself an origin.Origin: it tries [primary, fallback...] in order and, when one origin "misses" (a connection/transport error, a 404, or a configurable set of HTTP statuses — default 404 + all 5xx), falls through to the next. This is how `origin chain s3 -> cloudfront` from the Cadishfile is realized: FALLBACK IS COMPOSITION at the origin layer, never baked into any concrete origin (httporigin / s3origin know nothing about each other).
On a POSITIVE success (200/206) from any origin, the Chain returns that streaming response immediately and the remaining origins are NOT consulted — the live body belongs to the caller, who MUST Close it (the standard origin contract). A NEGATIVE response (a full-body 404/410, backlog #21) counts as a MISS: the Chain falls through to the next origin and Closes the abandoned negative body. If every origin misses, the Chain surfaces the last full-body negative response (if one was seen) so the server can negatively cache its real error page; otherwise the LAST error is surfaced.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultFallThrough ¶
DefaultFallThrough is the default policy: fall through on a connection/transport error (no HTTP status), a 404, or any 5xx. A 4xx other than 404 (e.g. 401, 403) does NOT fall through by default — it is a definitive answer from the origin and is surfaced to the caller.
Types ¶
type Chain ¶
type Chain struct {
// contains filtered or unexported fields
}
Chain is an origin.Origin that tries a list of origins in order, falling through on configurable conditions.
func New ¶
New builds a Chain over origins (in priority order: first is primary). It returns an error if no origins are given. The default fall-through policy is DefaultFallThrough; override it with WithFallThrough / WithFallThroughStatuses.
func (*Chain) Fetch ¶
Fetch implements origin.Origin. It tries each origin in order. On the first POSITIVE success (200/206) it returns that streaming response (caller owns/closes the body). A NEGATIVE response (a full-body 404/410, backlog #21) is treated as a miss: the chain falls through to the next origin, closing the abandoned negative body. On a fall-through error it tries the next origin, closing the captured upstream body of the error it abandons (an HTTP origin attaches the live non-2xx body to a *StatusError); on a non-fall-through error it returns that error immediately (body intact for the caller). If every origin falls through, the LAST outcome is surfaced — the last negative *Response if one was seen after the last error, otherwise the last error.
func (*Chain) ReplaceOrigins ¶
ReplaceOrigins rewrites each member origin in place by applying f, used by zero-downtime reload to repoint a transplanted lb pool (the survivor's old *lb.Upstream instance) inside a freshly-built chain. f is expected to recurse, so a nested chain is rewritten too. It is only safe to call on a chain the caller exclusively owns (a just-built, not-yet-published config), which is exactly the reload case.
type FallThrough ¶
FallThrough decides, given the error a tried origin returned, whether the Chain should try the next origin. It receives the origin's error (never nil — it is only consulted on a non-success) and reports true to fall through.
type Option ¶
type Option func(*Chain)
Option configures a Chain.
func WithFallThrough ¶
func WithFallThrough(ft FallThrough) Option
WithFallThrough overrides the fall-through predicate. The default is DefaultFallThrough (connection error + 404 + any 5xx). A non-falling status (e.g. a 403 you want surfaced, or a 401) stops the chain and surfaces that error.
func WithFallThroughStatuses ¶
WithFallThroughStatuses builds a fall-through predicate from an explicit set of HTTP statuses PLUS connection/transport errors (which carry no HTTP status). Use this for the common case "fall through on 404 and these specific codes". Connection errors (origin.StatusOf == 0) ALWAYS fall through with this option, because an origin that could not be reached should never end the chain.