Help us shape the future of Go! Take the 2026 Go Developer Survey

activator

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 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 ReasonTargetServesHTTP = "TargetServesHTTP"

ReasonTargetServesHTTP names a call refused because its target serves HTTP, which only the edge calls (ADR-0243).

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 RefuseHTTP added in v0.14.0

func RefuseHTTP(ctx context.Context, protocol ProtocolFunc, fn FunctionRef, op string) error

RefuseHTTP refuses a call from a Sensor, an App hook or a workflow step to a Function that serves HTTP, before any request reaches it (ADR-0243 Decision 5). A nil protocol, or a Function it cannot read, refuses nothing: the call then fails, or not, as it would.

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 ProtocolFunc added in v0.14.0

type ProtocolFunc func(ctx context.Context, fn FunctionRef) (v1.FunctionProtocol, error)

ProtocolFunc reads how a Function is called (ADR-0243).

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