anonpenguin23 0371c97318 feat(serverless): reactor-mode pre-warm pool — remove ~550ms cold-start (#898)
Every stateless invocation re-instantiates the module, running TinyGo's
_start/_initialize runtime init on the request's critical path (~550ms for
complex functions). Add a reactor-mode path: a function built -buildmode=c-shared
that exports handle(ptr,len)->packed is served from a per-module pool of
PRE-WARMED instances, so the _initialize cold-start runs ahead of the request
in the background instead of on it.

SAFETY: each warmed instance serves exactly ONE invocation and is then closed —
never reused across calls. Isolation is therefore identical to today's
fresh-instance-per-call model; no cross-tenant/cross-invocation state can leak
through a pooled instance. The pool only changes WHEN the cold-start runs. An
empty pool degrades gracefully (synchronous cold instantiate); command-mode
functions (which export _start) are detected and routed to the unchanged
ExecuteModule path. Pool is LRU-capped per distinct module and drained on
redeploy (Invalidate) + shutdown (Close).

Opt-in via function.yaml reactor:true (build flag) + the handle export. Per-call
identity rides ctx (WithInvocationContext); the reactor contract requires init()
to be identity-independent (do per-caller work in handle()).
2026-06-22 10:10:06 +03:00
..