@nimbus-sh/worker 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE.md +6 -0
- package/README.md +2 -2
- package/dist/_shared/cache-stats.d.ts +1 -1
- package/dist/_shared/cache-stats.js +1 -1
- package/dist/_shared/exports-resolver.d.ts +0 -2
- package/dist/_shared/exports-resolver.d.ts.map +1 -1
- package/dist/_shared/exports-resolver.js +0 -2
- package/dist/_shared/session-router.d.ts +0 -1
- package/dist/_shared/session-router.d.ts.map +1 -1
- package/dist/_shared/session-router.js +0 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -1
- package/dist/facets/cirrus-real.d.ts +1 -1
- package/dist/facets/cirrus-real.js +1 -1
- package/dist/facets/manager.d.ts +0 -1
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +3 -15
- package/dist/facets/process.d.ts +2 -2
- package/dist/facets/process.js +2 -2
- package/dist/facets/vite-dev-server.d.ts +3 -3
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +6 -8
- package/dist/facets/wasm-swap-registry.d.ts +15 -21
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +41 -54
- package/dist/facets/ws-terminal.d.ts +4 -5
- package/dist/facets/ws-terminal.d.ts.map +1 -1
- package/dist/facets/ws-terminal.js +7 -8
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +0 -1
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +0 -2
- package/dist/git-bundle.generated.d.ts +2 -3
- package/dist/git-bundle.generated.d.ts.map +1 -1
- package/dist/git-bundle.generated.js +3 -4
- package/dist/index.js +2 -2
- package/dist/loaders/child-process/spawn-facet.d.ts +7 -52
- package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-facet.js +7 -49
- package/dist/loaders/child-process/spawn-pool.d.ts +5 -44
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +5 -44
- package/dist/loaders/fanout-pool.d.ts +18 -65
- package/dist/loaders/fanout-pool.d.ts.map +1 -1
- package/dist/loaders/fanout-pool.js +25 -87
- package/dist/loaders/generated-workers.d.ts +1 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +5 -6
- package/dist/loaders/loader-pool.d.ts +1 -2
- package/dist/loaders/loader-pool.d.ts.map +1 -1
- package/dist/loaders/loader-pool.js +1 -1
- package/dist/loaders/npm-resolve-preamble.d.ts +4 -5
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +14 -21
- package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -1
- package/dist/loaders/pre-bundle-preamble.js +0 -1
- package/dist/npm/cache.js +1 -1
- package/dist/npm/install-batch-facet.d.ts.map +1 -1
- package/dist/npm/install-batch-facet.js +7 -12
- package/dist/npm/installer.d.ts +5 -7
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +20 -101
- package/dist/npm/r2-cache.d.ts +17 -29
- package/dist/npm/r2-cache.d.ts.map +1 -1
- package/dist/npm/r2-cache.js +16 -27
- package/dist/npm/resolve-facet.d.ts +11 -17
- package/dist/npm/resolve-facet.d.ts.map +1 -1
- package/dist/npm/resolve-facet.js +14 -28
- package/dist/npm/resolve-one-facet.d.ts +10 -13
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +8 -10
- package/dist/npm/resolver.d.ts +0 -2
- package/dist/npm/resolver.d.ts.map +1 -1
- package/dist/npm/resolver.js +0 -12
- package/dist/observability/oom-discriminator.d.ts +0 -2
- package/dist/observability/oom-discriminator.d.ts.map +1 -1
- package/dist/observability/oom-discriminator.js +0 -2
- package/dist/replica/routing.js +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +1 -1
- package/dist/runtime/barrel-synthesizer.js +1 -1
- package/dist/runtime/clang-runner.d.ts +5 -6
- package/dist/runtime/clang-runner.d.ts.map +1 -1
- package/dist/runtime/clang-runner.js +5 -6
- package/dist/runtime/esbuild-service.d.ts.map +1 -1
- package/dist/runtime/esbuild-service.js +0 -3
- package/dist/runtime/framework-detect.d.ts +0 -1
- package/dist/runtime/framework-detect.d.ts.map +1 -1
- package/dist/runtime/framework-detect.js +0 -1
- package/dist/runtime/node-runner.d.ts +1 -1
- package/dist/runtime/node-runner.js +1 -1
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +0 -22
- package/dist/runtime/package-manager.d.ts +2 -7
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +2 -7
- package/dist/runtime/process-logs-api.js +1 -1
- package/dist/runtime/process-logs.d.ts +0 -1
- package/dist/runtime/process-logs.d.ts.map +1 -1
- package/dist/runtime/process-table.d.ts +2 -2
- package/dist/runtime/process-table.d.ts.map +1 -1
- package/dist/runtime/process-table.js +1 -1
- package/dist/runtime/python-repl.d.ts +0 -1
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +0 -1
- package/dist/runtime/python-runner.d.ts +1 -2
- package/dist/runtime/python-runner.d.ts.map +1 -1
- package/dist/runtime/python-runner.js +1 -3
- package/dist/runtime/repl-session.d.ts +0 -1
- package/dist/runtime/repl-session.d.ts.map +1 -1
- package/dist/runtime/repl-session.js +1 -2
- package/dist/runtime/require-resolver.d.ts.map +1 -1
- package/dist/runtime/require-resolver.js +1 -4
- package/dist/runtime/ruby-runner.d.ts +0 -1
- package/dist/runtime/ruby-runner.d.ts.map +1 -1
- package/dist/runtime/ruby-runner.js +0 -1
- package/dist/runtime/runtime-catalog.d.ts +2 -4
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +2 -4
- package/dist/runtime/runtime-registry.d.ts +1 -1
- package/dist/runtime/runtime-registry.js +1 -1
- package/dist/runtime/streams.d.ts.map +1 -1
- package/dist/runtime/streams.js +0 -1
- package/dist/runtime/wasi-instance.d.ts +35 -45
- package/dist/runtime/wasi-instance.d.ts.map +1 -1
- package/dist/runtime/wasi-instance.js +87 -103
- package/dist/runtime/wasm-runner.d.ts +9 -15
- package/dist/runtime/wasm-runner.d.ts.map +1 -1
- package/dist/runtime/wasm-runner.js +23 -29
- package/dist/session/bindings.d.ts +2 -7
- package/dist/session/bindings.d.ts.map +1 -1
- package/dist/session/bindings.js +3 -8
- package/dist/session/helpers.d.ts +2 -9
- package/dist/session/helpers.d.ts.map +1 -1
- package/dist/session/helpers.js +2 -10
- package/dist/session/init.d.ts +3 -6
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +25 -30
- package/dist/session/nimbus-session.d.ts +1 -1
- package/dist/session/nimbus-session.js +5 -5
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +9 -16
- package/dist/session/rpc.d.ts +2 -2
- package/dist/session/rpc.js +6 -6
- package/dist/session/supervisor-rpc.d.ts +1 -2
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +1 -5
- package/dist/shell/features.d.ts +5 -5
- package/dist/shell/features.js +6 -6
- package/dist/shell/unix-commands.js +15 -15
- package/dist/vfs/dev-provider.d.ts +1 -1
- package/dist/vfs/dev-provider.js +1 -1
- package/dist/vfs/sqlite-vfs.d.ts +3 -3
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
- package/dist/vfs/sqlite-vfs.js +10 -11
- package/package.json +12 -2
- package/public/s/index.html +44 -75
- package/scripts/bundle-facet-workers.mjs +1 -1
- package/scripts/bundle-git.mjs +1 -1
package/dist/index.js
CHANGED
|
@@ -64,8 +64,8 @@ export function getCtxExports() {
|
|
|
64
64
|
return _getCtxExports();
|
|
65
65
|
}
|
|
66
66
|
// Worker default export — a `createNimbusHandler()` instance running in
|
|
67
|
-
// auto auth mode. The live demo and
|
|
67
|
+
// auto auth mode. The live demo and hosted-demo embedder are bit-identical
|
|
68
68
|
// from here on; the only difference is `NIMBUS_LEGACY_PUBLIC=1` env var
|
|
69
|
-
// (set on the live demo, unset for the
|
|
69
|
+
// (set on the live demo, unset for the hosted-demo) flipping auth.mode to
|
|
70
70
|
// 'legacy' inside the auto-resolver.
|
|
71
71
|
export default createNimbusHandler();
|
|
@@ -1,46 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* isolate via NimbusFanoutPool.
|
|
2
|
+
* Per-spawn task body for Worker Loader isolates.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* to the supervisor's FacetProcessManager._dispatch, which directly
|
|
9
|
-
* invokes either commandRegistry.runPureBuiltin or facetMgr.execStream.
|
|
10
|
-
* Both paths execute IN THE SUPERVISOR'S V8 CONTEXT. The supervisor's
|
|
11
|
-
* heap thus accumulates per-spawn allocation pressure.
|
|
12
|
-
*
|
|
13
|
-
* arch-gaps target: every cp.spawn / spawnSync / exec / execFile call
|
|
14
|
-
* runs inside a fresh Worker Loader isolate. NimbusFanoutPool (proven
|
|
15
|
-
* by F-1 install-batch and F-2 resolver fan-out) provides the auto-
|
|
16
|
-
* routing primitive (in-DO POC C for <5, peer-DO POC B for ≥5).
|
|
17
|
-
*
|
|
18
|
-
* What this task does
|
|
19
|
-
* ───────────────────
|
|
20
|
-
* 1. Mints a per-isolate token (`globalThis.__nimbus_g3_token__`).
|
|
21
|
-
* The first call into a fresh isolate creates the token; warm
|
|
22
|
-
* slots reuse it. Distinct tokens across calls = distinct
|
|
23
|
-
* isolates. Probe surface: audit/probes/arch-gaps/g3-e2e/
|
|
24
|
-
* child-spawn-isolation.mjs.
|
|
25
|
-
* 2. Delegates the actual command execution to
|
|
26
|
-
* `env.SUPERVISOR.cpDispatchInline(req, kind)`. This RPC reuses
|
|
27
|
-
* the existing pure-builtin / facet-direct execution paths
|
|
28
|
-
* (preserves correctness) but the dispatch envelope itself ran
|
|
29
|
-
* in a fresh isolate.
|
|
30
|
-
* 3. Returns `{ exitCode, marker, stdout, stderr }`. The supervisor-
|
|
31
|
-
* side ChildProcessSpawnPool wraps the marker into a per-spawn
|
|
32
|
-
* stderr line and forwards stdout/stderr to the parent's WS.
|
|
33
|
-
*
|
|
34
|
-
* Single-ownership invariant (carried over from git-freeze Q-fix):
|
|
35
|
-
* stdin (if any) is passed by-value as a string in `req.stdin`; no
|
|
36
|
-
* shared ArrayBuffer/Uint8Array refs. The result envelope returns
|
|
37
|
-
* stdout/stderr as strings (already copied by the structured-clone
|
|
38
|
-
* boundary).
|
|
39
|
-
*
|
|
40
|
-
* Stability invariants (cloudflare-parallel serialises via fn.toString):
|
|
41
|
-
* - No `this` references.
|
|
42
|
-
* - No closure capture other than args + (optional) preamble.
|
|
43
|
-
* - The function is the only export's body; helpers inlined.
|
|
4
|
+
* The isolate delegates command execution back to the supervisor through a
|
|
5
|
+
* narrow RPC and returns copied string output. The parent pool owns streaming
|
|
6
|
+
* and process bookkeeping.
|
|
44
7
|
*/
|
|
45
8
|
export interface SpawnInIsolateSpec {
|
|
46
9
|
/** The original cp.spawn payload from node-shims.ts. */
|
|
@@ -61,22 +24,14 @@ export interface SpawnInIsolateSpec {
|
|
|
61
24
|
}
|
|
62
25
|
export interface SpawnInIsolateResult {
|
|
63
26
|
exitCode: number;
|
|
64
|
-
/** Per-isolate token line
|
|
65
|
-
* Pre-pended to stderr by the supervisor-side spawn-pool when the
|
|
66
|
-
* result is forwarded to the cp.spawn parent. Distinct values across
|
|
67
|
-
* results = distinct isolates ran the dispatch. */
|
|
27
|
+
/** Per-isolate token line used by diagnostics that verify isolate routing. */
|
|
68
28
|
marker: string;
|
|
69
29
|
stdout: string;
|
|
70
30
|
stderr: string;
|
|
71
31
|
}
|
|
72
32
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* NimbusFanoutPool's internal `fn(item, env)` lines up.
|
|
76
|
-
*
|
|
77
|
-
* `env.SUPERVISOR` is the supervisor-rpc binding wired automatically
|
|
78
|
-
* by NimbusLoaderPool (see src/loaders/loader-pool.ts:288 — bindings
|
|
79
|
-
* default to `{ SUPERVISOR }`).
|
|
33
|
+
* Signature must remain `(spec, env)` because Worker Loader dispatch calls
|
|
34
|
+
* the task as `fn(item, env)`.
|
|
80
35
|
*/
|
|
81
36
|
export declare const runSpawnInIsolate: (spec: SpawnInIsolateSpec, env: {
|
|
82
37
|
SUPERVISOR: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-facet.d.ts","sourceRoot":"","sources":["../../../src/loaders/child-process/spawn-facet.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"spawn-facet.d.ts","sourceRoot":"","sources":["../../../src/loaders/child-process/spawn-facet.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,GAAG,EAAE;QACH,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,GAAG,CAAC;QACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,4DAA4D;IAC5D,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS,CAAC;IAClD,uEAAuE;IACvE,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,kBAAkB,EACxB,KAAK;IACH,UAAU,EAAE;QACV,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;YAChD,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;SAClD,CAAC,CAAC;KACJ,CAAC;CACH,KACA,OAAO,CAAC,oBAAoB,CAoD9B,CAAC"}
|
|
@@ -1,55 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* isolate via NimbusFanoutPool.
|
|
2
|
+
* Per-spawn task body for Worker Loader isolates.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* to the supervisor's FacetProcessManager._dispatch, which directly
|
|
9
|
-
* invokes either commandRegistry.runPureBuiltin or facetMgr.execStream.
|
|
10
|
-
* Both paths execute IN THE SUPERVISOR'S V8 CONTEXT. The supervisor's
|
|
11
|
-
* heap thus accumulates per-spawn allocation pressure.
|
|
12
|
-
*
|
|
13
|
-
* arch-gaps target: every cp.spawn / spawnSync / exec / execFile call
|
|
14
|
-
* runs inside a fresh Worker Loader isolate. NimbusFanoutPool (proven
|
|
15
|
-
* by F-1 install-batch and F-2 resolver fan-out) provides the auto-
|
|
16
|
-
* routing primitive (in-DO POC C for <5, peer-DO POC B for ≥5).
|
|
17
|
-
*
|
|
18
|
-
* What this task does
|
|
19
|
-
* ───────────────────
|
|
20
|
-
* 1. Mints a per-isolate token (`globalThis.__nimbus_g3_token__`).
|
|
21
|
-
* The first call into a fresh isolate creates the token; warm
|
|
22
|
-
* slots reuse it. Distinct tokens across calls = distinct
|
|
23
|
-
* isolates. Probe surface: audit/probes/arch-gaps/g3-e2e/
|
|
24
|
-
* child-spawn-isolation.mjs.
|
|
25
|
-
* 2. Delegates the actual command execution to
|
|
26
|
-
* `env.SUPERVISOR.cpDispatchInline(req, kind)`. This RPC reuses
|
|
27
|
-
* the existing pure-builtin / facet-direct execution paths
|
|
28
|
-
* (preserves correctness) but the dispatch envelope itself ran
|
|
29
|
-
* in a fresh isolate.
|
|
30
|
-
* 3. Returns `{ exitCode, marker, stdout, stderr }`. The supervisor-
|
|
31
|
-
* side ChildProcessSpawnPool wraps the marker into a per-spawn
|
|
32
|
-
* stderr line and forwards stdout/stderr to the parent's WS.
|
|
33
|
-
*
|
|
34
|
-
* Single-ownership invariant (carried over from git-freeze Q-fix):
|
|
35
|
-
* stdin (if any) is passed by-value as a string in `req.stdin`; no
|
|
36
|
-
* shared ArrayBuffer/Uint8Array refs. The result envelope returns
|
|
37
|
-
* stdout/stderr as strings (already copied by the structured-clone
|
|
38
|
-
* boundary).
|
|
39
|
-
*
|
|
40
|
-
* Stability invariants (cloudflare-parallel serialises via fn.toString):
|
|
41
|
-
* - No `this` references.
|
|
42
|
-
* - No closure capture other than args + (optional) preamble.
|
|
43
|
-
* - The function is the only export's body; helpers inlined.
|
|
4
|
+
* The isolate delegates command execution back to the supervisor through a
|
|
5
|
+
* narrow RPC and returns copied string output. The parent pool owns streaming
|
|
6
|
+
* and process bookkeeping.
|
|
44
7
|
*/
|
|
45
8
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* NimbusFanoutPool's internal `fn(item, env)` lines up.
|
|
49
|
-
*
|
|
50
|
-
* `env.SUPERVISOR` is the supervisor-rpc binding wired automatically
|
|
51
|
-
* by NimbusLoaderPool (see src/loaders/loader-pool.ts:288 — bindings
|
|
52
|
-
* default to `{ SUPERVISOR }`).
|
|
9
|
+
* Signature must remain `(spec, env)` because Worker Loader dispatch calls
|
|
10
|
+
* the task as `fn(item, env)`.
|
|
53
11
|
*/
|
|
54
12
|
export const runSpawnInIsolate = async function runSpawnInIsolate(spec, env) {
|
|
55
13
|
// Mint or reuse the per-isolate token.
|
|
@@ -72,7 +30,7 @@ export const runSpawnInIsolate = async function runSpawnInIsolate(spec, env) {
|
|
|
72
30
|
}
|
|
73
31
|
// env.SUPERVISOR is auto-injected by NimbusLoaderPool and pinned to
|
|
74
32
|
// THIS DO's id (props.doId = ctx.id.toString()). With the in-DO
|
|
75
|
-
//
|
|
33
|
+
// in-DO fanout route, "this DO" IS the user-session DO whose _cpRegistry
|
|
76
34
|
// is populated; cpDispatchInline therefore reaches the right
|
|
77
35
|
// dispatcher.
|
|
78
36
|
if (!env || !env.SUPERVISOR || typeof env.SUPERVISOR.cpDispatchInline !== 'function') {
|
|
@@ -1,49 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* dispatch in a fresh Worker Loader isolate via NimbusFanoutPool.
|
|
2
|
+
* Supervisor-side child-process dispatch pool.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* RPCs back to the supervisor's FacetProcessManager._dispatch, which
|
|
10
|
-
* directly invokes commandRegistry.runPureBuiltin / facetMgr.execStream
|
|
11
|
-
* IN-SUPERVISOR. The supervisor accumulates per-spawn allocation
|
|
12
|
-
* pressure.
|
|
13
|
-
*
|
|
14
|
-
* Post-arch-gaps, FacetProcessManager._dispatch routes through this
|
|
15
|
-
* pool, which submits ONE NimbusFanoutPool.submitMany task per spawn.
|
|
16
|
-
* NimbusFanoutPool auto-routes:
|
|
17
|
-
* < IN_DO_THRESHOLD (5) → POC C in-DO (concurrency = task count, capped at 4)
|
|
18
|
-
* ≥ IN_DO_THRESHOLD → POC B peer-DO with stable-id router
|
|
19
|
-
* (key = command name, so re-installs of
|
|
20
|
-
* the same toolchain cluster on warm peers).
|
|
21
|
-
*
|
|
22
|
-
* The per-spawn task body (`runSpawnInIsolate`) emits a per-isolate
|
|
23
|
-
* marker token and delegates the actual command execution back to the
|
|
24
|
-
* supervisor via `env.SUPERVISOR.cpDispatchInline(req, kind)` — that
|
|
25
|
-
* RPC reuses the existing pure-builtin / facet-direct paths (no
|
|
26
|
-
* correctness regression). The architectural win is the dispatch
|
|
27
|
-
* envelope itself running in a fresh isolate.
|
|
28
|
-
*
|
|
29
|
-
* Why one-task-per-spawn (not batched)
|
|
30
|
-
* ────────────────────────────────────
|
|
31
|
-
* cp.spawn is asynchronous from the parent's perspective: each spawn
|
|
32
|
-
* call returns an emitter immediately, with output streaming as data
|
|
33
|
-
* arrives. Batching multiple unrelated spawns into one submitMany
|
|
34
|
-
* call would couple their lifetimes (any failure aborts the batch).
|
|
35
|
-
* Per-spawn submit gives each call its own isolate-lifecycle envelope,
|
|
36
|
-
* matching the cp.spawn contract.
|
|
37
|
-
*
|
|
38
|
-
* Anti-requirements observed
|
|
39
|
-
* ──────────────────────────
|
|
40
|
-
* - NO setTimeout / sleep on hot paths.
|
|
41
|
-
* - NO fallback to in-supervisor dispatch when env.LOADER missing —
|
|
42
|
-
* NimbusFanoutPool throws BindingError at construction. Caller
|
|
43
|
-
* (FacetProcessManager._dispatch) propagates the error to the
|
|
44
|
-
* parent's stderr.
|
|
45
|
-
* - Single-ownership: stdin/stdout/stderr crossing the loader RPC
|
|
46
|
-
* boundary are strings (structured-clone boundary copies them).
|
|
4
|
+
* Child-process calls from Node facets are executed through Worker Loader
|
|
5
|
+
* isolates instead of allocation-heavy dispatch in the supervisor isolate.
|
|
6
|
+
* Each spawn receives its own lifecycle envelope while command semantics
|
|
7
|
+
* continue to flow through the existing supervisor RPC.
|
|
47
8
|
*/
|
|
48
9
|
export interface SpawnPoolHooks {
|
|
49
10
|
onStdout(data: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-pool.d.ts","sourceRoot":"","sources":["../../../src/loaders/child-process/spawn-pool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"spawn-pool.d.ts","sourceRoot":"","sources":["../../../src/loaders/child-process/spawn-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC;;;;;OAKG;IACH,OAAO,CAAC,KAAK,CAAuC;gBAExC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,kBAAkB;IAW7C;;;;;;;;OAQG;IACG,MAAM,CACV,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS,EACjD,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,GAAG,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC;CAyDnB"}
|
|
@@ -1,49 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* dispatch in a fresh Worker Loader isolate via NimbusFanoutPool.
|
|
2
|
+
* Supervisor-side child-process dispatch pool.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* RPCs back to the supervisor's FacetProcessManager._dispatch, which
|
|
10
|
-
* directly invokes commandRegistry.runPureBuiltin / facetMgr.execStream
|
|
11
|
-
* IN-SUPERVISOR. The supervisor accumulates per-spawn allocation
|
|
12
|
-
* pressure.
|
|
13
|
-
*
|
|
14
|
-
* Post-arch-gaps, FacetProcessManager._dispatch routes through this
|
|
15
|
-
* pool, which submits ONE NimbusFanoutPool.submitMany task per spawn.
|
|
16
|
-
* NimbusFanoutPool auto-routes:
|
|
17
|
-
* < IN_DO_THRESHOLD (5) → POC C in-DO (concurrency = task count, capped at 4)
|
|
18
|
-
* ≥ IN_DO_THRESHOLD → POC B peer-DO with stable-id router
|
|
19
|
-
* (key = command name, so re-installs of
|
|
20
|
-
* the same toolchain cluster on warm peers).
|
|
21
|
-
*
|
|
22
|
-
* The per-spawn task body (`runSpawnInIsolate`) emits a per-isolate
|
|
23
|
-
* marker token and delegates the actual command execution back to the
|
|
24
|
-
* supervisor via `env.SUPERVISOR.cpDispatchInline(req, kind)` — that
|
|
25
|
-
* RPC reuses the existing pure-builtin / facet-direct paths (no
|
|
26
|
-
* correctness regression). The architectural win is the dispatch
|
|
27
|
-
* envelope itself running in a fresh isolate.
|
|
28
|
-
*
|
|
29
|
-
* Why one-task-per-spawn (not batched)
|
|
30
|
-
* ────────────────────────────────────
|
|
31
|
-
* cp.spawn is asynchronous from the parent's perspective: each spawn
|
|
32
|
-
* call returns an emitter immediately, with output streaming as data
|
|
33
|
-
* arrives. Batching multiple unrelated spawns into one submitMany
|
|
34
|
-
* call would couple their lifetimes (any failure aborts the batch).
|
|
35
|
-
* Per-spawn submit gives each call its own isolate-lifecycle envelope,
|
|
36
|
-
* matching the cp.spawn contract.
|
|
37
|
-
*
|
|
38
|
-
* Anti-requirements observed
|
|
39
|
-
* ──────────────────────────
|
|
40
|
-
* - NO setTimeout / sleep on hot paths.
|
|
41
|
-
* - NO fallback to in-supervisor dispatch when env.LOADER missing —
|
|
42
|
-
* NimbusFanoutPool throws BindingError at construction. Caller
|
|
43
|
-
* (FacetProcessManager._dispatch) propagates the error to the
|
|
44
|
-
* parent's stderr.
|
|
45
|
-
* - Single-ownership: stdin/stdout/stderr crossing the loader RPC
|
|
46
|
-
* boundary are strings (structured-clone boundary copies them).
|
|
4
|
+
* Child-process calls from Node facets are executed through Worker Loader
|
|
5
|
+
* isolates instead of allocation-heavy dispatch in the supervisor isolate.
|
|
6
|
+
* Each spawn receives its own lifecycle envelope while command semantics
|
|
7
|
+
* continue to flow through the existing supervisor RPC.
|
|
47
8
|
*/
|
|
48
9
|
import { NimbusLoaderPool } from '../loader-pool.js';
|
|
49
10
|
import { runSpawnInIsolate } from './spawn-facet.js';
|
|
@@ -1,76 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Two-tier fan-out primitive for work that must execute in Worker Loader
|
|
3
|
+
* facets without tripping workerd's per-DO dynamic-worker ceiling.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* dispatches serialize against the cap and produce
|
|
10
|
-
* `Too many concurrent dynamic workers` errors. See
|
|
11
|
-
* `audit/sections/FANOUT-AUDIT.md` and
|
|
12
|
-
* `docs/research/poc-multi-backend-findings.md` for the measurement
|
|
13
|
-
* data.
|
|
5
|
+
* A single Durable Object method can drive at most four concurrent
|
|
6
|
+
* Worker Loader fetches before extra dispatches serialize or fail. Small
|
|
7
|
+
* batches therefore run in the coordinator DO through NimbusLoaderPool.
|
|
8
|
+
* Wider batches are sharded across sibling NimbusSession DOs, each of
|
|
9
|
+
* which owns its own four-loader budget.
|
|
14
10
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* limiter inside ONE facet — see the explicit comment at
|
|
20
|
-
* installer.ts:654 ("collapses what was 4 concurrent dynamic workers
|
|
21
|
-
* (pool.map slots) into 1").
|
|
22
|
-
*
|
|
23
|
-
* Two validated topologies (POC findings)
|
|
24
|
-
* ───────────────────────────────────────
|
|
25
|
-
* POC C in-DO fan-out 1 coordinator DO + N≤4 loaders 4.03× at N=4
|
|
26
|
-
* POC B DO Pool + 1 Loader/DO N peer DOs × 1 loader each 7.75× at N=8, flat to N=32
|
|
27
|
-
*
|
|
28
|
-
* `NimbusFanoutPool` exposes ONE `submitMany` API that routes
|
|
29
|
-
* automatically:
|
|
30
|
-
* width < IN_DO_THRESHOLD → POC C (uses existing NimbusLoaderPool)
|
|
31
|
-
* width >= IN_DO_THRESHOLD → POC B (peer NimbusSession DOs)
|
|
32
|
-
*
|
|
33
|
-
* IN_DO_THRESHOLD is 5 — exactly above the V8 cap so we never use the
|
|
34
|
-
* in-DO path beyond the safe ceiling, and the peer-DO path takes over
|
|
35
|
-
* cleanly for the wider workloads.
|
|
36
|
-
*
|
|
37
|
-
* Stable-id router
|
|
38
|
-
* ────────────────
|
|
39
|
-
* Each task carries a `key` (string). The router maps
|
|
40
|
-
* `key → siblingId = peerNamespace(coordDoIdShort, hash(key) mod N)`.
|
|
41
|
-
* Same key → same peer DO across runs. Tests can predict which peer
|
|
42
|
-
* handles which task, and warm peer isolates are reusable across
|
|
43
|
-
* back-to-back fan-outs that share keys.
|
|
44
|
-
*
|
|
45
|
-
* Hard-fail policy
|
|
46
|
-
* ────────────────
|
|
47
|
-
* Anti-requirement: NO fallback. If `env.LOADER` is missing, throw
|
|
48
|
-
* (existing NimbusLoaderPool already does). If
|
|
49
|
-
* `env.NIMBUS_SESSION` is missing AND a peer-DO route is needed,
|
|
50
|
-
* throw. Callers MUST get a deterministic error rather than silently
|
|
51
|
-
* collapsing back to width-1. The supervisor error handler logs and
|
|
52
|
-
* the install fails loudly — same posture every other facet binding
|
|
53
|
-
* has.
|
|
54
|
-
*
|
|
55
|
-
* Backpressure
|
|
56
|
-
* ────────────
|
|
57
|
-
* Hard cap: `MAX_PEER_FANOUT = 32` (POC B's flat zone). If
|
|
58
|
-
* `tasks.length > 32`, the surplus is queued and dispatched in
|
|
59
|
-
* subsequent rounds after the first 32 settle. This keeps the
|
|
60
|
-
* per-request peer-DO count bounded.
|
|
11
|
+
* Routing is deterministic: each task has a stable key, and the key maps
|
|
12
|
+
* to a sibling DO shard. There is no silent fallback to width-1 execution;
|
|
13
|
+
* missing LOADER or NIMBUS_SESSION bindings fail loudly so install and
|
|
14
|
+
* runtime operations do not appear successful after partial dispatch.
|
|
61
15
|
*/
|
|
62
16
|
/**
|
|
63
|
-
* Threshold at which
|
|
17
|
+
* Threshold at which routing switches from coordinator-local loaders to
|
|
18
|
+
* sibling Durable Objects.
|
|
64
19
|
*
|
|
65
20
|
* Set to **5** so the in-DO path stays below the V8 4-loaders-per-method
|
|
66
|
-
* cap by construction. width < 5
|
|
21
|
+
* cap by construction. width < 5 stays local; width >= 5 uses sibling DOs.
|
|
67
22
|
*/
|
|
68
23
|
export declare const IN_DO_THRESHOLD = 5;
|
|
69
24
|
/**
|
|
70
|
-
* Hard cap on concurrent peer DOs per single submitMany call.
|
|
71
|
-
*
|
|
72
|
-
* pathological 500-pkg installs still parallelise as wide as the
|
|
73
|
-
* topology supports.
|
|
25
|
+
* Hard cap on concurrent peer DOs per single submitMany call. Throughput stays
|
|
26
|
+
* flat through this width while keeping per-request scheduler pressure bounded.
|
|
74
27
|
*/
|
|
75
28
|
export declare const MAX_PEER_FANOUT = 32;
|
|
76
29
|
/** Argument shape for `submitMany`. */
|
|
@@ -140,8 +93,8 @@ export declare class NimbusFanoutPool {
|
|
|
140
93
|
* results in input order.
|
|
141
94
|
*
|
|
142
95
|
* Routing:
|
|
143
|
-
* tasks.length < 5
|
|
144
|
-
* tasks.length >= 5
|
|
96
|
+
* tasks.length < 5 -> coordinator-local NimbusLoaderPool
|
|
97
|
+
* tasks.length >= 5 -> sibling NimbusSession DOs
|
|
145
98
|
*
|
|
146
99
|
* Backpressure: if `tasks.length > MAX_PEER_FANOUT (32)`, tasks
|
|
147
100
|
* are sharded modulo `MAX_PEER_FANOUT` and each shard's bucket
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fanout-pool.d.ts","sourceRoot":"","sources":["../../src/loaders/fanout-pool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fanout-pool.d.ts","sourceRoot":"","sources":["../../src/loaders/fanout-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC;;;GAGG;AACH,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,uCAAuC;AACvC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,IAAI,EAAE,CAAC,CAAC;CACT;AAED,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC1C;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,uBAAuB;IAiB5E;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,UAAU,CAAC,CAAC,EAAE,CAAC,EACnB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EACtB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,EAAE,CAAC;IASf;;;;OAIG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO;IAK7D;;;;;;;;;OASG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;YAOvC,aAAa;YAmCb,eAAe;CAyG9B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAUrE"}
|
|
@@ -1,79 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Two-tier fan-out primitive for work that must execute in Worker Loader
|
|
3
|
+
* facets without tripping workerd's per-DO dynamic-worker ceiling.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* dispatches serialize against the cap and produce
|
|
10
|
-
* `Too many concurrent dynamic workers` errors. See
|
|
11
|
-
* `audit/sections/FANOUT-AUDIT.md` and
|
|
12
|
-
* `docs/research/poc-multi-backend-findings.md` for the measurement
|
|
13
|
-
* data.
|
|
5
|
+
* A single Durable Object method can drive at most four concurrent
|
|
6
|
+
* Worker Loader fetches before extra dispatches serialize or fail. Small
|
|
7
|
+
* batches therefore run in the coordinator DO through NimbusLoaderPool.
|
|
8
|
+
* Wider batches are sharded across sibling NimbusSession DOs, each of
|
|
9
|
+
* which owns its own four-loader budget.
|
|
14
10
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* limiter inside ONE facet — see the explicit comment at
|
|
20
|
-
* installer.ts:654 ("collapses what was 4 concurrent dynamic workers
|
|
21
|
-
* (pool.map slots) into 1").
|
|
22
|
-
*
|
|
23
|
-
* Two validated topologies (POC findings)
|
|
24
|
-
* ───────────────────────────────────────
|
|
25
|
-
* POC C in-DO fan-out 1 coordinator DO + N≤4 loaders 4.03× at N=4
|
|
26
|
-
* POC B DO Pool + 1 Loader/DO N peer DOs × 1 loader each 7.75× at N=8, flat to N=32
|
|
27
|
-
*
|
|
28
|
-
* `NimbusFanoutPool` exposes ONE `submitMany` API that routes
|
|
29
|
-
* automatically:
|
|
30
|
-
* width < IN_DO_THRESHOLD → POC C (uses existing NimbusLoaderPool)
|
|
31
|
-
* width >= IN_DO_THRESHOLD → POC B (peer NimbusSession DOs)
|
|
32
|
-
*
|
|
33
|
-
* IN_DO_THRESHOLD is 5 — exactly above the V8 cap so we never use the
|
|
34
|
-
* in-DO path beyond the safe ceiling, and the peer-DO path takes over
|
|
35
|
-
* cleanly for the wider workloads.
|
|
36
|
-
*
|
|
37
|
-
* Stable-id router
|
|
38
|
-
* ────────────────
|
|
39
|
-
* Each task carries a `key` (string). The router maps
|
|
40
|
-
* `key → siblingId = peerNamespace(coordDoIdShort, hash(key) mod N)`.
|
|
41
|
-
* Same key → same peer DO across runs. Tests can predict which peer
|
|
42
|
-
* handles which task, and warm peer isolates are reusable across
|
|
43
|
-
* back-to-back fan-outs that share keys.
|
|
44
|
-
*
|
|
45
|
-
* Hard-fail policy
|
|
46
|
-
* ────────────────
|
|
47
|
-
* Anti-requirement: NO fallback. If `env.LOADER` is missing, throw
|
|
48
|
-
* (existing NimbusLoaderPool already does). If
|
|
49
|
-
* `env.NIMBUS_SESSION` is missing AND a peer-DO route is needed,
|
|
50
|
-
* throw. Callers MUST get a deterministic error rather than silently
|
|
51
|
-
* collapsing back to width-1. The supervisor error handler logs and
|
|
52
|
-
* the install fails loudly — same posture every other facet binding
|
|
53
|
-
* has.
|
|
54
|
-
*
|
|
55
|
-
* Backpressure
|
|
56
|
-
* ────────────
|
|
57
|
-
* Hard cap: `MAX_PEER_FANOUT = 32` (POC B's flat zone). If
|
|
58
|
-
* `tasks.length > 32`, the surplus is queued and dispatched in
|
|
59
|
-
* subsequent rounds after the first 32 settle. This keeps the
|
|
60
|
-
* per-request peer-DO count bounded.
|
|
11
|
+
* Routing is deterministic: each task has a stable key, and the key maps
|
|
12
|
+
* to a sibling DO shard. There is no silent fallback to width-1 execution;
|
|
13
|
+
* missing LOADER or NIMBUS_SESSION bindings fail loudly so install and
|
|
14
|
+
* runtime operations do not appear successful after partial dispatch.
|
|
61
15
|
*/
|
|
62
16
|
import { serializeFunction } from './vendor/serialize.js';
|
|
63
17
|
import { BindingError } from './vendor/errors.js';
|
|
64
18
|
import { NimbusLoaderPool } from './loader-pool.js';
|
|
65
19
|
/**
|
|
66
|
-
* Threshold at which
|
|
20
|
+
* Threshold at which routing switches from coordinator-local loaders to
|
|
21
|
+
* sibling Durable Objects.
|
|
67
22
|
*
|
|
68
23
|
* Set to **5** so the in-DO path stays below the V8 4-loaders-per-method
|
|
69
|
-
* cap by construction. width < 5
|
|
24
|
+
* cap by construction. width < 5 stays local; width >= 5 uses sibling DOs.
|
|
70
25
|
*/
|
|
71
26
|
export const IN_DO_THRESHOLD = 5;
|
|
72
27
|
/**
|
|
73
|
-
* Hard cap on concurrent peer DOs per single submitMany call.
|
|
74
|
-
*
|
|
75
|
-
* pathological 500-pkg installs still parallelise as wide as the
|
|
76
|
-
* topology supports.
|
|
28
|
+
* Hard cap on concurrent peer DOs per single submitMany call. Throughput stays
|
|
29
|
+
* flat through this width while keeping per-request scheduler pressure bounded.
|
|
77
30
|
*/
|
|
78
31
|
export const MAX_PEER_FANOUT = 32;
|
|
79
32
|
/**
|
|
@@ -110,8 +63,8 @@ export class NimbusFanoutPool {
|
|
|
110
63
|
* results in input order.
|
|
111
64
|
*
|
|
112
65
|
* Routing:
|
|
113
|
-
* tasks.length < 5
|
|
114
|
-
* tasks.length >= 5
|
|
66
|
+
* tasks.length < 5 -> coordinator-local NimbusLoaderPool
|
|
67
|
+
* tasks.length >= 5 -> sibling NimbusSession DOs
|
|
115
68
|
*
|
|
116
69
|
* Backpressure: if `tasks.length > MAX_PEER_FANOUT (32)`, tasks
|
|
117
70
|
* are sharded modulo `MAX_PEER_FANOUT` and each shard's bucket
|
|
@@ -158,7 +111,7 @@ export class NimbusFanoutPool {
|
|
|
158
111
|
const shard = hashKeyToShard(key, peerCount);
|
|
159
112
|
return `nbf:${this.opts.tag}:${this.coordDoIdShort}:${shard}`;
|
|
160
113
|
}
|
|
161
|
-
// ── Private: in-DO dispatch (
|
|
114
|
+
// ── Private: in-DO dispatch (in-DO fanout) ──────────────────────────────
|
|
162
115
|
async _dispatchInDo(tasks, fn) {
|
|
163
116
|
// Use the existing NimbusLoaderPool. Concurrency = task count
|
|
164
117
|
// (capped at 4 by constructor — tasks.length is already < 5
|
|
@@ -192,7 +145,7 @@ export class NimbusFanoutPool {
|
|
|
192
145
|
catch { /* best-effort */ }
|
|
193
146
|
}
|
|
194
147
|
}
|
|
195
|
-
// ── Private: peer-DO dispatch (
|
|
148
|
+
// ── Private: peer-DO dispatch (peer-DO fanout) ────────────────────────────
|
|
196
149
|
async _dispatchPeerDo(tasks, fn) {
|
|
197
150
|
const ns = this.env?.NIMBUS_SESSION;
|
|
198
151
|
if (!ns || typeof ns.idFromName !== 'function' || typeof ns.get !== 'function') {
|
|
@@ -241,7 +194,7 @@ export class NimbusFanoutPool {
|
|
|
241
194
|
// Each peer DO RPC call uses ONE LOADER worker on its side.
|
|
242
195
|
// Supervisor → peer DO is a stub.fetch / RPC method call,
|
|
243
196
|
// NOT an env.LOADER.get(); that's the cap-sidestep that
|
|
244
|
-
// makes
|
|
197
|
+
// makes peer-DO fanout work.
|
|
245
198
|
const peerArgs = bucket.map((t) => t.args);
|
|
246
199
|
const rpcResp = await stub._rpcFanoutExecute(fnSource, peerArgs, {
|
|
247
200
|
tag: this.opts.tag,
|
|
@@ -271,25 +224,10 @@ export class NimbusFanoutPool {
|
|
|
271
224
|
}
|
|
272
225
|
});
|
|
273
226
|
}
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
//
|
|
278
|
-
// overflows → workerd cancels some shards with "Durable Object
|
|
279
|
-
// is overloaded" → batch-fanout aborts. Verified prod 15d3bfda:
|
|
280
|
-
// 17-33% session failure rate at N=12 concurrent.
|
|
281
|
-
//
|
|
282
|
-
// Wave-4d fix: chunk dispatch into PHASES. Each phase fires
|
|
283
|
-
// FANOUT_PHASE_SIZE shards via Promise.all and AWAITS phase
|
|
284
|
-
// completion before the next phase starts. Reduces simultaneous
|
|
285
|
-
// peer-DO cold-starts from N to FANOUT_PHASE_SIZE per session.
|
|
286
|
-
//
|
|
287
|
-
// FANOUT_PHASE_SIZE = 4: empirically the breakpoint where workerd
|
|
288
|
-
// schedules without queue overflow at N=12 concurrent (4 × 12 = 48
|
|
289
|
-
// simultaneous DO cold-starts, vs 8 × 12 = 96 for single-phase).
|
|
290
|
-
//
|
|
291
|
-
// NOT a sleep/setTimeout — pure Promise-chain serialization. Phase 2
|
|
292
|
-
// dispatchers START immediately when Phase 1 completes; no idle gap.
|
|
227
|
+
// Dispatch peer shards in bounded phases. A single Promise.all across all
|
|
228
|
+
// shards can create too many simultaneous cold sibling DO starts under
|
|
229
|
+
// concurrent installs. Promise-chain phasing limits scheduler pressure
|
|
230
|
+
// without sleeps, timers, or idle gaps between phases.
|
|
293
231
|
const FANOUT_PHASE_SIZE = 4;
|
|
294
232
|
for (let i = 0; i < dispatchers.length; i += FANOUT_PHASE_SIZE) {
|
|
295
233
|
const phase = dispatchers.slice(i, i + FANOUT_PHASE_SIZE);
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
* W7-frame symbols: encodeWriteBatchStream, decodeWriteBatchStream,
|
|
16
16
|
* W7_MAGIC, W7_TRAILER.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* Tar size: 3.86 KiB
|
|
18
|
+
* Tar size: 3.84 KiB
|
|
20
19
|
* W7 size: 7.78 KiB
|
|
21
20
|
*/
|
|
22
21
|
export declare const TAR_STREAM_PREAMBLE: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generated-workers.d.ts","sourceRoot":"","sources":["../../src/loaders/generated-workers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"generated-workers.d.ts","sourceRoot":"","sources":["../../src/loaders/generated-workers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,mBAAmB,EAAE,MAAygI,CAAC;AAE5iI,eAAO,MAAM,wBAAwB,EAAE,MAAa,CAAC;AAErD,eAAO,MAAM,iBAAiB,EAAE,MAA0jQ,CAAC;AAE3lQ,eAAO,MAAM,sBAAsB,EAAE,MAAa,CAAC"}
|