@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.
Files changed (160) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +6 -0
  3. package/README.md +2 -2
  4. package/dist/_shared/cache-stats.d.ts +1 -1
  5. package/dist/_shared/cache-stats.js +1 -1
  6. package/dist/_shared/exports-resolver.d.ts +0 -2
  7. package/dist/_shared/exports-resolver.d.ts.map +1 -1
  8. package/dist/_shared/exports-resolver.js +0 -2
  9. package/dist/_shared/session-router.d.ts +0 -1
  10. package/dist/_shared/session-router.d.ts.map +1 -1
  11. package/dist/_shared/session-router.js +0 -1
  12. package/dist/constants.d.ts.map +1 -1
  13. package/dist/constants.js +0 -1
  14. package/dist/facets/cirrus-real.d.ts +1 -1
  15. package/dist/facets/cirrus-real.js +1 -1
  16. package/dist/facets/manager.d.ts +0 -1
  17. package/dist/facets/manager.d.ts.map +1 -1
  18. package/dist/facets/manager.js +3 -15
  19. package/dist/facets/process.d.ts +2 -2
  20. package/dist/facets/process.js +2 -2
  21. package/dist/facets/vite-dev-server.d.ts +3 -3
  22. package/dist/facets/vite-dev-server.d.ts.map +1 -1
  23. package/dist/facets/vite-dev-server.js +6 -8
  24. package/dist/facets/wasm-swap-registry.d.ts +15 -21
  25. package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
  26. package/dist/facets/wasm-swap-registry.js +41 -54
  27. package/dist/facets/ws-terminal.d.ts +4 -5
  28. package/dist/facets/ws-terminal.d.ts.map +1 -1
  29. package/dist/facets/ws-terminal.js +7 -8
  30. package/dist/git/commands.d.ts.map +1 -1
  31. package/dist/git/commands.js +0 -1
  32. package/dist/git/network-facet.d.ts.map +1 -1
  33. package/dist/git/network-facet.js +0 -2
  34. package/dist/git-bundle.generated.d.ts +2 -3
  35. package/dist/git-bundle.generated.d.ts.map +1 -1
  36. package/dist/git-bundle.generated.js +3 -4
  37. package/dist/index.js +2 -2
  38. package/dist/loaders/child-process/spawn-facet.d.ts +7 -52
  39. package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -1
  40. package/dist/loaders/child-process/spawn-facet.js +7 -49
  41. package/dist/loaders/child-process/spawn-pool.d.ts +5 -44
  42. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
  43. package/dist/loaders/child-process/spawn-pool.js +5 -44
  44. package/dist/loaders/fanout-pool.d.ts +18 -65
  45. package/dist/loaders/fanout-pool.d.ts.map +1 -1
  46. package/dist/loaders/fanout-pool.js +25 -87
  47. package/dist/loaders/generated-workers.d.ts +1 -2
  48. package/dist/loaders/generated-workers.d.ts.map +1 -1
  49. package/dist/loaders/generated-workers.js +5 -6
  50. package/dist/loaders/loader-pool.d.ts +1 -2
  51. package/dist/loaders/loader-pool.d.ts.map +1 -1
  52. package/dist/loaders/loader-pool.js +1 -1
  53. package/dist/loaders/npm-resolve-preamble.d.ts +4 -5
  54. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
  55. package/dist/loaders/npm-resolve-preamble.js +14 -21
  56. package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -1
  57. package/dist/loaders/pre-bundle-preamble.js +0 -1
  58. package/dist/npm/cache.js +1 -1
  59. package/dist/npm/install-batch-facet.d.ts.map +1 -1
  60. package/dist/npm/install-batch-facet.js +7 -12
  61. package/dist/npm/installer.d.ts +5 -7
  62. package/dist/npm/installer.d.ts.map +1 -1
  63. package/dist/npm/installer.js +20 -101
  64. package/dist/npm/r2-cache.d.ts +17 -29
  65. package/dist/npm/r2-cache.d.ts.map +1 -1
  66. package/dist/npm/r2-cache.js +16 -27
  67. package/dist/npm/resolve-facet.d.ts +11 -17
  68. package/dist/npm/resolve-facet.d.ts.map +1 -1
  69. package/dist/npm/resolve-facet.js +14 -28
  70. package/dist/npm/resolve-one-facet.d.ts +10 -13
  71. package/dist/npm/resolve-one-facet.d.ts.map +1 -1
  72. package/dist/npm/resolve-one-facet.js +8 -10
  73. package/dist/npm/resolver.d.ts +0 -2
  74. package/dist/npm/resolver.d.ts.map +1 -1
  75. package/dist/npm/resolver.js +0 -12
  76. package/dist/observability/oom-discriminator.d.ts +0 -2
  77. package/dist/observability/oom-discriminator.d.ts.map +1 -1
  78. package/dist/observability/oom-discriminator.js +0 -2
  79. package/dist/replica/routing.js +1 -1
  80. package/dist/router/index.d.ts +1 -1
  81. package/dist/router/index.js +1 -1
  82. package/dist/runtime/barrel-synthesizer.js +1 -1
  83. package/dist/runtime/clang-runner.d.ts +5 -6
  84. package/dist/runtime/clang-runner.d.ts.map +1 -1
  85. package/dist/runtime/clang-runner.js +5 -6
  86. package/dist/runtime/esbuild-service.d.ts.map +1 -1
  87. package/dist/runtime/esbuild-service.js +0 -3
  88. package/dist/runtime/framework-detect.d.ts +0 -1
  89. package/dist/runtime/framework-detect.d.ts.map +1 -1
  90. package/dist/runtime/framework-detect.js +0 -1
  91. package/dist/runtime/node-runner.d.ts +1 -1
  92. package/dist/runtime/node-runner.js +1 -1
  93. package/dist/runtime/node-shims.d.ts.map +1 -1
  94. package/dist/runtime/node-shims.js +0 -22
  95. package/dist/runtime/package-manager.d.ts +2 -7
  96. package/dist/runtime/package-manager.d.ts.map +1 -1
  97. package/dist/runtime/package-manager.js +2 -7
  98. package/dist/runtime/process-logs-api.js +1 -1
  99. package/dist/runtime/process-logs.d.ts +0 -1
  100. package/dist/runtime/process-logs.d.ts.map +1 -1
  101. package/dist/runtime/process-table.d.ts +2 -2
  102. package/dist/runtime/process-table.d.ts.map +1 -1
  103. package/dist/runtime/process-table.js +1 -1
  104. package/dist/runtime/python-repl.d.ts +0 -1
  105. package/dist/runtime/python-repl.d.ts.map +1 -1
  106. package/dist/runtime/python-repl.js +0 -1
  107. package/dist/runtime/python-runner.d.ts +1 -2
  108. package/dist/runtime/python-runner.d.ts.map +1 -1
  109. package/dist/runtime/python-runner.js +1 -3
  110. package/dist/runtime/repl-session.d.ts +0 -1
  111. package/dist/runtime/repl-session.d.ts.map +1 -1
  112. package/dist/runtime/repl-session.js +1 -2
  113. package/dist/runtime/require-resolver.d.ts.map +1 -1
  114. package/dist/runtime/require-resolver.js +1 -4
  115. package/dist/runtime/ruby-runner.d.ts +0 -1
  116. package/dist/runtime/ruby-runner.d.ts.map +1 -1
  117. package/dist/runtime/ruby-runner.js +0 -1
  118. package/dist/runtime/runtime-catalog.d.ts +2 -4
  119. package/dist/runtime/runtime-catalog.d.ts.map +1 -1
  120. package/dist/runtime/runtime-catalog.js +2 -4
  121. package/dist/runtime/runtime-registry.d.ts +1 -1
  122. package/dist/runtime/runtime-registry.js +1 -1
  123. package/dist/runtime/streams.d.ts.map +1 -1
  124. package/dist/runtime/streams.js +0 -1
  125. package/dist/runtime/wasi-instance.d.ts +35 -45
  126. package/dist/runtime/wasi-instance.d.ts.map +1 -1
  127. package/dist/runtime/wasi-instance.js +87 -103
  128. package/dist/runtime/wasm-runner.d.ts +9 -15
  129. package/dist/runtime/wasm-runner.d.ts.map +1 -1
  130. package/dist/runtime/wasm-runner.js +23 -29
  131. package/dist/session/bindings.d.ts +2 -7
  132. package/dist/session/bindings.d.ts.map +1 -1
  133. package/dist/session/bindings.js +3 -8
  134. package/dist/session/helpers.d.ts +2 -9
  135. package/dist/session/helpers.d.ts.map +1 -1
  136. package/dist/session/helpers.js +2 -10
  137. package/dist/session/init.d.ts +3 -6
  138. package/dist/session/init.d.ts.map +1 -1
  139. package/dist/session/init.js +25 -30
  140. package/dist/session/nimbus-session.d.ts +1 -1
  141. package/dist/session/nimbus-session.js +5 -5
  142. package/dist/session/routes.d.ts.map +1 -1
  143. package/dist/session/routes.js +9 -16
  144. package/dist/session/rpc.d.ts +2 -2
  145. package/dist/session/rpc.js +6 -6
  146. package/dist/session/supervisor-rpc.d.ts +1 -2
  147. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  148. package/dist/session/supervisor-rpc.js +1 -5
  149. package/dist/shell/features.d.ts +5 -5
  150. package/dist/shell/features.js +6 -6
  151. package/dist/shell/unix-commands.js +15 -15
  152. package/dist/vfs/dev-provider.d.ts +1 -1
  153. package/dist/vfs/dev-provider.js +1 -1
  154. package/dist/vfs/sqlite-vfs.d.ts +3 -3
  155. package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
  156. package/dist/vfs/sqlite-vfs.js +10 -11
  157. package/package.json +12 -2
  158. package/public/s/index.html +44 -75
  159. package/scripts/bundle-facet-workers.mjs +1 -1
  160. 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 dogfood embedder are bit-identical
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 dogfood) flipping auth.mode to
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
- * spawn-facet.ts — Per-spawn task body run inside a fresh Worker Loader
3
- * isolate via NimbusFanoutPool.
2
+ * Per-spawn task body for Worker Loader isolates.
4
3
  *
