activator

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package activator implements scale-to-zero (ADR-0016): an in-process data-path component backing a gateway route's upstream. For a request to a scaled-to-zero function it buffers the request, single-flights a wake (Scaler.ScaleTo(fn,1)), waits for a ready upstream to appear, then forwards the held request (or 503s on timeout, or at once for a Failed function); and it runs a periodic idle-reclaim pass that scales idle functions to zero. It emits a scale INTENT through two seams (Endpoints read / Scaler write); it does not provision workers (that is the P-M Function reconciler) and it does not register a Function reconciler (one-reconciler-per-gvk, ADR-0015).

Index

Constants

View Source
const DeadlineOp = "activator.response-deadline"

DeadlineOp is the op of the fault an external invoke gets when its response does not start in time (ADR-0151).

View Source
const TimeoutHeader = "X-Funcd-Timeout-Ms"

TimeoutHeader carries the time left for a call to a worker, in whole milliseconds rounded up, so a pool can arm its own timer (ADR-0151). Relative, like grpc-timeout, so funcd and the worker need no shared clock.

Variables

This section is empty.

Functions

func DeadlineTransport added in v0.4.0

func DeadlineTransport(rt http.RoundTripper) http.RoundTripper

DeadlineTransport sets TimeoutHeader on a copy of each request to the earlier of its context deadline and its ResponseDeadline, and deletes it when there is neither, so a caller cannot set it. With a ResponseDeadline it cancels the inner request when d.At passes before the response headers, closes a response that arrives later, and returns the DeadlineOp fault; a response returned before d.At is never cancelled. The inner response is returned unwrapped, so an upgraded (101) body stays an io.ReadWriteCloser.

func FailedFault added in v0.2.1

func FailedFault(op string, f *v1.Function) error

