@nimbus-sh/fabric 0.6.0 → 0.7.1
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/README.md +19 -1
- package/dist/bindings.d.ts +10 -0
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js +17 -8
- package/dist/fanout.d.ts.map +1 -1
- package/dist/fanout.js +2 -0
- package/dist/host-dispatch.d.ts +12 -4
- package/dist/host-dispatch.d.ts.map +1 -1
- package/dist/host-dispatch.js +11 -4
- package/dist/isolate-pool.d.ts +7 -0
- package/dist/isolate-pool.d.ts.map +1 -1
- package/dist/isolate-pool.js +2 -2
- package/dist/process-fabric.d.ts +7 -0
- package/dist/process-fabric.d.ts.map +1 -1
- package/dist/process-host.d.ts +3 -0
- package/dist/process-host.d.ts.map +1 -1
- package/dist/process-host.js +5 -2
- package/dist/turn-budget.d.ts +5 -1
- package/dist/turn-budget.d.ts.map +1 -1
- package/dist/turn-budget.js +45 -12
- package/dist/workerd-facet-host.d.ts.map +1 -1
- package/dist/workerd-facet-host.js +3 -3
- package/package.json +4 -4
- package/src/bindings.ts +23 -10
- package/src/fanout.ts +2 -0
- package/src/host-dispatch.ts +22 -7
- package/src/isolate-pool.ts +8 -2
- package/src/process-fabric.ts +7 -0
- package/src/process-host.ts +7 -2
- package/src/turn-budget.ts +41 -12
- package/src/workerd-facet-host.ts +3 -5
package/README.md
CHANGED
|
@@ -51,7 +51,25 @@ composeFabric({
|
|
|
51
51
|
adoptCtxExports(ctx.exports);
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
`composeFabric` runs once per isolate. Calling it again with the same values
|
|
55
|
+
is a no-op; calling it again with different values throws, naming both. A
|
|
56
|
+
Worker that imports Nimbus's own entry (`@nimbus-sh/sdk/worker`) inherits
|
|
57
|
+
that entry's composition, so a host that names its own namespace composes in
|
|
58
|
+
a Worker that does not import it.
|
|
59
|
+
|
|
60
|
+
The route back to the host (namespace, dispatch method, supervisor
|
|
61
|
+
entrypoint) is minted into every binding the fabric hands a program, in the
|
|
62
|
+
host's isolate, and the entrypoints that answer those bindings read it from
|
|
63
|
+
their props. The platform serves a Worker's entrypoints from whichever
|
|
64
|
+
isolate it likes; an isolate that composed nothing still answers to the
|
|
65
|
+
right host.
|
|
66
|
+
|
|
67
|
+
Every instance of the host namespace forwards `supervisorOp(envelope)` to a
|
|
68
|
+
hosted runtime, the siblings Nimbus opens by name included: a wide `npm
|
|
69
|
+
install` fans out to `nbf:*` peers of the same namespace, and
|
|
70
|
+
`NIMBUS_PROCESS_HOST=peer` places processes on siblings. A sibling that
|
|
71
|
+
forwards to a bare workspace answers "is a host op, and this handler is a
|
|
72
|
+
bare workspace's".
|
|
55
73
|
|
|
56
74
|
## Timers
|
|
57
75
|
|
package/dist/bindings.d.ts
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
26
26
|
import { z } from 'zod/v4';
|
|
27
|
+
import type { HostRoute } from './composition.js';
|
|
27
28
|
import type { WorkerCode } from './vendor/types.js';
|
|
28
29
|
/**
|
|
29
30
|
* A dynamic worker's entrypoint, as hop 3 relays to it. `fetch` is the
|
|
@@ -67,6 +68,8 @@ interface NimbusAssetsProps {
|
|
|
67
68
|
assetsDir?: string;
|
|
68
69
|
/** Supervisor DO id whose VFS holds the assets. */
|
|
69
70
|
doId?: string;
|
|
71
|
+
/** The way back to that DO, minted with the binding. */
|
|
72
|
+
route?: HostRoute;
|
|
70
73
|
}
|
|
71
74
|
/**
|
|
72
75
|
* Assets binding shim. The inner Worker calls `env.ASSETS.fetch(request)`
|
|
@@ -105,6 +108,11 @@ declare const NimbusLoadedEntrypointPropsSchema: z.ZodObject<{
|
|
|
105
108
|
doId: z.ZodString;
|
|
106
109
|
pid: z.ZodNumber;
|
|
107
110
|
writerId: z.ZodString;
|
|
111
|
+
route: z.ZodOptional<z.ZodObject<{
|
|
112
|
+
supervisorEntrypoint: z.ZodString;
|
|
113
|
+
hostNamespace: z.ZodString;
|
|
114
|
+
hostDispatchMethod: z.ZodString;
|
|
115
|
+
}, z.core.$strip>>;
|
|
108
116
|
}, z.core.$strip>>;
|
|
109
117
|
stage: z.ZodOptional<z.ZodUnknown>;
|
|
110
118
|
}, z.core.$loose>;
|
|
@@ -213,6 +221,8 @@ export declare class NimbusLoadedEntrypoint extends WorkerEntrypoint<NimbusLoade
|
|
|
213
221
|
interface NimbusDoNamespaceProps {
|
|
214
222
|
bindingName?: string;
|
|
215
223
|
supervisorDoId?: string;
|
|
224
|
+
/** The way back to the supervisor DO, minted with the binding. */
|
|
225
|
+
route?: HostRoute;
|
|
216
226
|
}
|
|
217
227
|
/**
|
|
218
228
|
* `env.MY_DO` shim — a DurableObjectNamespace-like WorkerEntrypoint.
|
package/dist/bindings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
|
package/dist/bindings.js
CHANGED
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
26
26
|
import { z } from 'zod/v4';
|
|
27
27
|
import { disposeRpcResource, useRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
28
|
-
import { supervisorEntrypoint, supervisorEntrypointName } from './composition.js';
|
|
29
|
-
import { stagedBootAssembler } from './composition.js';
|
|
28
|
+
import { supervisorEntrypoint, supervisorEntrypointName, stagedBootAssembler } from './composition.js';
|
|
30
29
|
import { hostNamespaceBinding, hostOpDispatch } from './host-dispatch.js';
|
|
31
30
|
import { assertModuleMapWithinCodeLimit } from './budgets.js';
|
|
32
31
|
/**
|
|
@@ -98,9 +97,9 @@ export class NimbusAssetsRPC extends WorkerEntrypoint {
|
|
|
98
97
|
let stub = null;
|
|
99
98
|
let dispatch;
|
|
100
99
|
try {
|
|
101
|
-
const ns = hostNamespaceBinding(this.env, 'NimbusAssetsRPC');
|
|
100
|
+
const ns = hostNamespaceBinding(this.env, 'NimbusAssetsRPC', props.route);
|
|
102
101
|
stub = ns.get(ns.idFromString(doId));
|
|
103
|
-
dispatch = hostOpDispatch(stub, 'NimbusAssetsRPC');
|
|
102
|
+
dispatch = hostOpDispatch(stub, 'NimbusAssetsRPC', props.route);
|
|
104
103
|
}
|
|
105
104
|
catch (e) {
|
|
106
105
|
disposeRpcResource(stub);
|
|
@@ -242,6 +241,11 @@ function mimeTypeForPath(path) {
|
|
|
242
241
|
const _NIMBUS_LOADED_CODES = new Map();
|
|
243
242
|
const _LOADED_CODES_MAX = 32;
|
|
244
243
|
let _loadedCodesEvictions = 0;
|
|
244
|
+
const HostRouteSchema = z.object({
|
|
245
|
+
supervisorEntrypoint: z.string().min(1),
|
|
246
|
+
hostNamespace: z.string().min(1),
|
|
247
|
+
hostDispatchMethod: z.string().min(1),
|
|
248
|
+
});
|
|
245
249
|
const NimbusLoadedEntrypointPropsSchema = z.object({
|
|
246
250
|
key: z.string().min(1),
|
|
247
251
|
name: z.string().nullable().optional(),
|
|
@@ -250,6 +254,7 @@ const NimbusLoadedEntrypointPropsSchema = z.object({
|
|
|
250
254
|
doId: z.string().min(1),
|
|
251
255
|
pid: z.number().int().nonnegative(),
|
|
252
256
|
writerId: z.string().uuid(),
|
|
257
|
+
route: HostRouteSchema.optional(),
|
|
253
258
|
}).optional(),
|
|
254
259
|
/**
|
|
255
260
|
* Staged-artifact spec, for a ONE-SHOT run. The module map — ~23 MB for
|
|
@@ -445,9 +450,12 @@ export class NimbusLoadedEntrypoint extends WorkerEntrypoint {
|
|
|
445
450
|
async _supervisorBinding(props) {
|
|
446
451
|
if (!props.supervisor)
|
|
447
452
|
return undefined;
|
|
448
|
-
|
|
453
|
+
// The route names the entrypoint too: this stateless hop may run in an
|
|
454
|
+
// isolate whose composition is not the host's.
|
|
455
|
+
const name = props.supervisor.route?.supervisorEntrypoint ?? supervisorEntrypointName();
|
|
456
|
+
const factory = supervisorEntrypoint(ctxExportsOf(this.ctx), name ?? undefined);
|
|
449
457
|
if (!factory) {
|
|
450
|
-
throw new Error(`Nimbus: ctx.exports.${
|
|
458
|
+
throw new Error(`Nimbus: ctx.exports.${name ?? '<supervisor entrypoint>'} unavailable`);
|
|
451
459
|
}
|
|
452
460
|
return await factory({ props: props.supervisor });
|
|
453
461
|
}
|
|
@@ -635,6 +643,7 @@ export class NimbusDurableObjectNamespace extends WorkerEntrypoint {
|
|
|
635
643
|
props: {
|
|
636
644
|
bindingName: props.bindingName,
|
|
637
645
|
supervisorDoId: props.supervisorDoId,
|
|
646
|
+
route: props.route,
|
|
638
647
|
id: String(id),
|
|
639
648
|
},
|
|
640
649
|
});
|
|
@@ -664,9 +673,9 @@ export class NimbusDOStub extends WorkerEntrypoint {
|
|
|
664
673
|
let stub = null;
|
|
665
674
|
let dispatch;
|
|
666
675
|
try {
|
|
667
|
-
const ns = hostNamespaceBinding(this.env ?? {}, 'NimbusDOStub');
|
|
676
|
+
const ns = hostNamespaceBinding(this.env ?? {}, 'NimbusDOStub', props.route);
|
|
668
677
|
stub = ns.get(ns.idFromString(supervisorDoId));
|
|
669
|
-
dispatch = hostOpDispatch(stub, 'NimbusDOStub');
|
|
678
|
+
dispatch = hostOpDispatch(stub, 'NimbusDOStub', props.route);
|
|
670
679
|
}
|
|
671
680
|
catch (e) {
|
|
672
681
|
disposeRpcResource(stub);
|
package/dist/fanout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fanout.d.ts","sourceRoot":"","sources":["../src/fanout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"fanout.d.ts","sourceRoot":"","sources":["../src/fanout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOtD;;+EAE+E;AAC/E,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC;;;GAGG;AACH,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,qBAAqB,UAAmB,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,UAAqB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,uCAAuC;AACvC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,IAAI,EAAE,CAAC,CAAC;CACT;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B;;;;;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;IACzB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAWD;;;;;;;;GAQG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,aAAa;IAoBzE;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,UAAU,CAAC,CAAC,EAAE,CAAC,EACnB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EACtB,EAAE,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GACpB,OAAO,CAAC,CAAC,EAAE,CAAC;IASf,mEAAmE;IACnE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO;IAK7D;;;;;;OAMG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;YAOvC,aAAa;YAoCb,eAAe;CA4J9B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAUrE"}
|
package/dist/fanout.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { serializeFunction } from './vendor/serialize.js';
|
|
17
17
|
import { BindingError } from './vendor/errors.js';
|
|
18
18
|
import { IsolatePool } from './isolate-pool.js';
|
|
19
|
+
import { hostRoute } from './composition.js';
|
|
19
20
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
20
21
|
import { describeError, isDoOverloaded, isTransientDoReset } from '@nimbus-sh/platform/oom-classify.js';
|
|
21
22
|
import { hostNamespaceBinding, hostOpDispatch, } from './host-dispatch.js';
|
|
@@ -265,6 +266,7 @@ export class Fanout {
|
|
|
265
266
|
// ... write into the peer's own VFS — invisible to the
|
|
266
267
|
// user. See INSTALL-HONESTY-retro.md.
|
|
267
268
|
coordinatorDoId: this.coordDoId,
|
|
269
|
+
coordinatorRoute: hostRoute() ?? undefined,
|
|
268
270
|
// Credential source for peer-side writeBatchStream — the
|
|
269
271
|
// invoking process pid, so package writes are authorized
|
|
270
272
|
// as the user (not rejected as pid:0).
|
package/dist/host-dispatch.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HostRoute } from './composition.js';
|
|
2
|
+
import type { SupervisorOpDispatch } from '@nimbus-sh/core/workspace/supervisor-op.js';
|
|
2
3
|
export type HostNamespaceBinding = Pick<DurableObjectNamespace, 'get' | 'idFromName' | 'idFromString'>;
|
|
3
|
-
export type HostOpDispatch =
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export type HostOpDispatch = SupervisorOpDispatch;
|
|
5
|
+
/**
|
|
6
|
+
* The host's namespace binding. An entrypoint answering a facet passes the
|
|
7
|
+
* route the binding's props carry, minted in the host's isolate; the host
|
|
8
|
+
* itself, and a binding minted before routes travelled (a facet outlives
|
|
9
|
+
* the deploy that minted its binding), resolve from this isolate's
|
|
10
|
+
* composition.
|
|
11
|
+
*/
|
|
12
|
+
export declare function hostNamespaceBinding(env: object | null | undefined, usage: string, route?: Pick<HostRoute, 'hostNamespace'>): HostNamespaceBinding;
|
|
13
|
+
export declare function hostOpDispatch(stub: object, usage: string, route?: Pick<HostRoute, 'hostDispatchMethod'>): HostOpDispatch;
|
|
6
14
|
//# sourceMappingURL=host-dispatch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-dispatch.d.ts","sourceRoot":"","sources":["../src/host-dispatch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"host-dispatch.d.ts","sourceRoot":"","sources":["../src/host-dispatch.ts"],"names":[],"mappings":"AACA,OAAO,EAAqC,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAEvF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,sBAAsB,EAAE,KAAK,GAAG,YAAY,GAAG,cAAc,CAAC,CAAC;AACvG,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAQlD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,GACvC,oBAAoB,CAOtB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,GAC5C,cAAc,CAWhB"}
|
package/dist/host-dispatch.js
CHANGED
|
@@ -5,16 +5,23 @@ function isNamespace(value) {
|
|
|
5
5
|
&& typeof Reflect.get(value, 'idFromString') === 'function'
|
|
6
6
|
&& typeof Reflect.get(value, 'get') === 'function';
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The host's namespace binding. An entrypoint answering a facet passes the
|
|
10
|
+
* route the binding's props carry, minted in the host's isolate; the host
|
|
11
|
+
* itself, and a binding minted before routes travelled (a facet outlives
|
|
12
|
+
* the deploy that minted its binding), resolve from this isolate's
|
|
13
|
+
* composition.
|
|
14
|
+
*/
|
|
15
|
+
export function hostNamespaceBinding(env, usage, route) {
|
|
16
|
+
const name = route?.hostNamespace ?? hostNamespace();
|
|
10
17
|
const binding = env ? Reflect.get(env, name) : undefined;
|
|
11
18
|
if (binding === null || (typeof binding !== 'object' && typeof binding !== 'function') || !isNamespace(binding)) {
|
|
12
19
|
throw new BindingError(`${usage}: env.${name} must be the Durable Object namespace configured by composeFabric`);
|
|
13
20
|
}
|
|
14
21
|
return binding;
|
|
15
22
|
}
|
|
16
|
-
export function hostOpDispatch(stub, usage) {
|
|
17
|
-
const name = hostDispatchMethod();
|
|
23
|
+
export function hostOpDispatch(stub, usage, route) {
|
|
24
|
+
const name = route?.hostDispatchMethod ?? hostDispatchMethod();
|
|
18
25
|
if (stub === null || (typeof stub !== 'object' && typeof stub !== 'function')) {
|
|
19
26
|
throw new BindingError(`${usage}: the workspace namespace returned no stub`);
|
|
20
27
|
}
|
package/dist/isolate-pool.d.ts
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* The vendored directory contains only the upstream serialization, error,
|
|
24
24
|
* and binding types used by this implementation.
|
|
25
25
|
*/
|
|
26
|
+
import { type HostRoute } from './composition.js';
|
|
26
27
|
import type { FacetBindings } from '@nimbus-sh/core/runtime/facet-host.js';
|
|
27
28
|
import type { WorkerLoader } from './vendor/types.js';
|
|
28
29
|
/**
|
|
@@ -102,6 +103,12 @@ export interface IsolatePoolOptions {
|
|
|
102
103
|
* coordinator. Effective only when `omitSupervisor !== true`.
|
|
103
104
|
*/
|
|
104
105
|
supervisorDoIdOverride?: string;
|
|
106
|
+
/**
|
|
107
|
+
* The coordinator's route, forwarded with `supervisorDoIdOverride`: the
|
|
108
|
+
* binding is the coordinator's, so its way back is the coordinator's
|
|
109
|
+
* too, whatever this peer's isolate composed.
|
|
110
|
+
*/
|
|
111
|
+
supervisorRoute?: HostRoute;
|
|
105
112
|
/**
|
|
106
113
|
* Process pid baked into the auto-injected SUPERVISOR binding's props.
|
|
107
114
|
* The supervisor derives the write credential from this pid
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isolate-pool.d.ts","sourceRoot":"","sources":["../src/isolate-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;
|
|
1
|
+
{"version":3,"file":"isolate-pool.d.ts","sourceRoot":"","sources":["../src/isolate-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAanF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,IAAI;IAC9B,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnD,CAAC,MAAM,CAAC,CAAC;AAEV,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,mDAAmD;AACnD,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;OAgBG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC3C;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC3C;AAED,oEAAoE;AACpE,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACrC;AAkCD,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,8EAA8E;AAC9E,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,+BAA+B,GACvC,MAAM,CAgFR;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,WAAW;;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;IAC7D;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAsC;IAEtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAOzB;IACH;;;;4DAIwD;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAE7B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,kBAAkB,EACvB,IAAI,CAAC,EAAE,kBAAkB;IA+G3B,wEAAwE;IACxE,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAyZD;;;OAGG;IACG,MAAM,CAAC,CAAC,EAAE,CAAC,EACf,EAAE,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,GAAG,EAAE,CAAC,EACN,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAatB;;;;;;;;OAQG;IACG,aAAa,CACjB,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,EAC1E,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,QAAQ,CAAC;IAwBpB;;;;;OAKG;IACG,GAAG,CAAC,CAAC,EAAE,CAAC,EACZ,EAAE,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAOpC;;;;;;;;;;;;;;;;OAgBG;IACG,SAAS,CAAC,CAAC,EAAE,CAAC,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IA+DpC;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,IAAI;CAShB"}
|
package/dist/isolate-pool.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* and binding types used by this implementation.
|
|
25
25
|
*/
|
|
26
26
|
import { CF_COMPAT_DATE } from '@nimbus-sh/core/constants.js';
|
|
27
|
-
import { supervisorEntrypoint } from './composition.js';
|
|
27
|
+
import { hostRoute, supervisorEntrypoint } from './composition.js';
|
|
28
28
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
29
29
|
import { serializeFunction, hashSource } from './vendor/serialize.js';
|
|
30
30
|
import { beginLoaderFetch, recordLoaderId, withDynamicWorkerCapNamed } from './budgets.js';
|
|
@@ -243,7 +243,7 @@ export class IsolatePool {
|
|
|
243
243
|
const supDoId = opts?.supervisorDoIdOverride ?? ctx.id.toString();
|
|
244
244
|
const supPid = opts?.supervisorPid ?? 0;
|
|
245
245
|
bindings.SUPERVISOR = supervisorRpc({
|
|
246
|
-
props: { doId: supDoId, pid: supPid },
|
|
246
|
+
props: { doId: supDoId, pid: supPid, route: opts?.supervisorRoute ?? hostRoute() ?? undefined },
|
|
247
247
|
});
|
|
248
248
|
// Whatever the minted worker's env carries must be in its loader
|
|
249
249
|
// cache key — workerd's loader cache survives a DO hibernation
|
package/dist/process-fabric.d.ts
CHANGED
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
* bytes, and the host reads them off the coordinator's own disk through the
|
|
74
74
|
* `ResidentDiskReader` it was given.
|
|
75
75
|
*/
|
|
76
|
+
import type { HostRoute } from './composition.js';
|
|
76
77
|
import { z } from 'zod/v4';
|
|
77
78
|
import type { RouteableFacetTarget } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
78
79
|
import type { ServiceStub } from './vendor/types.js';
|
|
@@ -222,6 +223,12 @@ export interface ResidentSupervisorProps {
|
|
|
222
223
|
doId: string;
|
|
223
224
|
pid: number;
|
|
224
225
|
writerId: string;
|
|
226
|
+
/**
|
|
227
|
+
* The way back to the coordinator, minted with the binding. Absent only
|
|
228
|
+
* when the coordinator's isolate composed nothing, in which case no
|
|
229
|
+
* supervisor binding is minted either.
|
|
230
|
+
*/
|
|
231
|
+
route?: HostRoute;
|
|
225
232
|
}
|
|
226
233
|
/** Everything a host needs to run one process. Substrate-free by construction. */
|
|
227
234
|
export interface ProcessHostParams {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-fabric.d.ts","sourceRoot":"","sources":["../src/process-fabric.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBA0CjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK;;;;;;;;;;;;;;;;;4BAKjF;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAU7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,gCAAgC,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAID;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAmBlC;AA2BD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"process-fabric.d.ts","sourceRoot":"","sources":["../src/process-fabric.ts"],"names":[],"mappings":"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"}
|
package/dist/process-host.d.ts
CHANGED
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
* that pair unforgeable by anything that did not open the process.
|
|
65
65
|
*/
|
|
66
66
|
import { type ProcessHost, type ResidentDiskReader } from './process-fabric.js';
|
|
67
|
+
import { type HostRoute } from './composition.js';
|
|
67
68
|
/** The substrates this deployment can be configured for. */
|
|
68
69
|
export type ProcessHostMode = 'facet' | 'peer';
|
|
69
70
|
/**
|
|
@@ -79,6 +80,8 @@ export declare function isolateToken(): string;
|
|
|
79
80
|
/** Options the coordinator hands a hosting peer. */
|
|
80
81
|
export interface HostProcessOpts {
|
|
81
82
|
coordinatorDoId: string;
|
|
83
|
+
/** The coordinator's route, minted into the process's SUPERVISOR binding. */
|
|
84
|
+
route?: HostRoute;
|
|
82
85
|
pid: number;
|
|
83
86
|
writerId: string;
|
|
84
87
|
workerKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-host.d.ts","sourceRoot":"","sources":["../src/process-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAOH,OAAO,EAGL,KAAK,WAAW,EAIhB,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"process-host.d.ts","sourceRoot":"","sources":["../src/process-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAOH,OAAO,EAGL,KAAK,WAAW,EAIhB,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7D,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,kBAAkB,GAC7B,WAAW,CAIb;AA+ED,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;CAC7B;AAaD;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,8BAA8B,CAAC;AACvE,eAAO,MAAM,kCAAkC,yCAAyC,CAAC;AAiUzF;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAWhE"}
|
package/dist/process-host.js
CHANGED
|
@@ -71,6 +71,7 @@ import { z } from 'zod/v4';
|
|
|
71
71
|
import { DYNAMIC_WORKER_CODE_LIMIT_BYTES } from './budgets.js';
|
|
72
72
|
import { BindingError } from './vendor/errors.js';
|
|
73
73
|
import { processes, } from './workerd-facet-host.js';
|
|
74
|
+
import { hostRoute } from './composition.js';
|
|
74
75
|
/**
|
|
75
76
|
* The substrate for this deployment, resolved once. The mode arrives already
|
|
76
77
|
* decided — the embedder owns the config var that picks it, and refuses an
|
|
@@ -108,13 +109,14 @@ class FacetProcessHost {
|
|
|
108
109
|
this.coordDoId = ctx.id.toString();
|
|
109
110
|
}
|
|
110
111
|
runOnce(params, consume) {
|
|
111
|
-
return processes(this.ctx, this.env).run({ doId: this.coordDoId, pid: params.pid, writerId: params.writerId }, params, consume);
|
|
112
|
+
return processes(this.ctx, this.env).run({ doId: this.coordDoId, pid: params.pid, writerId: params.writerId, route: hostRoute() ?? undefined }, params, consume);
|
|
112
113
|
}
|
|
113
114
|
async open(params) {
|
|
114
115
|
const supervisor = {
|
|
115
116
|
doId: this.coordDoId,
|
|
116
117
|
pid: params.pid,
|
|
117
118
|
writerId: params.writerId,
|
|
119
|
+
route: hostRoute() ?? undefined,
|
|
118
120
|
};
|
|
119
121
|
const { name, ...facet } = processes(this.ctx, this.env).spawn(this.disk, supervisor, params);
|
|
120
122
|
return {
|
|
@@ -259,7 +261,7 @@ class PeerProcessHost {
|
|
|
259
261
|
* worker of the coordinator here exactly as it does on `facet`.
|
|
260
262
|
*/
|
|
261
263
|
runOnce(params, consume) {
|
|
262
|
-
return processes(this.ctx, this.env).run({ doId: this.coordDoId, pid: params.pid, writerId: params.writerId }, params, consume);
|
|
264
|
+
return processes(this.ctx, this.env).run({ doId: this.coordDoId, pid: params.pid, writerId: params.writerId, route: hostRoute() ?? undefined }, params, consume);
|
|
263
265
|
}
|
|
264
266
|
async open(params) {
|
|
265
267
|
if (params.facet) {
|
|
@@ -280,6 +282,7 @@ class PeerProcessHost {
|
|
|
280
282
|
// the peer dies under either.
|
|
281
283
|
const hostLeg = placement.stub._rpcHostProcess(params.boot, {
|
|
282
284
|
coordinatorDoId: this.coordDoId,
|
|
285
|
+
route: hostRoute() ?? undefined,
|
|
283
286
|
pid: params.pid,
|
|
284
287
|
writerId: params.writerId,
|
|
285
288
|
workerKey: params.workerKey,
|
package/dist/turn-budget.d.ts
CHANGED
|
@@ -114,7 +114,7 @@ export interface PacedWorkHost {
|
|
|
114
114
|
* reason. Without it the pump degrades to a same-context timer — see
|
|
115
115
|
* {@link PacedWork.nextTurn}.
|
|
116
116
|
*/
|
|
117
|
-
requestTurn?: (notBefore?: number) => void
|
|
117
|
+
requestTurn?: (notBefore?: number) => void | Promise<void>;
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
120
|
* The granting side of {@link TurnScheduler}: parks suspended launches
|
|
@@ -134,6 +134,7 @@ export declare class PacedWork implements TurnScheduler {
|
|
|
134
134
|
* from its inputs is the same idempotent work again.
|
|
135
135
|
*/
|
|
136
136
|
private waiters;
|
|
137
|
+
private closed;
|
|
137
138
|
/**
|
|
138
139
|
* `ctx` keys the cold-start queue the pump drains first on every turn it
|
|
139
140
|
* grants — see {@link pump}.
|
|
@@ -159,6 +160,9 @@ export declare class PacedWork implements TurnScheduler {
|
|
|
159
160
|
* the runtime may tear the context down mid-chunk.
|
|
160
161
|
*/
|
|
161
162
|
pump(): Promise<void>;
|
|
163
|
+
private requestTurn;
|
|
164
|
+
/** Reject parked work before the owner drains launch cleanup and cancels its alarm. */
|
|
165
|
+
close(reason?: Error): void;
|
|
162
166
|
/** Whether any launch is suspended waiting for a turn. */
|
|
163
167
|
get hasPending(): boolean;
|
|
164
168
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-budget.d.ts","sourceRoot":"","sources":["../src/turn-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,qBAAa,UAAU;IAkBnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAnB/B,qEAAqE;IACrE,MAAM,SAAK;IACX,iDAAiD;IACjD,KAAK,SAAK;IAEV,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,UAAU,CAA8D;IAEhF;;;;;;;OAOG;gBAEgB,SAAS,EAAE,aAAa,EACxB,aAAa,GAAE,MAA6B,EAC5C,WAAW,CAAC,GAAE,MAAM,IAAI,aAAA;IAG3C;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczC;;;;OAIG;IACH,MAAM,IAAI,IAAI;CAIf;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,CAAC,GAAG,IAAI,KAAK;IAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;CAAE,CAI/G;AAED,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"turn-budget.d.ts","sourceRoot":"","sources":["../src/turn-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,qBAAa,UAAU;IAkBnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAnB/B,qEAAqE;IACrE,MAAM,SAAK;IACX,iDAAiD;IACjD,KAAK,SAAK;IAEV,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,UAAU,CAA8D;IAEhF;;;;;;;OAOG;gBAEgB,SAAS,EAAE,aAAa,EACxB,aAAa,GAAE,MAA6B,EAC5C,WAAW,CAAC,GAAE,MAAM,IAAI,aAAA;IAG3C;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczC;;;;OAIG;IACH,MAAM,IAAI,IAAI;CAIf;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,CAAC,GAAG,IAAI,KAAK;IAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;CAAE,CAI/G;AAED,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED;;;GAGG;AACH,qBAAa,SAAU,YAAW,aAAa;IAmB3C,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAnBvB;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAqH;IACpI,OAAO,CAAC,MAAM,CAAoB;IAElC;;;OAGG;gBAEgB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa;IAGtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjE;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBb,WAAW;IAKzB,uFAAuF;IACvF,KAAK,CAAC,MAAM,QAA0C,GAAG,IAAI;IAK7D,0DAA0D;IAC1D,IAAI,UAAU,IAAI,OAAO,CAExB;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAMtD"}
|
package/dist/turn-budget.js
CHANGED
|
@@ -130,6 +130,7 @@ export class PacedWork {
|
|
|
130
130
|
* from its inputs is the same idempotent work again.
|
|
131
131
|
*/
|
|
132
132
|
waiters = [];
|
|
133
|
+
closed;
|
|
133
134
|
/**
|
|
134
135
|
* `ctx` keys the cold-start queue the pump drains first on every turn it
|
|
135
136
|
* grants — see {@link pump}.
|
|
@@ -149,10 +150,19 @@ export class PacedWork {
|
|
|
149
150
|
* responsiveness but keeps the behaviour.
|
|
150
151
|
*/
|
|
151
152
|
nextTurn(chunkEnded, notBefore = 0) {
|
|
152
|
-
|
|
153
|
-
this.
|
|
153
|
+
if (this.closed)
|
|
154
|
+
return Promise.reject(this.closed);
|
|
155
|
+
return new Promise((resume, reject) => {
|
|
156
|
+
const waiter = { resume, reject, chunkEnded, notBefore };
|
|
157
|
+
this.waiters.push(waiter);
|
|
154
158
|
if (this.host.requestTurn) {
|
|
155
|
-
this.
|
|
159
|
+
void this.requestTurn(notBefore).catch((error) => {
|
|
160
|
+
const index = this.waiters.indexOf(waiter);
|
|
161
|
+
if (index < 0)
|
|
162
|
+
return;
|
|
163
|
+
this.waiters.splice(index, 1);
|
|
164
|
+
waiter.reject(error);
|
|
165
|
+
});
|
|
156
166
|
return;
|
|
157
167
|
}
|
|
158
168
|
setTimeout(() => { void this.pump(); }, Math.max(0, notBefore - Date.now()));
|
|
@@ -167,21 +177,44 @@ export class PacedWork {
|
|
|
167
177
|
* the runtime may tear the context down mid-chunk.
|
|
168
178
|
*/
|
|
169
179
|
async pump() {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// is what an alarm calls, and the first turn after a reset is the
|
|
173
|
-
// re-delivered alarm of a launch the reset interrupted.
|
|
180
|
+
if (this.closed)
|
|
181
|
+
return;
|
|
174
182
|
await runColdStart(this.ctx);
|
|
183
|
+
if (this.closed)
|
|
184
|
+
return;
|
|
175
185
|
const now = Date.now();
|
|
176
186
|
const waiting = this.waiters.filter((waiter) => waiter.notBefore <= now);
|
|
177
187
|
this.waiters = this.waiters.filter((waiter) => waiter.notBefore > now);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
188
|
+
const future = [...this.waiters];
|
|
189
|
+
const scheduled = future.length > 0
|
|
190
|
+
? this.requestTurn(Math.min(...future.map((waiter) => waiter.notBefore))).catch((error) => {
|
|
191
|
+
for (const waiter of future) {
|
|
192
|
+
const index = this.waiters.indexOf(waiter);
|
|
193
|
+
if (index < 0)
|
|
194
|
+
continue;
|
|
195
|
+
this.waiters.splice(index, 1);
|
|
196
|
+
waiter.reject(error);
|
|
197
|
+
}
|
|
198
|
+
throw error;
|
|
199
|
+
})
|
|
200
|
+
: Promise.resolve();
|
|
182
201
|
for (const waiter of waiting)
|
|
183
202
|
waiter.resume();
|
|
184
|
-
await Promise.
|
|
203
|
+
const results = await Promise.allSettled([scheduled, ...waiting.map((waiter) => waiter.chunkEnded)]);
|
|
204
|
+
const failure = results.find((result) => result.status === 'rejected');
|
|
205
|
+
if (failure?.status === 'rejected')
|
|
206
|
+
throw failure.reason;
|
|
207
|
+
}
|
|
208
|
+
async requestTurn(notBefore) {
|
|
209
|
+
if (this.closed)
|
|
210
|
+
throw this.closed;
|
|
211
|
+
await this.host.requestTurn?.(notBefore);
|
|
212
|
+
}
|
|
213
|
+
/** Reject parked work before the owner drains launch cleanup and cancels its alarm. */
|
|
214
|
+
close(reason = new Error('Launch scheduler is closed')) {
|
|
215
|
+
this.closed ??= reason;
|
|
216
|
+
for (const waiter of this.waiters.splice(0))
|
|
217
|
+
waiter.reject(this.closed);
|
|
185
218
|
}
|
|
186
219
|
/** Whether any launch is suspended waiting for a turn. */
|
|
187
220
|
get hasPending() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workerd-facet-host.d.ts","sourceRoot":"","sources":["../src/workerd-facet-host.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"workerd-facet-host.d.ts","sourceRoot":"","sources":["../src/workerd-facet-host.ts"],"names":[],"mappings":"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"}
|
|
@@ -356,7 +356,7 @@ async function runOneShot(ctx, env, supervisor, params, consume) {
|
|
|
356
356
|
throw new Error('Nimbus: env.LOADER binding missing or invalid. Running a program requires '
|
|
357
357
|
+ 'the Worker Loader binding; add it via worker_loaders in wrangler.jsonc.');
|
|
358
358
|
}
|
|
359
|
-
const supervisorRpc = supervisorEntrypoint();
|
|
359
|
+
const supervisorRpc = supervisorEntrypoint(undefined, supervisor.route?.supervisorEntrypoint);
|
|
360
360
|
let supervisorBinding;
|
|
361
361
|
let worker;
|
|
362
362
|
let entrypoint;
|
|
@@ -439,9 +439,9 @@ export async function residentWorkerConfig(env, disk, supervisor, boot) {
|
|
|
439
439
|
? await stagedBootAssembler()(env, boot.stage)
|
|
440
440
|
: await residentLoaderConfig(boot.code, disk());
|
|
441
441
|
assertModuleMapWithinCodeLimit(configModules(config));
|
|
442
|
-
const supervisorRpc = supervisorEntrypoint();
|
|
442
|
+
const supervisorRpc = supervisorEntrypoint(undefined, supervisor.route?.supervisorEntrypoint);
|
|
443
443
|
if (!supervisorRpc) {
|
|
444
|
-
throw new Error(`Nimbus: ctx.exports.${supervisorEntrypointName() ?? '<supervisor entrypoint>'} unavailable`);
|
|
444
|
+
throw new Error(`Nimbus: ctx.exports.${supervisor.route?.supervisorEntrypoint ?? supervisorEntrypointName() ?? '<supervisor entrypoint>'} unavailable`);
|
|
445
445
|
}
|
|
446
446
|
return { ...config, env: { SUPERVISOR: supervisorRpc({ props: supervisor }) } };
|
|
447
447
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimbus-sh/fabric",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The Cloudflare half of Nimbus
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "The Cloudflare half of Nimbus \u2014 Durable Object facet hosting, dynamic-worker loader pools, the resident-process fabric, and DO alarm/hibernation machinery.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
7
7
|
"workers",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"typecheck": "tsc --noEmit"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@nimbus-sh/core": "^0.
|
|
54
|
-
"@nimbus-sh/platform": "^0.
|
|
53
|
+
"@nimbus-sh/core": "^0.12.0",
|
|
54
|
+
"@nimbus-sh/platform": "^0.5.1",
|
|
55
55
|
"zod": "^4.4.3"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
package/src/bindings.ts
CHANGED
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
27
27
|
import { z } from 'zod/v4';
|
|
28
28
|
import { disposeRpcResource, useRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
29
|
-
import { hostNamespace, supervisorEntrypoint, supervisorEntrypointName } from './composition.js';
|
|
30
|
-
import {
|
|
29
|
+
import { hostNamespace, supervisorEntrypoint, supervisorEntrypointName, stagedBootAssembler } from './composition.js';
|
|
30
|
+
import type { HostRoute } from './composition.js';
|
|
31
31
|
import { hostNamespaceBinding, hostOpDispatch, type HostOpDispatch } from './host-dispatch.js';
|
|
32
32
|
import { assertModuleMapWithinCodeLimit } from './budgets.js';
|
|
33
33
|
import type { EntrypointLoopbackFactory } from './composition.js';
|
|
@@ -114,6 +114,8 @@ interface NimbusAssetsProps {
|
|
|
114
114
|
assetsDir?: string;
|
|
115
115
|
/** Supervisor DO id whose VFS holds the assets. */
|
|
116
116
|
doId?: string;
|
|
117
|
+
/** The way back to that DO, minted with the binding. */
|
|
118
|
+
route?: HostRoute;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
/**
|
|
@@ -164,9 +166,9 @@ export class NimbusAssetsRPC extends WorkerEntrypoint<object, NimbusAssetsProps>
|
|
|
164
166
|
let stub: DurableObjectStub | null = null;
|
|
165
167
|
let dispatch: HostOpDispatch;
|
|
166
168
|
try {
|
|
167
|
-
const ns = hostNamespaceBinding(this.env, 'NimbusAssetsRPC');
|
|
169
|
+
const ns = hostNamespaceBinding(this.env, 'NimbusAssetsRPC', props.route);
|
|
168
170
|
stub = ns.get(ns.idFromString(doId));
|
|
169
|
-
dispatch = hostOpDispatch(stub, 'NimbusAssetsRPC');
|
|
171
|
+
dispatch = hostOpDispatch(stub, 'NimbusAssetsRPC', props.route);
|
|
170
172
|
} catch (e) {
|
|
171
173
|
disposeRpcResource(stub);
|
|
172
174
|
return new Response(`ASSETS binding not wired: ${e instanceof Error ? e.message : String(e)}`, { status: 500 });
|
|
@@ -307,6 +309,12 @@ const _NIMBUS_LOADED_CODES: Map<string, WorkerCode> = new Map();
|
|
|
307
309
|
const _LOADED_CODES_MAX = 32;
|
|
308
310
|
let _loadedCodesEvictions = 0;
|
|
309
311
|
|
|
312
|
+
const HostRouteSchema = z.object({
|
|
313
|
+
supervisorEntrypoint: z.string().min(1),
|
|
314
|
+
hostNamespace: z.string().min(1),
|
|
315
|
+
hostDispatchMethod: z.string().min(1),
|
|
316
|
+
});
|
|
317
|
+
|
|
310
318
|
const NimbusLoadedEntrypointPropsSchema = z.object({
|
|
311
319
|
key: z.string().min(1),
|
|
312
320
|
name: z.string().nullable().optional(),
|
|
@@ -315,6 +323,7 @@ const NimbusLoadedEntrypointPropsSchema = z.object({
|
|
|
315
323
|
doId: z.string().min(1),
|
|
316
324
|
pid: z.number().int().nonnegative(),
|
|
317
325
|
writerId: z.string().uuid(),
|
|
326
|
+
route: HostRouteSchema.optional(),
|
|
318
327
|
}).optional(),
|
|
319
328
|
/**
|
|
320
329
|
* Staged-artifact spec, for a ONE-SHOT run. The module map — ~23 MB for
|
|
@@ -532,11 +541,12 @@ export class NimbusLoadedEntrypoint extends WorkerEntrypoint<NimbusLoaderShimEnv
|
|
|
532
541
|
|
|
533
542
|
async _supervisorBinding(props: NimbusLoadedEntrypointProps): Promise<unknown> {
|
|
534
543
|
if (!props.supervisor) return undefined;
|
|
535
|
-
|
|
544
|
+
// The route names the entrypoint too: this stateless hop may run in an
|
|
545
|
+
// isolate whose composition is not the host's.
|
|
546
|
+
const name = props.supervisor.route?.supervisorEntrypoint ?? supervisorEntrypointName();
|
|
547
|
+
const factory = supervisorEntrypoint(ctxExportsOf(this.ctx), name ?? undefined);
|
|
536
548
|
if (!factory) {
|
|
537
|
-
throw new Error(
|
|
538
|
-
`Nimbus: ctx.exports.${supervisorEntrypointName() ?? '<supervisor entrypoint>'} unavailable`,
|
|
539
|
-
);
|
|
549
|
+
throw new Error(`Nimbus: ctx.exports.${name ?? '<supervisor entrypoint>'} unavailable`);
|
|
540
550
|
}
|
|
541
551
|
return await factory({ props: props.supervisor });
|
|
542
552
|
}
|
|
@@ -691,6 +701,8 @@ export class NimbusLoadedEntrypoint extends WorkerEntrypoint<NimbusLoaderShimEnv
|
|
|
691
701
|
interface NimbusDoNamespaceProps {
|
|
692
702
|
bindingName?: string;
|
|
693
703
|
supervisorDoId?: string;
|
|
704
|
+
/** The way back to the supervisor DO, minted with the binding. */
|
|
705
|
+
route?: HostRoute;
|
|
694
706
|
}
|
|
695
707
|
|
|
696
708
|
/**
|
|
@@ -755,6 +767,7 @@ export class NimbusDurableObjectNamespace extends WorkerEntrypoint<unknown, Nimb
|
|
|
755
767
|
props: {
|
|
756
768
|
bindingName: props.bindingName,
|
|
757
769
|
supervisorDoId: props.supervisorDoId,
|
|
770
|
+
route: props.route,
|
|
758
771
|
id: String(id),
|
|
759
772
|
},
|
|
760
773
|
});
|
|
@@ -789,9 +802,9 @@ export class NimbusDOStub extends WorkerEntrypoint<object, NimbusDoStubProps> {
|
|
|
789
802
|
let stub: DurableObjectStub | null = null;
|
|
790
803
|
let dispatch: HostOpDispatch;
|
|
791
804
|
try {
|
|
792
|
-
const ns = hostNamespaceBinding(this.env ?? {}, 'NimbusDOStub');
|
|
805
|
+
const ns = hostNamespaceBinding(this.env ?? {}, 'NimbusDOStub', props.route);
|
|
793
806
|
stub = ns.get(ns.idFromString(supervisorDoId));
|
|
794
|
-
dispatch = hostOpDispatch(stub, 'NimbusDOStub');
|
|
807
|
+
dispatch = hostOpDispatch(stub, 'NimbusDOStub', props.route);
|
|
795
808
|
} catch (e) {
|
|
796
809
|
disposeRpcResource(stub);
|
|
797
810
|
return new Response(`Nimbus: ${e instanceof Error ? e.message : String(e)}`, { status: 500 });
|
package/src/fanout.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { serializeFunction } from './vendor/serialize.js';
|
|
18
18
|
import { BindingError } from './vendor/errors.js';
|
|
19
19
|
import { IsolatePool, type FacetTaskFn } from './isolate-pool.js';
|
|
20
|
+
import { hostRoute } from './composition.js';
|
|
20
21
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
21
22
|
import { describeError, isDoOverloaded, isTransientDoReset } from '@nimbus-sh/platform/oom-classify.js';
|
|
22
23
|
import type { WorkerLoader } from './vendor/types.js';
|
|
@@ -383,6 +384,7 @@ export class Fanout {
|
|
|
383
384
|
// ... write into the peer's own VFS — invisible to the
|
|
384
385
|
// user. See INSTALL-HONESTY-retro.md.
|
|
385
386
|
coordinatorDoId: this.coordDoId,
|
|
387
|
+
coordinatorRoute: hostRoute() ?? undefined,
|
|
386
388
|
// Credential source for peer-side writeBatchStream — the
|
|
387
389
|
// invoking process pid, so package writes are authorized
|
|
388
390
|
// as the user (not rejected as pid:0).
|
package/src/host-dispatch.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BindingError } from './vendor/errors.js';
|
|
2
|
-
import { hostDispatchMethod, hostNamespace } from './composition.js';
|
|
3
|
-
import type {
|
|
2
|
+
import { hostDispatchMethod, hostNamespace, type HostRoute } from './composition.js';
|
|
3
|
+
import type { SupervisorOpDispatch } from '@nimbus-sh/core/workspace/supervisor-op.js';
|
|
4
4
|
|
|
5
5
|
export type HostNamespaceBinding = Pick<DurableObjectNamespace, 'get' | 'idFromName' | 'idFromString'>;
|
|
6
|
-
export type HostOpDispatch =
|
|
6
|
+
export type HostOpDispatch = SupervisorOpDispatch;
|
|
7
7
|
|
|
8
8
|
function isNamespace(value: object): value is HostNamespaceBinding {
|
|
9
9
|
return typeof Reflect.get(value, 'idFromName') === 'function'
|
|
@@ -11,8 +11,19 @@ function isNamespace(value: object): value is HostNamespaceBinding {
|
|
|
11
11
|
&& typeof Reflect.get(value, 'get') === 'function';
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* The host's namespace binding. An entrypoint answering a facet passes the
|
|
16
|
+
* route the binding's props carry, minted in the host's isolate; the host
|
|
17
|
+
* itself, and a binding minted before routes travelled (a facet outlives
|
|
18
|
+
* the deploy that minted its binding), resolve from this isolate's
|
|
19
|
+
* composition.
|
|
20
|
+
*/
|
|
21
|
+
export function hostNamespaceBinding(
|
|
22
|
+
env: object | null | undefined,
|
|
23
|
+
usage: string,
|
|
24
|
+
route?: Pick<HostRoute, 'hostNamespace'>,
|
|
25
|
+
): HostNamespaceBinding {
|
|
26
|
+
const name = route?.hostNamespace ?? hostNamespace();
|
|
16
27
|
const binding = env ? Reflect.get(env, name) : undefined;
|
|
17
28
|
if (binding === null || (typeof binding !== 'object' && typeof binding !== 'function') || !isNamespace(binding)) {
|
|
18
29
|
throw new BindingError(`${usage}: env.${name} must be the Durable Object namespace configured by composeFabric`);
|
|
@@ -20,8 +31,12 @@ export function hostNamespaceBinding(env: object | null | undefined, usage: stri
|
|
|
20
31
|
return binding;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
|
-
export function hostOpDispatch(
|
|
24
|
-
|
|
34
|
+
export function hostOpDispatch(
|
|
35
|
+
stub: object,
|
|
36
|
+
usage: string,
|
|
37
|
+
route?: Pick<HostRoute, 'hostDispatchMethod'>,
|
|
38
|
+
): HostOpDispatch {
|
|
39
|
+
const name = route?.hostDispatchMethod ?? hostDispatchMethod();
|
|
25
40
|
if (stub === null || (typeof stub !== 'object' && typeof stub !== 'function')) {
|
|
26
41
|
throw new BindingError(`${usage}: the workspace namespace returned no stub`);
|
|
27
42
|
}
|
package/src/isolate-pool.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import { CF_COMPAT_DATE } from '@nimbus-sh/core/constants.js';
|
|
28
|
-
import { supervisorEntrypoint } from './composition.js';
|
|
28
|
+
import { hostRoute, supervisorEntrypoint, type HostRoute } from './composition.js';
|
|
29
29
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
30
30
|
import { serializeFunction, hashSource } from './vendor/serialize.js';
|
|
31
31
|
import { beginLoaderFetch, recordLoaderId, withDynamicWorkerCapNamed } from './budgets.js';
|
|
@@ -120,6 +120,12 @@ export interface IsolatePoolOptions {
|
|
|
120
120
|
* coordinator. Effective only when `omitSupervisor !== true`.
|
|
121
121
|
*/
|
|
122
122
|
supervisorDoIdOverride?: string;
|
|
123
|
+
/**
|
|
124
|
+
* The coordinator's route, forwarded with `supervisorDoIdOverride`: the
|
|
125
|
+
* binding is the coordinator's, so its way back is the coordinator's
|
|
126
|
+
* too, whatever this peer's isolate composed.
|
|
127
|
+
*/
|
|
128
|
+
supervisorRoute?: HostRoute;
|
|
123
129
|
/**
|
|
124
130
|
* Process pid baked into the auto-injected SUPERVISOR binding's props.
|
|
125
131
|
* The supervisor derives the write credential from this pid
|
|
@@ -524,7 +530,7 @@ export class IsolatePool {
|
|
|
524
530
|
const supDoId = opts?.supervisorDoIdOverride ?? ctx.id.toString();
|
|
525
531
|
const supPid = opts?.supervisorPid ?? 0;
|
|
526
532
|
bindings.SUPERVISOR = supervisorRpc({
|
|
527
|
-
props: { doId: supDoId, pid: supPid },
|
|
533
|
+
props: { doId: supDoId, pid: supPid, route: opts?.supervisorRoute ?? hostRoute() ?? undefined },
|
|
528
534
|
});
|
|
529
535
|
// Whatever the minted worker's env carries must be in its loader
|
|
530
536
|
// cache key — workerd's loader cache survives a DO hibernation
|
package/src/process-fabric.ts
CHANGED
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
* `ResidentDiskReader` it was given.
|
|
75
75
|
*/
|
|
76
76
|
|
|
77
|
+
import type { HostRoute } from './composition.js';
|
|
77
78
|
import { z } from 'zod/v4';
|
|
78
79
|
import type { RouteableFacetTarget } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
79
80
|
import type { ServiceStub } from './vendor/types.js';
|
|
@@ -316,6 +317,12 @@ export interface ResidentSupervisorProps {
|
|
|
316
317
|
doId: string;
|
|
317
318
|
pid: number;
|
|
318
319
|
writerId: string;
|
|
320
|
+
/**
|
|
321
|
+
* The way back to the coordinator, minted with the binding. Absent only
|
|
322
|
+
* when the coordinator's isolate composed nothing, in which case no
|
|
323
|
+
* supervisor binding is minted either.
|
|
324
|
+
*/
|
|
325
|
+
route?: HostRoute;
|
|
319
326
|
}
|
|
320
327
|
|
|
321
328
|
/** Everything a host needs to run one process. Substrate-free by construction. */
|
package/src/process-host.ts
CHANGED
|
@@ -85,6 +85,7 @@ import {
|
|
|
85
85
|
processes,
|
|
86
86
|
type ResidentFacetEnv,
|
|
87
87
|
} from './workerd-facet-host.js';
|
|
88
|
+
import { hostRoute, type HostRoute } from './composition.js';
|
|
88
89
|
|
|
89
90
|
/** The substrates this deployment can be configured for. */
|
|
90
91
|
export type ProcessHostMode = 'facet' | 'peer';
|
|
@@ -137,7 +138,7 @@ class FacetProcessHost implements ProcessHost {
|
|
|
137
138
|
|
|
138
139
|
runOnce<T>(params: OneShotParams, consume: (response: Response) => Promise<T>): Promise<T> {
|
|
139
140
|
return processes(this.ctx, this.env).run(
|
|
140
|
-
{ doId: this.coordDoId, pid: params.pid, writerId: params.writerId },
|
|
141
|
+
{ doId: this.coordDoId, pid: params.pid, writerId: params.writerId, route: hostRoute() ?? undefined },
|
|
141
142
|
params,
|
|
142
143
|
consume,
|
|
143
144
|
);
|
|
@@ -148,6 +149,7 @@ class FacetProcessHost implements ProcessHost {
|
|
|
148
149
|
doId: this.coordDoId,
|
|
149
150
|
pid: params.pid,
|
|
150
151
|
writerId: params.writerId,
|
|
152
|
+
route: hostRoute() ?? undefined,
|
|
151
153
|
};
|
|
152
154
|
const { name, ...facet } = processes(this.ctx, this.env).spawn(this.disk, supervisor, params);
|
|
153
155
|
return {
|
|
@@ -192,6 +194,8 @@ export function isolateToken(): string {
|
|
|
192
194
|
/** Options the coordinator hands a hosting peer. */
|
|
193
195
|
export interface HostProcessOpts {
|
|
194
196
|
coordinatorDoId: string;
|
|
197
|
+
/** The coordinator's route, minted into the process's SUPERVISOR binding. */
|
|
198
|
+
route?: HostRoute;
|
|
195
199
|
pid: number;
|
|
196
200
|
writerId: string;
|
|
197
201
|
workerKey: string;
|
|
@@ -354,7 +358,7 @@ class PeerProcessHost implements ProcessHost {
|
|
|
354
358
|
*/
|
|
355
359
|
runOnce<T>(params: OneShotParams, consume: (response: Response) => Promise<T>): Promise<T> {
|
|
356
360
|
return processes(this.ctx, this.env).run(
|
|
357
|
-
{ doId: this.coordDoId, pid: params.pid, writerId: params.writerId },
|
|
361
|
+
{ doId: this.coordDoId, pid: params.pid, writerId: params.writerId, route: hostRoute() ?? undefined },
|
|
358
362
|
params,
|
|
359
363
|
consume,
|
|
360
364
|
);
|
|
@@ -381,6 +385,7 @@ class PeerProcessHost implements ProcessHost {
|
|
|
381
385
|
// the peer dies under either.
|
|
382
386
|
const hostLeg = placement.stub._rpcHostProcess(params.boot, {
|
|
383
387
|
coordinatorDoId: this.coordDoId,
|
|
388
|
+
route: hostRoute() ?? undefined,
|
|
384
389
|
pid: params.pid,
|
|
385
390
|
writerId: params.writerId,
|
|
386
391
|
workerKey: params.workerKey,
|
package/src/turn-budget.ts
CHANGED
|
@@ -142,7 +142,7 @@ export interface PacedWorkHost {
|
|
|
142
142
|
* reason. Without it the pump degrades to a same-context timer — see
|
|
143
143
|
* {@link PacedWork.nextTurn}.
|
|
144
144
|
*/
|
|
145
|
-
requestTurn?: (notBefore?: number) => void
|
|
145
|
+
requestTurn?: (notBefore?: number) => void | Promise<void>;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
@@ -160,7 +160,8 @@ export class PacedWork implements TurnScheduler {
|
|
|
160
160
|
* half-built work for pids that no longer exist, where re-driving a launch
|
|
161
161
|
* from its inputs is the same idempotent work again.
|
|
162
162
|
*/
|
|
163
|
-
private waiters: Array<{ resume: () => void; chunkEnded: Promise<void>; notBefore: number }> = [];
|
|
163
|
+
private waiters: Array<{ resume: () => void; reject: (error: unknown) => void; chunkEnded: Promise<void>; notBefore: number }> = [];
|
|
164
|
+
private closed: Error | undefined;
|
|
164
165
|
|
|
165
166
|
/**
|
|
166
167
|
* `ctx` keys the cold-start queue the pump drains first on every turn it
|
|
@@ -182,10 +183,17 @@ export class PacedWork implements TurnScheduler {
|
|
|
182
183
|
* responsiveness but keeps the behaviour.
|
|
183
184
|
*/
|
|
184
185
|
nextTurn(chunkEnded: Promise<void>, notBefore = 0): Promise<void> {
|
|
185
|
-
return
|
|
186
|
-
|
|
186
|
+
if (this.closed) return Promise.reject(this.closed);
|
|
187
|
+
return new Promise<void>((resume, reject) => {
|
|
188
|
+
const waiter = { resume, reject, chunkEnded, notBefore };
|
|
189
|
+
this.waiters.push(waiter);
|
|
187
190
|
if (this.host.requestTurn) {
|
|
188
|
-
this.
|
|
191
|
+
void this.requestTurn(notBefore).catch((error: unknown) => {
|
|
192
|
+
const index = this.waiters.indexOf(waiter);
|
|
193
|
+
if (index < 0) return;
|
|
194
|
+
this.waiters.splice(index, 1);
|
|
195
|
+
waiter.reject(error);
|
|
196
|
+
});
|
|
189
197
|
return;
|
|
190
198
|
}
|
|
191
199
|
setTimeout(() => { void this.pump(); }, Math.max(0, notBefore - Date.now()));
|
|
@@ -201,18 +209,39 @@ export class PacedWork implements TurnScheduler {
|
|
|
201
209
|
* the runtime may tear the context down mid-chunk.
|
|
202
210
|
*/
|
|
203
211
|
async pump(): Promise<void> {
|
|
204
|
-
|
|
205
|
-
// the resident-launch journal's recovery sits (`onColdStart`): the pump
|
|
206
|
-
// is what an alarm calls, and the first turn after a reset is the
|
|
207
|
-
// re-delivered alarm of a launch the reset interrupted.
|
|
212
|
+
if (this.closed) return;
|
|
208
213
|
await runColdStart(this.ctx);
|
|
214
|
+
if (this.closed) return;
|
|
209
215
|
const now = Date.now();
|
|
210
216
|
const waiting = this.waiters.filter((waiter) => waiter.notBefore <= now);
|
|
211
217
|
this.waiters = this.waiters.filter((waiter) => waiter.notBefore > now);
|
|
212
|
-
|
|
213
|
-
|
|
218
|
+
const future = [...this.waiters];
|
|
219
|
+
const scheduled = future.length > 0
|
|
220
|
+
? this.requestTurn(Math.min(...future.map((waiter) => waiter.notBefore))).catch((error: unknown) => {
|
|
221
|
+
for (const waiter of future) {
|
|
222
|
+
const index = this.waiters.indexOf(waiter);
|
|
223
|
+
if (index < 0) continue;
|
|
224
|
+
this.waiters.splice(index, 1);
|
|
225
|
+
waiter.reject(error);
|
|
226
|
+
}
|
|
227
|
+
throw error;
|
|
228
|
+
})
|
|
229
|
+
: Promise.resolve();
|
|
214
230
|
for (const waiter of waiting) waiter.resume();
|
|
215
|
-
await Promise.
|
|
231
|
+
const results = await Promise.allSettled([scheduled, ...waiting.map((waiter) => waiter.chunkEnded)]);
|
|
232
|
+
const failure = results.find((result) => result.status === 'rejected');
|
|
233
|
+
if (failure?.status === 'rejected') throw failure.reason;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private async requestTurn(notBefore: number): Promise<void> {
|
|
237
|
+
if (this.closed) throw this.closed;
|
|
238
|
+
await this.host.requestTurn?.(notBefore);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Reject parked work before the owner drains launch cleanup and cancels its alarm. */
|
|
242
|
+
close(reason = new Error('Launch scheduler is closed')): void {
|
|
243
|
+
this.closed ??= reason;
|
|
244
|
+
for (const waiter of this.waiters.splice(0)) waiter.reject(this.closed);
|
|
216
245
|
}
|
|
217
246
|
|
|
218
247
|
/** Whether any launch is suspended waiting for a turn. */
|
|
@@ -541,7 +541,7 @@ async function runOneShot<T>(
|
|
|
541
541
|
+ 'the Worker Loader binding; add it via worker_loaders in wrangler.jsonc.',
|
|
542
542
|
);
|
|
543
543
|
}
|
|
544
|
-
const supervisorRpc = supervisorEntrypoint();
|
|
544
|
+
const supervisorRpc = supervisorEntrypoint(undefined, supervisor.route?.supervisorEntrypoint);
|
|
545
545
|
let supervisorBinding: unknown;
|
|
546
546
|
let worker: LoadedWorkerStub | undefined;
|
|
547
547
|
let entrypoint: LoadedWorkerEntrypointStub | undefined;
|
|
@@ -626,11 +626,9 @@ export async function residentWorkerConfig(
|
|
|
626
626
|
? await stagedBootAssembler()(env, boot.stage)
|
|
627
627
|
: await residentLoaderConfig(boot.code, disk());
|
|
628
628
|
assertModuleMapWithinCodeLimit(configModules(config));
|
|
629
|
-
const supervisorRpc = supervisorEntrypoint();
|
|
629
|
+
const supervisorRpc = supervisorEntrypoint(undefined, supervisor.route?.supervisorEntrypoint);
|
|
630
630
|
if (!supervisorRpc) {
|
|
631
|
-
throw new Error(
|
|
632
|
-
`Nimbus: ctx.exports.${supervisorEntrypointName() ?? '<supervisor entrypoint>'} unavailable`,
|
|
633
|
-
);
|
|
631
|
+
throw new Error(`Nimbus: ctx.exports.${supervisor.route?.supervisorEntrypoint ?? supervisorEntrypointName() ?? '<supervisor entrypoint>'} unavailable`);
|
|
634
632
|
}
|
|
635
633
|
return { ...config, env: { SUPERVISOR: supervisorRpc({ props: supervisor }) } };
|
|
636
634
|
}
|