@nimbus-sh/fabric 0.7.1 → 0.8.0
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/dist/bindings.d.ts +1 -0
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js +2 -0
- package/dist/connections.d.ts +1 -1
- package/dist/connections.js +1 -1
- package/dist/do-calls.d.ts +71 -9
- package/dist/do-calls.d.ts.map +1 -1
- package/dist/do-calls.js +148 -22
- package/dist/facet-pool.d.ts +3 -0
- package/dist/facet-pool.d.ts.map +1 -1
- package/dist/facet-pool.js +3 -0
- package/dist/fanout.d.ts.map +1 -1
- package/dist/fanout.js +4 -3
- package/dist/fenced-work.d.ts +3 -3
- package/dist/image-store.js +2 -2
- package/dist/inner-do-registry.d.ts +9 -0
- package/dist/inner-do-registry.d.ts.map +1 -1
- package/dist/inner-do-registry.js +35 -0
- package/dist/isolate-pool.d.ts +1 -1
- package/dist/isolate-pool.d.ts.map +1 -1
- package/dist/isolate-pool.js +10 -8
- package/dist/process-fabric.d.ts +16 -12
- package/dist/process-fabric.d.ts.map +1 -1
- package/dist/process-fabric.js +18 -6
- package/dist/process-host.d.ts +3 -1
- package/dist/process-host.d.ts.map +1 -1
- package/dist/process-host.js +13 -14
- package/dist/supervisor-props.d.ts +47 -0
- package/dist/supervisor-props.d.ts.map +1 -0
- package/dist/supervisor-props.js +37 -0
- package/dist/workerd-facet-host.d.ts +4 -17
- package/dist/workerd-facet-host.d.ts.map +1 -1
- package/dist/workerd-facet-host.js +95 -29
- package/package.json +5 -5
- package/src/bindings.ts +2 -0
- package/src/connections.ts +1 -1
- package/src/do-calls.ts +182 -25
- package/src/facet-pool.ts +5 -0
- package/src/fanout.ts +4 -3
- package/src/fenced-work.ts +3 -3
- package/src/image-store.ts +2 -2
- package/src/inner-do-registry.ts +31 -0
- package/src/isolate-pool.ts +10 -8
- package/src/process-fabric.ts +33 -17
- package/src/process-host.ts +16 -14
- package/src/supervisor-props.ts +56 -0
- package/src/workerd-facet-host.ts +96 -32
package/dist/isolate-pool.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* 3. **Supervisor autoinjection**. The pool grabs the embedder's
|
|
16
16
|
* registered supervisor entrypoint stub (see `supervisorEntrypoint` in
|
|
17
17
|
* composition.ts) and forwards it as `env.SUPERVISOR` to every facet,
|
|
18
|
-
* same pattern as git
|
|
18
|
+
* same pattern as git/network-facet.ts. Callers can add more bindings
|
|
19
19
|
* via `extraBindings`.
|
|
20
20
|
* 4. **Fail-loud defaults**: timeout 60s, retries 0, onError 'throw'.
|
|
21
21
|
* Caller opts in to leniency.
|
|
@@ -24,7 +24,8 @@
|
|
|
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 {
|
|
27
|
+
import { supervisorEntrypoint } from './composition.js';
|
|
28
|
+
import { supervisorBindingProps, supervisorLoaderKey } from './supervisor-props.js';
|
|
28
29
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
29
30
|
import { serializeFunction, hashSource } from './vendor/serialize.js';
|
|
30
31
|
import { beginLoaderFetch, recordLoaderId, withDynamicWorkerCapNamed } from './budgets.js';
|
|
@@ -240,11 +241,11 @@ export class IsolatePool {
|
|
|
240
241
|
// via supervisorDoIdOverride so SUPERVISOR.* RPCs route back
|
|
241
242
|
// to the user's session DO, not the peer DO. Default to the
|
|
242
243
|
// local ctx.id (single-DO callers and the in-DO in-DO fanout path).
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
props: { doId: supDoId, pid: supPid, route: opts?.supervisorRoute ?? hostRoute() ?? undefined },
|
|
244
|
+
const supervisor = supervisorBindingProps(ctx, opts?.supervisorPid ?? 0, {
|
|
245
|
+
doId: opts?.supervisorDoIdOverride,
|
|
246
|
+
route: opts?.supervisorRoute,
|
|
247
247
|
});
|
|
248
|
+
bindings.SUPERVISOR = supervisorRpc({ props: supervisor });
|
|
248
249
|
// Whatever the minted worker's env carries must be in its loader
|
|
249
250
|
// cache key — workerd's loader cache survives a DO hibernation
|
|
250
251
|
// wake while generation-strided pids (1000001 → 2000001) do not:
|
|
@@ -252,8 +253,9 @@ export class IsolatePool {
|
|
|
252
253
|
// the new generation still credentialed to the dead pid, and
|
|
253
254
|
// every pid-authorized RPC from it fails "process pid … does
|
|
254
255
|
// not exist". doIdShort alone cannot cover this — it changes
|
|
255
|
-
// across sessions, not across wakes of the same session.
|
|
256
|
-
|
|
256
|
+
// across sessions, not across wakes of the same session. So does
|
|
257
|
+
// the instance a binding delivers mutations to, when it names one.
|
|
258
|
+
this.supervisorKey = supervisorLoaderKey(`s${supervisor.doId.slice(0, 12)}-${supervisor.pid}`, supervisor);
|
|
257
259
|
}
|
|
258
260
|
else {
|
|
259
261
|
// Supervisor entrypoint unavailable — running without ctx.exports
|
package/dist/process-fabric.d.ts
CHANGED
|
@@ -73,7 +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 {
|
|
76
|
+
import type { SupervisorBindingProps } from './supervisor-props.js';
|
|
77
77
|
import { z } from 'zod/v4';
|
|
78
78
|
import type { RouteableFacetTarget } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
79
79
|
import type { ServiceStub } from './vendor/types.js';
|
|
@@ -178,7 +178,7 @@ export declare const FACET_IMAGE_DIR = "var/lib/nimbus/facet-images";
|
|
|
178
178
|
* generated text into `startArgs` would make every image per-PROGRAM and
|
|
179
179
|
* shareable across spawns and sessions; the sweep bounds the store either way.
|
|
180
180
|
*/
|
|
181
|
-
export declare function facetImageDigest(
|
|
181
|
+
export declare function facetImageDigest(image: string | Uint8Array): Promise<string>;
|
|
182
182
|
export declare function facetImagePath(digest: string): string;
|
|
183
183
|
/**
|
|
184
184
|
* The digest an image path claims, for the reader's verify-on-read. Content
|
|
@@ -217,18 +217,13 @@ export declare function residentLoaderConfig(spec: ResidentCodeSpec, disk: Resid
|
|
|
217
217
|
/**
|
|
218
218
|
* The identity a resident process's SUPERVISOR binding is minted for. Always
|
|
219
219
|
* the COORDINATOR's — a process hosted somewhere else still reads and writes
|
|
220
|
-
* the user's disk, and still reports to the user's process table.
|
|
220
|
+
* the user's disk, and still reports to the user's process table. Minted by
|
|
221
|
+
* `supervisorBindingProps` on the coordinator; `route` is absent only when
|
|
222
|
+
* the coordinator's isolate composed nothing, in which case no supervisor
|
|
223
|
+
* binding is minted either.
|
|
221
224
|
*/
|
|
222
|
-
export interface ResidentSupervisorProps {
|
|
223
|
-
doId: string;
|
|
224
|
-
pid: number;
|
|
225
|
+
export interface ResidentSupervisorProps extends SupervisorBindingProps {
|
|
225
226
|
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;
|
|
232
227
|
}
|
|
233
228
|
/** Everything a host needs to run one process. Substrate-free by construction. */
|
|
234
229
|
export interface ProcessHostParams {
|
|
@@ -253,6 +248,13 @@ export interface ProcessHostParams {
|
|
|
253
248
|
name: string;
|
|
254
249
|
durable: boolean;
|
|
255
250
|
};
|
|
251
|
+
/**
|
|
252
|
+
* Bytes the process's store is filled with before it runs (its data plan).
|
|
253
|
+
* The hosting actor's storage ledger (N18) admits them under the facet's
|
|
254
|
+
* name before the facet starts: ENOSPC, and no facet, when they would cross
|
|
255
|
+
* the storage limit.
|
|
256
|
+
*/
|
|
257
|
+
storageBytes?: number;
|
|
256
258
|
}
|
|
257
259
|
/**
|
|
258
260
|
* One resident process, as its coordinator sees it. Identical in meaning on
|
|
@@ -524,6 +526,8 @@ export interface ResidentProcessSpawn {
|
|
|
524
526
|
name: string;
|
|
525
527
|
durable: boolean;
|
|
526
528
|
};
|
|
529
|
+
/** See {@link ProcessHostParams.storageBytes}. */
|
|
530
|
+
storageBytes?: number;
|
|
527
531
|
/**
|
|
528
532
|
* Called before any concrete host capability can expose this writer.
|
|
529
533
|
* A spawn must not proceed unless the supervisor accepts the authority.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-fabric.d.ts","sourceRoot":"","sources":["../src/process-fabric.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"process-fabric.d.ts","sourceRoot":"","sources":["../src/process-fabric.ts"],"names":[],"mappings":"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"}
|
package/dist/process-fabric.js
CHANGED
|
@@ -179,8 +179,10 @@ export const FACET_IMAGE_DIR = 'var/lib/nimbus/facet-images';
|
|
|
179
179
|
* generated text into `startArgs` would make every image per-PROGRAM and
|
|
180
180
|
* shareable across spawns and sessions; the sweep bounds the store either way.
|
|
181
181
|
*/
|
|
182
|
-
export async function facetImageDigest(
|
|
183
|
-
|
|
182
|
+
export async function facetImageDigest(image) {
|
|
183
|
+
// An image is its UTF-8 bytes; a caller holding them is not made to encode a second copy.
|
|
184
|
+
const bytes = typeof image === 'string' ? new TextEncoder().encode(image) : image;
|
|
185
|
+
const digest = await crypto.subtle.digest('SHA-256', bytes);
|
|
184
186
|
return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, '0')).join('');
|
|
185
187
|
}
|
|
186
188
|
export function facetImagePath(digest) {
|
|
@@ -212,8 +214,16 @@ export async function residentLoaderConfig(spec, disk) {
|
|
|
212
214
|
const resolved = {};
|
|
213
215
|
for (const [moduleName, path] of Object.entries(spec.vfsWasmModules ?? {})) {
|
|
214
216
|
const bytes = await disk.readFile(path);
|
|
217
|
+
// The read's own buffer when it fits exactly, and only otherwise a copy.
|
|
218
|
+
// These are the largest members a spec carries — ruby's interpreter image
|
|
219
|
+
// is 34.3 MiB, esbuild's 13.3 — and an unconditional slice held both
|
|
220
|
+
// copies at once in the coordinator's 128 MiB isolate, at the one moment
|
|
221
|
+
// the module map is also resident.
|
|
222
|
+
const exact = bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength;
|
|
215
223
|
resolved[moduleName] = {
|
|
216
|
-
wasm:
|
|
224
|
+
wasm: exact
|
|
225
|
+
? bytes.buffer
|
|
226
|
+
: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength),
|
|
217
227
|
};
|
|
218
228
|
}
|
|
219
229
|
for (const [moduleName, path] of Object.entries(spec.vfsTextModules ?? {})) {
|
|
@@ -240,13 +250,14 @@ async function readFacetImage(disk, path) {
|
|
|
240
250
|
if (!expected) {
|
|
241
251
|
throw new Error(`Nimbus: '${path}' is not a content-addressed facet image path`);
|
|
242
252
|
}
|
|
243
|
-
|
|
244
|
-
const
|
|
253
|
+
// Verified from the bytes read, and decoded only after: re-encoding the decoded string held a third copy of the largest member.
|
|
254
|
+
const bytes = await disk.readFile(path);
|
|
255
|
+
const actual = await facetImageDigest(bytes);
|
|
245
256
|
if (actual !== expected) {
|
|
246
257
|
throw new Error(`Nimbus: facet image '${path}' does not match its digest (read ${actual}); `
|
|
247
258
|
+ 'the image store is corrupt and the process cannot boot from it');
|
|
248
259
|
}
|
|
249
|
-
return
|
|
260
|
+
return new TextDecoder().decode(bytes);
|
|
250
261
|
}
|
|
251
262
|
// ── Handle ──────────────────────────────────────────────────────────────────
|
|
252
263
|
/**
|
|
@@ -350,6 +361,7 @@ export class ProcessFabric {
|
|
|
350
361
|
writerId,
|
|
351
362
|
startArgs: spawn.startArgs,
|
|
352
363
|
...(spawn.facet !== undefined ? { facet: spawn.facet } : {}),
|
|
364
|
+
...(spawn.storageBytes !== undefined ? { storageBytes: spawn.storageBytes } : {}),
|
|
353
365
|
});
|
|
354
366
|
}
|
|
355
367
|
catch (error) {
|
package/dist/process-host.d.ts
CHANGED
|
@@ -64,7 +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 {
|
|
67
|
+
import type { HostRoute } from './composition.js';
|
|
68
68
|
/** The substrates this deployment can be configured for. */
|
|
69
69
|
export type ProcessHostMode = 'facet' | 'peer';
|
|
70
70
|
/**
|
|
@@ -84,6 +84,8 @@ export interface HostProcessOpts {
|
|
|
84
84
|
route?: HostRoute;
|
|
85
85
|
pid: number;
|
|
86
86
|
writerId: string;
|
|
87
|
+
/** The coordinator instance's delivery incarnation, minted into the SUPERVISOR binding (ResidentSupervisorProps). */
|
|
88
|
+
hostIncarnation?: string;
|
|
87
89
|
workerKey: string;
|
|
88
90
|
/** Unforgeable capability for the fetch-semantic WebSocket hop. */
|
|
89
91
|
webSocketCapability: 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;AAO7B,OAAO,
|
|
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,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,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;AA0ED,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,qHAAqH;IACrH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,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;AAqUzF;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAWhE"}
|
package/dist/process-host.js
CHANGED
|
@@ -64,14 +64,14 @@
|
|
|
64
64
|
* that pair unforgeable by anything that did not open the process.
|
|
65
65
|
*/
|
|
66
66
|
import { disposeRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
|
|
67
|
-
import {
|
|
67
|
+
import { classifyDoCall, isRetryableDoCall } from '@nimbus-sh/platform/oom-classify.js';
|
|
68
68
|
import { PEER_RETRY_BACKOFF_MS, PEER_TRANSIENT_RESET_RETRIES } from './fanout.js';
|
|
69
69
|
import { hostNamespaceBinding, hostOpDispatch } from './host-dispatch.js';
|
|
70
70
|
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 {
|
|
74
|
+
import { supervisorBindingProps } from './supervisor-props.js';
|
|
75
75
|
/**
|
|
76
76
|
* The substrate for this deployment, resolved once. The mode arrives already
|
|
77
77
|
* decided — the embedder owns the config var that picks it, and refuses an
|
|
@@ -109,15 +109,10 @@ class FacetProcessHost {
|
|
|
109
109
|
this.coordDoId = ctx.id.toString();
|
|
110
110
|
}
|
|
111
111
|
runOnce(params, consume) {
|
|
112
|
-
return processes(this.ctx, this.env).run({
|
|
112
|
+
return processes(this.ctx, this.env).run({ ...supervisorBindingProps(this.ctx, params.pid), writerId: params.writerId }, params, consume);
|
|
113
113
|
}
|
|
114
114
|
async open(params) {
|
|
115
|
-
const supervisor = {
|
|
116
|
-
doId: this.coordDoId,
|
|
117
|
-
pid: params.pid,
|
|
118
|
-
writerId: params.writerId,
|
|
119
|
-
route: hostRoute() ?? undefined,
|
|
120
|
-
};
|
|
115
|
+
const supervisor = { ...supervisorBindingProps(this.ctx, params.pid), writerId: params.writerId };
|
|
121
116
|
const { name, ...facet } = processes(this.ctx, this.env).spawn(this.disk, supervisor, params);
|
|
122
117
|
return {
|
|
123
118
|
...facet,
|
|
@@ -261,7 +256,7 @@ class PeerProcessHost {
|
|
|
261
256
|
* worker of the coordinator here exactly as it does on `facet`.
|
|
262
257
|
*/
|
|
263
258
|
runOnce(params, consume) {
|
|
264
|
-
return processes(this.ctx, this.env).run({
|
|
259
|
+
return processes(this.ctx, this.env).run({ ...supervisorBindingProps(this.ctx, params.pid), writerId: params.writerId }, params, consume);
|
|
265
260
|
}
|
|
266
261
|
async open(params) {
|
|
267
262
|
if (params.facet) {
|
|
@@ -280,11 +275,15 @@ class PeerProcessHost {
|
|
|
280
275
|
// also what keeps the hosting DO resident. It settles when a `lifetime`
|
|
281
276
|
// runner exits or when a `boot` runner's host is cancelled, and rejects if
|
|
282
277
|
// the peer dies under either.
|
|
278
|
+
// The peer mints the process's binding from these, for THIS object: the
|
|
279
|
+
// coordinator's doId, route and delivery instance.
|
|
280
|
+
const supervisor = supervisorBindingProps(this.ctx, params.pid);
|
|
283
281
|
const hostLeg = placement.stub._rpcHostProcess(params.boot, {
|
|
284
|
-
coordinatorDoId:
|
|
285
|
-
route:
|
|
286
|
-
pid:
|
|
282
|
+
coordinatorDoId: supervisor.doId,
|
|
283
|
+
route: supervisor.route,
|
|
284
|
+
pid: supervisor.pid,
|
|
287
285
|
writerId: params.writerId,
|
|
286
|
+
hostIncarnation: supervisor.hostIncarnation,
|
|
288
287
|
workerKey: params.workerKey,
|
|
289
288
|
webSocketCapability,
|
|
290
289
|
startArgs: params.startArgs,
|
|
@@ -396,7 +395,7 @@ class PeerProcessHost {
|
|
|
396
395
|
return probe;
|
|
397
396
|
}
|
|
398
397
|
catch (err) {
|
|
399
|
-
if (attempt < PEER_TRANSIENT_RESET_RETRIES &&
|
|
398
|
+
if (attempt < PEER_TRANSIENT_RESET_RETRIES && isRetryableDoCall(classifyDoCall(err))) {
|
|
400
399
|
await new Promise((r) => setTimeout(r, PEER_RETRY_BACKOFF_MS[Math.min(attempt, PEER_RETRY_BACKOFF_MS.length - 1)]));
|
|
401
400
|
continue;
|
|
402
401
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supervisor-props.ts — what every SUPERVISOR binding a Durable Object mints
|
|
3
|
+
* for a process carries, and the one rule for naming the instance in it.
|
|
4
|
+
*
|
|
5
|
+
* A binding names its host INSTANCE (`hostIncarnation`) exactly when a
|
|
6
|
+
* mutation sent through it can be delivered once
|
|
7
|
+
* (@nimbus-sh/core/workspace/supervisor-delivery.js): the host opened a
|
|
8
|
+
* delivery store, the binding acts as a real process (SupervisorRPC refuses
|
|
9
|
+
* every filesystem mutation of pid 0), and it routes back to this very
|
|
10
|
+
* object rather than another (a fanout pool writes to its coordinator).
|
|
11
|
+
* Minting every binding here is what keeps a new mint site from forgetting
|
|
12
|
+
* that, which would fail silently: its mutations would simply never be
|
|
13
|
+
* re-sent.
|
|
14
|
+
*/
|
|
15
|
+
import { type HostRoute } from './composition.js';
|
|
16
|
+
/** The props every SUPERVISOR binding for a process carries. */
|
|
17
|
+
export interface SupervisorBindingProps {
|
|
18
|
+
/** The Durable Object the binding's calls reach. */
|
|
19
|
+
doId: string;
|
|
20
|
+
/** The process the calls act as; 0 is none, and can mutate nothing. */
|
|
21
|
+
pid: number;
|
|
22
|
+
/** The way back, minted with the binding in the host's isolate. */
|
|
23
|
+
route?: HostRoute;
|
|
24
|
+
/** The host instance that applies this binding's mutations once, when there is one. */
|
|
25
|
+
hostIncarnation?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The props of a SUPERVISOR binding minted in the Durable Object whose state
|
|
29
|
+
* is `ctx`, for process `pid`, reaching `options.doId` (this object by
|
|
30
|
+
* default) by `options.route` (this isolate's composition by default).
|
|
31
|
+
*/
|
|
32
|
+
export declare function supervisorBindingProps(ctx: {
|
|
33
|
+
readonly id: {
|
|
34
|
+
toString(): string;
|
|
35
|
+
};
|
|
36
|
+
}, pid: number, options?: {
|
|
37
|
+
doId?: string;
|
|
38
|
+
route?: HostRoute;
|
|
39
|
+
}): SupervisorBindingProps;
|
|
40
|
+
/**
|
|
41
|
+
* `key`, for a loader cache entry whose worker holds a binding with `props`:
|
|
42
|
+
* made specific to the host instance the binding names, since the loader
|
|
43
|
+
* outlives that instance and the next one refuses every mutation the binding
|
|
44
|
+
* would deliver. A binding that names none keeps `key`, and its warm worker.
|
|
45
|
+
*/
|
|
46
|
+
export declare function supervisorLoaderKey(key: string, props: Pick<SupervisorBindingProps, 'hostIncarnation'>): string;
|
|
47
|
+
//# sourceMappingURL=supervisor-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor-props.d.ts","sourceRoot":"","sources":["../src/supervisor-props.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7D,gEAAgE;AAChE,MAAM,WAAW,sBAAsB;IACrC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uFAAuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,EAAE;QAAE,QAAQ,IAAI,MAAM,CAAA;KAAE,CAAA;CAAE,EAC5C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAO,GACjD,sBAAsB,CAMxB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,GAAG,MAAM,CAE/G"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supervisor-props.ts — what every SUPERVISOR binding a Durable Object mints
|
|
3
|
+
* for a process carries, and the one rule for naming the instance in it.
|
|
4
|
+
*
|
|
5
|
+
* A binding names its host INSTANCE (`hostIncarnation`) exactly when a
|
|
6
|
+
* mutation sent through it can be delivered once
|
|
7
|
+
* (@nimbus-sh/core/workspace/supervisor-delivery.js): the host opened a
|
|
8
|
+
* delivery store, the binding acts as a real process (SupervisorRPC refuses
|
|
9
|
+
* every filesystem mutation of pid 0), and it routes back to this very
|
|
10
|
+
* object rather than another (a fanout pool writes to its coordinator).
|
|
11
|
+
* Minting every binding here is what keeps a new mint site from forgetting
|
|
12
|
+
* that, which would fail silently: its mutations would simply never be
|
|
13
|
+
* re-sent.
|
|
14
|
+
*/
|
|
15
|
+
import { supervisorDeliveryProps } from '@nimbus-sh/core/workspace/supervisor-delivery.js';
|
|
16
|
+
import { hostRoute } from './composition.js';
|
|
17
|
+
/**
|
|
18
|
+
* The props of a SUPERVISOR binding minted in the Durable Object whose state
|
|
19
|
+
* is `ctx`, for process `pid`, reaching `options.doId` (this object by
|
|
20
|
+
* default) by `options.route` (this isolate's composition by default).
|
|
21
|
+
*/
|
|
22
|
+
export function supervisorBindingProps(ctx, pid, options = {}) {
|
|
23
|
+
const own = ctx.id.toString();
|
|
24
|
+
const doId = options.doId ?? own;
|
|
25
|
+
const route = options.route ?? hostRoute() ?? undefined;
|
|
26
|
+
const delivery = pid > 0 && doId === own ? supervisorDeliveryProps(ctx) : {};
|
|
27
|
+
return { doId, pid, route, ...delivery };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* `key`, for a loader cache entry whose worker holds a binding with `props`:
|
|
31
|
+
* made specific to the host instance the binding names, since the loader
|
|
32
|
+
* outlives that instance and the next one refuses every mutation the binding
|
|
33
|
+
* would deliver. A binding that names none keeps `key`, and its warm worker.
|
|
34
|
+
*/
|
|
35
|
+
export function supervisorLoaderKey(key, props) {
|
|
36
|
+
return props.hostIncarnation === undefined ? key : `${key}:${props.hostIncarnation}`;
|
|
37
|
+
}
|
|
@@ -24,11 +24,7 @@ export interface NimbusCtxExports {
|
|
|
24
24
|
key: string;
|
|
25
25
|
name: string | null;
|
|
26
26
|
depth: number;
|
|
27
|
-
supervisor:
|
|
28
|
-
doId: string;
|
|
29
|
-
pid: number;
|
|
30
|
-
writerId: string;
|
|
31
|
-
};
|
|
27
|
+
supervisor: ResidentSupervisorProps;
|
|
32
28
|
stage?: unknown;
|
|
33
29
|
};
|
|
34
30
|
}) => LoadedWorkerEntrypointStub;
|
|
@@ -40,11 +36,7 @@ export declare function getNimbusCtxExports(): NimbusCtxExports;
|
|
|
40
36
|
* request rather than leaving it resident: their module map is assembled in
|
|
41
37
|
* that stateless entrypoint's own isolate, never in a session DO.
|
|
42
38
|
*/
|
|
43
|
-
export declare function createLoadedWorkerEntrypoint(ctxExports: NimbusCtxExports, supervisor:
|
|
44
|
-
doId: string;
|
|
45
|
-
pid: number;
|
|
46
|
-
writerId: string;
|
|
47
|
-
}, stage: unknown, name?: string | null): Promise<LoadedWorkerEntrypointStub>;
|
|
39
|
+
export declare function createLoadedWorkerEntrypoint(ctxExports: NimbusCtxExports, supervisor: ResidentSupervisorProps, stage: unknown, name?: string | null): Promise<LoadedWorkerEntrypointStub>;
|
|
48
40
|
/** What an unkeyed `LOADER.load` hands back. */
|
|
49
41
|
interface LoadedWorkerStub {
|
|
50
42
|
getEntrypoint(): LoadedWorkerEntrypointStub;
|
|
@@ -133,13 +125,8 @@ export declare function cloneStorage(ctx: DurableObjectState, clone: {
|
|
|
133
125
|
export declare function residentFacetName(slot: number): string;
|
|
134
126
|
/** The prefix every durable application's facet name carries. */
|
|
135
127
|
export declare const DURABLE_FACET_NAME_PREFIX = "app-slot-";
|
|
136
|
-
/**
|
|
137
|
-
|
|
138
|
-
* storage. `spawnResident` releases ephemeral processes with abort+delete
|
|
139
|
-
* (storage is slot-reuse hygiene) and durable ones with abort alone (the
|
|
140
|
-
* storage IS the durable application's state); explicit removal arrives here
|
|
141
|
-
* through the coordinator's durable-slot book, owner-checked.
|
|
142
|
-
*/
|
|
128
|
+
/** The facet a running resident process `pid` lives in on this actor, for its storage ledger row. */
|
|
129
|
+
export declare function residentFacetOf(ctx: DurableObjectState, pid: number): string | undefined;
|
|
143
130
|
export declare function deleteFacetStorage(ctx: DurableObjectState, name: string): void;
|
|
144
131
|
/**
|
|
145
132
|
* What `processes(ctx, env).spawn` hands back: a running process, minus its placement.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workerd-facet-host.d.ts","sourceRoot":"","sources":["../src/workerd-facet-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"workerd-facet-host.d.ts","sourceRoot":"","sources":["../src/workerd-facet-host.ts"],"names":[],"mappings":"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"}
|