Repository navigation
[APPS-2961] Update: run each local backend function call in a fresh process - #608
Conversation
Live Debugger Runtime BenchmarkSDK-loaded dormant-probe runtime overhead, measured against an uninstrumented bundle in the same browser session.
What do the Tiny and Hot workloads represent? Browser Debugger SDK: Full diagnosticsRaw samples are in the |
b0d7fe4 to
5bb05d3
Compare
5bb05d3 to
4c9b050
Compare
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
🟡 Changes recommended
Shutdown cleanup can leave children running, and linked-package dependencies outside the app’s workspace can be incorrectly blocked.
2 open issues
What changed in this PR
Moves Vite 6+ local backend calls into fresh child processes, improving production parity while retaining Vite 5’s in-process fallback. Parallel execution remains a follow-up.
Changes:
- Adds process isolation, permissions, timeouts, and streamed logs.
- Routes module loading and authenticated actions through the dev server.
- Adds integration coverage, fixtures, packaging, and documentation.
| File | Description |
|---|---|
| yarn.lock | Locks new matching dependencies. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childVirtual.backend.ts | Tests virtual module imports. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childTopLevelWriteHelper.ts | Probes load-time writes. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childTopLevelWrite.backend.ts | Exercises load-time guards. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childState.backend.ts | Exercises isolation, limits, and logs. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childSlowLoad.backend.ts | Exercises loading timeouts. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childSandboxProbes.ts | Probes permissions and module requests. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childSandbox.backend.ts | Exposes sandbox test functions. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childLoadTime.backend.ts | Exercises runtime-context initialization. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childLaterImport.backend.ts | Exercises missing imports. |
| packages/tests/src/_jest/fixtures/apps_backend_project/childActions.backend.ts | Exercises action validation. |
| packages/plugins/apps/src/vite/local-execution.ts | Exports the shared execution queue. |
| packages/plugins/apps/src/vite/local-execution-protocol.ts | Defines parent-child messages. |
| packages/plugins/apps/src/vite/local-execution-process.ts | Implements child orchestration and checks. |
| packages/plugins/apps/src/vite/local-execution-process.test.ts | Covers child execution behavior. |
| packages/plugins/apps/src/vite/local-execution-process.fixtures.ts | Builds the test child entry. |
| packages/plugins/apps/src/vite/local-execution-child.ts | Executes functions and forwards actions. |
| packages/plugins/apps/src/vite/local-execution-child-path.ts | Locates the bundled child entry. |
| packages/plugins/apps/src/vite/index.ts | Selects and configures the executor. |
| packages/plugins/apps/src/vite/index.test.ts | Tests executor selection and fallback. |
| packages/plugins/apps/src/vite/dev-server.ts | Delegates local calls to the executor. |
| packages/plugins/apps/src/vite/dev-server.test.ts | Tests executor delegation. |
| packages/plugins/apps/src/vite/dev-server.integration.test.ts | Verifies fresh processes through middleware. |
| packages/plugins/apps/src/vite/dev-server-module-graph.ts | Makes stale-module uncaching configurable. |
| packages/plugins/apps/src/vite/dev-server-module-graph.test.ts | Tests child-mode cache handling. |
| packages/plugins/apps/README.md | Documents isolation, limits, and debugging. |
| packages/plugins/apps/package.json | Adds child packaging and matching dependencies. |
Review effort: Balanced
aa5b6d7 to
ba6b653
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba6b65359a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ba6b653 to
4d1fb34
Compare
9a36cab to
b6220fb
Compare
4384bc9 to
6c426e6
Compare
🎉 All green!🧪 All tests passed 🔗 Commit SHA: 8796b07 | Docs | View more details | Give us feedback! |
b6220fb to
5721b26
Compare
6c426e6 to
e842184
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
e842184 to
44a23e7
Compare
5721b26 to
74f28bc
Compare
44a23e7 to
9f367ef
Compare
74f28bc to
11b2000
Compare
9f367ef to
c78647b
Compare
11b2000 to
f08b751
Compare
c78647b to
b750a1b
Compare
/__dd/executeAction forks a Node process per call, running the project's Vite module runner, which loads modules from the dev server over IPC. Each call starts with fresh module state. Calls still run one at a time. Each process runs under the guards, which refuse writes outside its temp dir and /tmp, subprocesses and worker threads. Its heap is capped at 256 MB and its environment holds no developer variables or keys. $.Actions calls go back to the dev server, which keeps the credentials and checks each call's connection. Output streams to the terminal line by line. A call past its time budget is killed, even in a synchronous loop, and the dev server kills its calls when it closes, restarts or exits. The in-process executor and its fallbacks are gone. A Yarn Plug'n'Play dev server, whose packages load through hooks a call's process doesn't get, fails each call with a hint to use a node_modules install or dev:verify. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b750a1b to
8796b07
Compare