5
- * Why this exists (gap #1 from arch-gaps wave)
6
- * ────────────────────────────────────────────
7
- * Pre-arch-gaps, child_process.spawn from inside a node facet RPCs back
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: `[g3-spawn-isolate] tok=<TOKEN>\n`.
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
- * Per-spawn task body. Serialised via fn.toString() and dispatched
74
- * by NimbusFanoutPool.submitMany. Signature must be (spec, env) so
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;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;;;wDAGoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;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
+ {"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
- * spawn-facet.ts — Per-spawn task body run inside a fresh Worker Loader
3
- * isolate via NimbusFanoutPool.
2
+ * Per-spawn task body for Worker Loader isolates.
4
3
  *
5
- * Why this exists (gap #1 from arch-gaps wave)
6
- * ────────────────────────────────────────────
7
- * Pre-arch-gaps, child_process.spawn from inside a node facet RPCs back
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
- * Per-spawn task body. Serialised via fn.toString() and dispatched
47
- * by NimbusFanoutPool.submitMany. Signature must be (spec, env) so
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
- // POC C route, "this DO" IS the user-session DO whose _cpRegistry
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
- * spawn-pool.ts — Supervisor-side wrapper that runs each cp.spawn
3
- * dispatch in a fresh Worker Loader isolate via NimbusFanoutPool.
2
+ * Supervisor-side child-process dispatch pool.
4
3
  *
5
- * Why this exists (gap #1 from arch-gaps wave)
6
- * ────────────────────────────────────────────
7
- * Closes the architectural gap surfaced by G1 S6: pre-arch-gaps,
8
- * cp.spawn / spawnSync / exec / execFile from inside a node facet
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;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
+ {"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
- * spawn-pool.ts — Supervisor-side wrapper that runs each cp.spawn
3
- * dispatch in a fresh Worker Loader isolate via NimbusFanoutPool.
2
+ * Supervisor-side child-process dispatch pool.
4
3
  *
5
- * Why this exists (gap #1 from arch-gaps wave)
6
- * ────────────────────────────────────────────
7
- * Closes the architectural gap surfaced by G1 S6: pre-arch-gaps,
8
- * cp.spawn / spawnSync / exec / execFile from inside a node facet
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
- * fanout-pool.ts — two-tier fan-out primitive.
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
- * Background
5
- * ──────────
6
- * The supervisor DO sits behind a V8 invariant: at most **4 concurrent
7
- * env.LOADER.get(...).getEntrypoint().fetch(...)** calls per DO method
8
- * invocation (3 from a Worker handler context). Beyond that, additional
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
- * The existing `NimbusLoaderPool` (src/loaders/loader-pool.ts) defaults
16
- * `concurrency = 4` precisely because of this cap. Every wide fan-out
17
- * site in `src/npm/installer.ts` (resolver, install-batch, pre-bundle)
18
- * was forced into a `concurrency: 1` outer pool with an internal
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 we switch from in-DO POC C → peer-DO POC B.
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 → POC C; width >= 5 → POC B.
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. POC B
71
- * measured flat throughput from N=8 to N=32; we use the ceiling so
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 → POC C in-DO via NimbusLoaderPool (concurrency = tasks.length, capped at 4)
144
- * tasks.length >= 5 → POC B peer-DO via env.NIMBUS_SESSION sibling DOs (deterministic stable-id router)
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAMH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC;;;;;GAKG;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;CAwH9B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAUrE"}
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
- * fanout-pool.ts — two-tier fan-out primitive.
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
- * Background
5
- * ──────────
6
- * The supervisor DO sits behind a V8 invariant: at most **4 concurrent
7
- * env.LOADER.get(...).getEntrypoint().fetch(...)** calls per DO method
8
- * invocation (3 from a Worker handler context). Beyond that, additional
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
- * The existing `NimbusLoaderPool` (src/loaders/loader-pool.ts) defaults
16
- * `concurrency = 4` precisely because of this cap. Every wide fan-out
17
- * site in `src/npm/installer.ts` (resolver, install-batch, pre-bundle)
18
- * was forced into a `concurrency: 1` outer pool with an internal
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 we switch from in-DO POC C → peer-DO POC B.
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 → POC C; width >= 5 → POC B.
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. POC B
74
- * measured flat throughput from N=8 to N=32; we use the ceiling so
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 → POC C in-DO via NimbusLoaderPool (concurrency = tasks.length, capped at 4)
114
- * tasks.length >= 5 → POC B peer-DO via env.NIMBUS_SESSION sibling DOs (deterministic stable-id router)
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 (POC C) ──────────────────────────────
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 (POC B) ────────────────────────────
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 POC B work.
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
- // [P0a wave-4d STAGGERED FAN-OUT]
275
- // Dispatching all N shards via a single Promise.all triggered N
276
- // simultaneous peer-DO cold-starts. Under concurrent-session load
277
- // (N sessions × M shards each), the workerd DO scheduler queue
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
- * Generated at: 2026-06-04T22:29:13.391Z
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;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,mBAAmB,EAAE,MAAyhI,CAAC;AAE5jI,eAAO,MAAM,wBAAwB,EAAE,MAAa,CAAC;AAErD,eAAO,MAAM,iBAAiB,EAAE,MAA+jQ,CAAC;AAEhmQ,eAAO,MAAM,sBAAsB,EAAE,MAAa,CAAC"}
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"}