[dsbx] feat: per-invocation context for pod runtime env - #30234
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
fontanierh
force-pushed
the
fn-invocation-context
branch
from
August 8, 2026 14:26
63dec61 to
c76a5e9
Compare
The function runner can now execute an invocation inside an AsyncLocalStorage context carrying that invocation's environment, and @dust/pod (currentUser, db, new podEnv) reads the environment through the context instead of process.env. The storage is shared between the runner bundle and the vendored package through the Symbol.for registry, since the two are distinct module graphs. Inside a context only the context env is consulted, so one invocation's environment can never leak into another; outside any context (cold runs, local use) reads fall back to process.env unchanged. invoke() takes the per-invocation env as an optional argument; the v1 warm server still swaps process.env, so behavior is unchanged until the concurrent server lands on top of this.
fontanierh
force-pushed
the
fn-invocation-context
branch
from
August 10, 2026 14:45
c76a5e9 to
7e98fc6
Compare
davidebbo
reviewed
Aug 10, 2026
| * each other instead of misreading the store. */ | ||
| export const INVOCATION_CONTEXT_KEY = "dust.pod.invocation-context.v1"; | ||
|
|
||
| function contextStorage(): AsyncLocalStorage<InvocationContext> { |
Contributor
There was a problem hiding this comment.
Can the two contexts share logic? A number of things look identical.
Contributor
Author
There was a problem hiding this comment.
not really because they are entirely separate module graphs that cannot share code: The runner is pre-bundled into runner.js and embedded in the dsbx binary and @dust/pod is vendored into the image's global node_modules and resolved by bundles at import time via NODE_PATH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
First PR of a stack that makes warm function servers serve invocations concurrently (like a web server) instead of one at a time.
Today the warm server injects per-invocation state (user identity, sandbox token) by swapping process.env around each invocation, which forces strict serialization. This PR moves that state into an AsyncLocalStorage invocation context:
podEnv(name)reads the active invocation's env;currentUser()anddb()now go through it. Outside any context (cold runs, local use) it reads process.env, unchanged behavior.@dust/podthrough theSymbol.forregistry: they are distinct module graphs (the runner is pre-bundled, the package resolves via NODE_PATH), so a module-level singleton would not be shared.invoke()takes the per-invocation env as an optional argument. The v1 warm server still swaps process.env, so nothing changes until the concurrent server lands on top.Tests
Unit tests for the context (isolation across concurrent flows, no fallback leakage), context-aware
currentUser(), andinvoke()with an invocation env. The runner-side test fixture imports the pod package's copy of the context module, so the cross-module-graph Symbol.for contract is exercised for real.Risk
No behavior change on its own: the cold path reads process.env as before and the v1 server still swaps env. The SDK change ships with the next base image bump.
Deploy Plan
Merges freely; takes effect with the stack's dsbx release + base image bump (last PR of the stack).