Motivation
Architecture
sequenceDiagram participant B as "Browser" participant D as "Vite dev server" participant C as "Call process" participant API as "Datadog API" B->>D: "POST /__dd/executeAction" D->>API: "Hydrate $ (preview-async)" D->>C: "Fork a fresh process: stripped env, 256 MB heap" loop "Each module the call imports" C->>D: "fetchModule over IPC" D-->>C: "Module code" end C->>D: "$.Actions call" D->>D: "Allowlist check, add credentials" D->>API: "Single-action query" D-->>C: "action-result" C-->>D: "stdout and stderr lines" C->>D: "result or error" D->>C: "SIGKILL" D-->>B: "Response"Changes
10 changes across local-execution-process.ts, local-execution-child.ts, local-execution.ts, index.ts, the README and tests
local-execution-process.ts$.Actionsfor the call over IPC, and fails the call when a reply can't be sent before the call returns, whethersendthrows or reports the error to its callback.local-execution-process.tslocal-execution-process.ts,index.tsModuleRunnerwith Node'simport.meta.resolve, under the in-process guards.local-execution-child.ts,local-execution-protocol.tslocal-execution.ts,dev-server.ts,dev-server-module-graph.ts'error'event, such as a failed kill, so exit still kills it.local-execution-process.tslocal-execution-process.tslocal-execution-shared.tspackage.json,README.mdnode:child_process, since a sandbox guard from another test file can leaveforkunspyable.local-execution-process.integration.test.ts,local-execution-process.test.ts,dev-server.test.ts,dev-server.integration.test.ts,index.test.tsQA Instructions
c78647b9, as are the staging checks below. Setup: build-plugins: Testing and QA Guide.{"hello":"qa","pid":21506}, dev server pid 21486calls: 1three times, three pidsprocess.exit(3)ended before returning a result (exit code 3)timed out after 10000msin 10114 ms$.Actionscall settling after the return{"returned":true,...}DD_API_KEYset["TMPDIR","__CF_USER_TEXT_ENCODING"]server.close()ps -p), everydd-apps-exec-*dir removedimport.meta.resolve('vite'), Vite 7.3.7file://…/app7/node_modules/vite/dist/node/index.jsnodeLinker: pnpLocal execution of backend functions needs a node_modules install: …Local QA app, helper script and output
Vite 7 packed-app QA:
import.meta.resolveand Plug'n'PlayStaging QA in a Vite 8 app against a Datadog staging org, at
c78647b91, 1, 1DD_*variables a dependency sees$.Actionsunscoped, unlisted connectiondev:verifyBlast Radius
/__dd/executeAction; builds, deploys anddev:verifyare unchanged.nodeLinker: node-modulesordev:verify.Out of Scope / Follow-ups
10 items deferred
NODE_OPTIONShooks.kill -9or an unhandled signal.index.test.tsjustifies thessr.noExternalentries byserver.ssrLoadModule, which local execution doesn't call.--inspectwhile debugging, not the dev server'sNODE_OPTIONSor flags such as--enable-source-maps.vite/module-runnerresolves from the project root, not the running Vite, so a framework-owned Vite under pnpm's strict layout gets none, and a second hoisted Vite gets a mismatched one.network-guard.ts's header still describes guarding calls inside the dev server's process.server.close, which isn't plugin API.Documentation
ModuleRunnerandhandleInvoke🤖 Generated with Claude Code