FailedFault is the fault.Unavailable a call to f is answered with when f is Failed, naming its Ready reason, else nil. A wake does not leave Failed (ADR-0016 C2) and the reconciler does not restart a ShapeInvalid worker (ADR-0142), so a held call could only time out (issue #142).

func HeldRevision added in v0.7.0

func HeldRevision(f *v1.Function, ref FunctionRef) bool

HeldRevision reports whether ref is pinned to a revision of f other than its current and serving ones, or, for a pooled f, other than its current one, which alone its pool holds (ADR-0190 Decisions 6 and 8): a wake of it is a demand on that Revision, which runs solo, and its Revision.status, not f's phase, judges it.

func KeepEdgeHeaders added in v0.2.3

func KeepEdgeHeaders(rp *httputil.ReverseProxy, w http.ResponseWriter)

KeepEdgeHeaders makes rp put the headers w carries now back before the final response or the error response: httputil.ReverseProxy clears the whole header map after it relays an upstream 1xx, which would drop the X-Request-Id and CORS headers the edge set before proxying (#417). ReverseProxy appends the upstream's values, so the upstream's copy of an edge header is dropped and the edge's value wins, like the shaping header rules; Vary is a list, so both sides' values are kept (#720). It sets rp.ModifyResponse and wraps rp.ErrorHandler, which must be set first.

func Reclaimable added in v0.5.0

func Reclaimable(fn *v1.Function) bool

Reclaimable reports whether idle reclaim may move fn to Idle (ADR-0016 C2, ADR-0169, ADR-0185): a gate-held Pending Function runs no worker, so it is never reclaimed.

func ReclaimablePhase added in v0.7.0

func ReclaimablePhase(p v1.Phase) bool

ReclaimablePhase reports whether idle reclaim may move a Function or a held Revision in phase p to Idle.

func RevisionFailedFault added in v0.7.0

func RevisionFailedFault(op string, fn FunctionRef, rev *v1.Revision) error

RevisionFailedFault is the fault.Unavailable a call pinned to the held revision rev is answered with when rev is Failed, naming its Ready reason, else nil (ADR-0190 Decision 5).

func WithFunction

func WithFunction(r *http.Request, fn FunctionRef) *http.Request

WithFunction returns r carrying fn for ServeHTTP. The gateway route wiring (P-I) sets it from the matched route; tests set it directly.

func WithResponseDeadline added in v0.4.0

func WithResponseDeadline(r *http.Request, d ResponseDeadline) *http.Request

WithResponseDeadline returns r carrying d for ServeHTTP and DeadlineTransport. Only the data plane's serveFunction sets it, for a request not marked internal.

Types

type Activator

type Activator struct {
	// contains filtered or unexported fields
}

Activator is the scale-to-zero data path + idle-reclaim component.

func New

func New(d Deps) (*Activator, error)

New builds the activator. Endpoints and Scaler are required.

func (*Activator) ReclaimIdle

func (a *Activator) ReclaimIdle(ctx context.Context) error

ReclaimIdle scales to zero every minReplicas==0 function in a Reclaimable phase whose last activity is older than its IdleTimeout, that has no call in flight and no wake in progress. Functions with recent activity, MinReplicas != 0, a zero IdleTimeout (reclaim disabled), or any other phase — Pending, Failed, Deploying, Terminating, Idle — are skipped. A function not yet seen, or with a call in flight, is given a full grace window from the current time. Entries for functions that no longer exist are dropped. A held revision is reclaimed by its pinned ref after its Function's IdleTimeout, or heldIdleTimeout when that is zero, whatever the replica floor (ADR-0190 Decisions 6 and 10).

func (*Activator) Run

func (a *Activator) Run(ctx context.Context) error

Run calls ReclaimIdle every ReclaimInterval until ctx is cancelled. On return it ends every in-flight activation (its waiters get Unavailable) and waits for them.

func (*Activator) ServeHTTP

func (a *Activator) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serves one request: warm → proxy now; cold → single-flight ScaleTo(1), wait for a ready upstream (bounded by ActivationTimeout), then forward. On activation timeout or for a Failed function → 503 problem+json; a request with no FunctionRef in context → 500 problem+json. A request with a ResponseDeadline gets the DeadlineOp 504 when the deadline passes before the upstream's headers: at once when already past (no wake), during the wake (the shared activation goes on, ADR-0016), or during the call (DeadlineTransport) — ADR-0151.

func (*Activator) Wake

func (a *Activator) Wake(ctx context.Context, fn FunctionRef) (string, error)

Wake returns fn's ready upstream, single-flight-activating (ScaleTo(1) + poll, bounded by ActivationTimeout) if it is cold — the shared wake primitive (ADR-0033) used by both the data-plane cold path (ServeHTTP) and the eventing trigger path. It records activity (touch, feeding idle reclaim); an Endpoints error → fault.Unavailable; a ready function returns its upstream immediately; a not-ready one is woken via the existing per-fn singleflight.

type CallTracker added in v0.1.4

type CallTracker struct {
	// contains filtered or unexported fields
}

CallTracker counts the calls made to each worker, keyed by the upstream's host:port, so the Function reconciler can tell when a worker of a demoted revision is drained (ADR-0143). Every caller that reaches workers — the activator's proxy, the workflow dispatcher, the Sensor invoker — sends through Wrap, and the resolver records each hand-out. Safe for concurrent use.

func NewCallTracker added in v0.1.4

func NewCallTracker(c clock.Clock) *CallTracker

NewCallTracker builds a tracker on c (the system clock when nil).

func (*CallTracker) HandedOut added in v0.1.4

func (t *CallTracker) HandedOut(upstream string)

HandedOut records that the resolver returned upstream to a caller.

func (*CallTracker) Idle added in v0.1.4

func (t *CallTracker) Idle(upstream string, settle time.Duration) bool

Idle reports whether no call to upstream is in flight and it was not handed out within settle. An idle upstream is forgotten.

func (*CallTracker) Wrap added in v0.1.4

Wrap returns a RoundTripper that counts each request to its URL's host:port from RoundTrip until the response body is closed, or until RoundTrip fails. A nil rt wraps a new httpx.NodeTransport.

type Deps

type Deps struct {
	Store             store.Store   // lists Functions for idle reclaim; read for a Failed phase while activating
	Endpoints         Endpoints     // ready-upstream resolver (required)
	Scaler            Scaler        // scale-intent writer (required)
	Clock             clock.Clock   // default clock.System()
	Logger            *slog.Logger  // default slog.Default()
	ActivationTimeout time.Duration // cold-start hold bound; default 30s
	PollInterval      time.Duration // ready-poll cadence; default 25ms
	ReclaimInterval   time.Duration // idle-reclaim cadence for Run; default 30s
	Calls             *CallTracker  // counts the calls to each worker (ADR-0143), which idle reclaim also reads; nil ⇒ uncounted
}

Deps configures the activator (internal component, ADR-0002 §1).

type Endpoints

type Endpoints interface {
	// Upstream returns the ready upstream URL for fn and whether one exists. The URL's path, if
	// any, is where fn's worker serves it (a pool worker's /function/<name>, ADR-0046).
	Upstream(ctx context.Context, fn FunctionRef) (upstream string, ready bool, err error)
}

Endpoints resolves a function's currently-ready upstream. P-M/scheduler provide the production driver (from the provisioned replica set); tests inject a fake.

type FunctionRef

type FunctionRef struct {
	Namespace v1.NamespaceName
	Name      v1.ObjectName
	Revision  v1.ObjectName // "" ⇒ the serving revision
	UID       v1.UID        // set with Revision
}

FunctionRef identifies the function a request / scale-decision targets. A ref with a Revision names one revision of the Function with UID (ADR-0190), so single-flight, activity and idle reclaim keyed by it are per revision.

type ResponseDeadline added in v0.4.0

type ResponseDeadline struct {
	At     time.Time
	Limit  time.Duration
	Source string // "spec.timeout" or "invoke.defaultTimeout"
}

ResponseDeadline bounds an external invoke from its receipt until the upstream's headers reach the activator. Limit and Source name the bound in the 504's detail.

type Scaler

type Scaler interface {
	ScaleTo(ctx context.Context, fn FunctionRef, replicas int) error
}

Scaler drives a function toward a target replica count (V1 uses only 0 and 1).

Directories

Path Synopsis
Package storescaler is the V1 store-backed activator.Scaler driver (ADR-0016): it records a function's scale intent as its partitioned status Phase — the wake edge Idle→Deploying for replicas>=1, the reclaim edge Ready/Degraded/empty→Idle for replicas==0 (activator.Reclaimable, ADR-0169, ADR-0185) — via store.Update.
Package storescaler is the V1 store-backed activator.Scaler driver (ADR-0016): it records a function's scale intent as its partitioned status Phase — the wake edge Idle→Deploying for replicas>=1, the reclaim edge Ready/Degraded/empty→Idle for replicas==0 (activator.Reclaimable, ADR-0169, ADR-0185) — via store.Update.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL