@nimbus-sh/fabric 0.9.0 → 0.10.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/README.md CHANGED
@@ -67,6 +67,15 @@ Worker that imports Nimbus's own entry (`@nimbus-sh/sdk/worker`) inherits
67
67
  that entry's composition, so a host that names its own namespace composes in
68
68
  a Worker that does not import it.
69
69
 
70
+ A program's filesystem calls reach the supervisor entrypoint through its
71
+ `answer(method, args)`, which resolves `{ value }`, or `{ refusal }` for an
72
+ error with a `code` (ENOENT, ENOTDIR, EEXIST), and the program's client
73
+ rethrows the refusal as the error a throw would have delivered. A refusal
74
+ thrown from an entrypoint is recorded by the platform as an exception
75
+ ("canceled ... your Worker's code had hung") although its caller was
76
+ answered. `SupervisorRPC` implements `answer`, so an entrypoint that extends
77
+ it has it; one written from scratch must implement it too.
78
+
70
79
  The route back to the host (namespace, dispatch method, supervisor
71
80
  entrypoint) is minted into every binding the fabric hands a program, in the
72
81
  host's isolate, and the entrypoints that answer those bindings read it from
@@ -247,6 +256,43 @@ as it lives. `dynamicWorkerHeadroom(ctx)` is what is left,
247
256
  `claimDynamicWorkers(ctx, n)` reserves a width, `loaderLedgerStats(ctx)`
248
257
  reports it all, and a limit refusal names the workers in flight.
249
258
 
259
+ `beginLoaderFetch(ctx, key)` holds a worker and returns the function that
260
+ ends the hold. To wait for room rather than be refused, take the hold with
261
+ `beginLoaderFetchWhenFree` instead:
262
+
263
+ ```ts
264
+ import { beginLoaderFetchWhenFree } from '@nimbus-sh/fabric';
265
+
266
+ const end = await beginLoaderFetchWhenFree(ctx, key, { signal: AbortSignal.timeout(15_000) });
267
+ try {
268
+ return await worker.getEntrypoint().run();
269
+ } catch (error) {
270
+ end(error); // a limit refusal pauses the ledger; anything else just ends the hold
271
+ throw error;
272
+ } finally {
273
+ end();
274
+ }
275
+ ```
276
+
277
+ It resolves, holding `key`, once `key` is already in flight (requests to
278
+ one worker count once) or one more distinct worker fits. Waits are let in in
279
+ the order they asked, one per freed slot, by whoever makes the room: any
280
+ hold's end, a claim's release, or the end of a refusal's pause, so a wait
281
+ sees Nimbus's own releases as well as the caller's. The hold is taken as the
282
+ wait is let in, so no other caller can take the slot first, and it is the
283
+ caller's to end. An aborted `signal` rejects the wait with its reason, and
284
+ the wait holds nothing. A resident process holds its worker for as long as
285
+ it runs, so bound a wait that room may never reach.
286
+
287
+ The platform counts a worker for a moment after its call returns, which no
288
+ release can show. So a call refused with "Dynamic worker concurrency limit
289
+ exceeded" hands the refusal to its end function, and the ledger then admits
290
+ no new worker for 50 ms, doubling to 2 s while refusals continue
291
+ (`loaderLedgerStats(ctx).pauseMs`; the headroom reads 0 meanwhile).
292
+ `IsolatePool` retries a refused call this way, for 15 s in all. Holds taken
293
+ under a claim (`beginLoaderFetch(ctx, key, claim)`, or `IsolatePool`'s
294
+ `claim` option, which `Fanout` passes) count inside its width.
295
+
250
296
  ## Process fabric
251
297
 
252
298
  A resident process is a Durable Object facet running a class from a dynamic
@@ -344,6 +390,32 @@ and never `method.call(ep, request)`, which workerd refuses.
344
390
 
345
391
  Nesting is capped at depth 4. Raise it with `NIMBUS_INNER_LOADER_DEPTH`.
346
392
 
393
+ A classic Durable Object binding is a local namespace inside the inner
394
+ Worker (`inner-do-env.ts`), because a namespace's API is synchronous and an
395
+ RpcPromise cannot travel as an argument. `innerWorkerModules` makes an adapter
396
+ the bundle's first import; it replaces `env.MY_DO` in the env every handler,
397
+ entrypoint and object of the isolate sees, so
398
+ `env.MY_DO.get(env.MY_DO.idFromName('x'))` needs no `await`. A stub is
399
+ `new RpcStub(target)`, with a prototype shaped as a Durable Object stub's:
400
+ an entrypoint of a dynamically-loaded Worker is not transferable, an RPC stub
401
+ is. The target relays each member the caller reaches (a call, a read, or a
402
+ path through both) to `NimbusDurableObjectNamespace.callOn` or `getOn`, and
403
+ the session reaches it on the object's facet. The adapter also exports the
404
+ build's class check, under a name the bundle never spells.
405
+ tests/unit/wrangler-dev-do-rpc-workerd.mjs checks the whole stub surface
406
+ against plain workerd.
407
+
408
+ Limits, where a stub differs from Cloudflare's:
409
+
410
+ - `typeof stub` is `'function'`, not `'object'`: the runtime makes every RPC
411
+ stub callable.
412
+ - A Worker Loader env cannot carry a stub. `env.LOADER.load({ env: { S: stub } })`
413
+ throws "RpcStub cannot be serialized in this context because it is not a
414
+ persistent stub", where Cloudflare passes it. The loader shim keeps a
415
+ child's code and loads it again in each later request, so the child's env
416
+ can carry nothing made in one request; a namespace is refused there on
417
+ Cloudflare too.
418
+
347
419
  ## Measured platform limits
348
420
 
349
421
  Figures below come from production workerd, June to August 2026. The code
@@ -226,30 +226,20 @@ interface NimbusDoNamespaceProps {
226
226
  route?: HostRoute;
227
227
  }
228
228
  /**
229
- * `env.MY_DO` shim — a DurableObjectNamespace-like WorkerEntrypoint.
229
+ * The binding the loader passes for `env.MY_DO` (a WorkerEntrypoint of the
230
+ * session's isolate). The inner Worker does not use it as its namespace: a
231
+ * DurableObjectNamespace's API is synchronous, and this one's answers are
232
+ * RpcPromises, which cannot travel as arguments. The inner Worker replaces it
233
+ * with a local namespace (inner-do-env.ts, innerWorkerModules) that makes ids
234
+ * and stubs itself, and relays each member a stub's caller reaches, its
235
+ * fetch included, to `callOn` or `getOn`.
230
236
  *
231
- * Usage from inner Worker:
232
- * const id = await env.MY_DO.idFromName('x'); // AWAIT required
233
- * const stub = env.MY_DO.get(id);
234
- * await stub.fetch(request);
235
- *
236
- * IMPORTANT: unlike the real DurableObjectNamespace, idFromName /
237
- * newUniqueId / idFromString here return **Promises**, because they're
238
- * RPC-backed WorkerEntrypoint methods. The inner caller MUST `await`
239
- * them before passing the result to `.get()`. Workers RPC pipelining
240
- * does not currently allow passing an RpcPromise as a method argument
241
- * — the no-await form fails with:
242
- * "Could not serialize object of type \"RpcPromise\"."
243
- *
244
- * Typical real-Worker code written for Cloudflare's synchronous
245
- * DurableObjectNamespace needs a one-word change (add `await`).
246
- *
247
- * idFromName produces prefix `name:` (deterministic FNV-style hash);
248
- * newUniqueId uses `uniq:` (random). The prefixes keep the two id
249
- * spaces distinct so a name-derived id can't collide with a random
250
- * one.
237
+ * `idFromName`, `newUniqueId`, `idFromString` and `get` answer as before, for
238
+ * a caller that awaits them. idFromName produces prefix `name:` (a
239
+ * deterministic hash, innerDoIdFromName); newUniqueId uses `uniq:`; the
240
+ * prefixes keep the two id spaces distinct.
251
241
  */
252
- export declare class NimbusDurableObjectNamespace extends WorkerEntrypoint<unknown, NimbusDoNamespaceProps> {
242
+ export declare class NimbusDurableObjectNamespace extends WorkerEntrypoint<object, NimbusDoNamespaceProps> {
253
243
  /** Stable string id derived from a name. Hash is deterministic. */
254
244
  idFromName(name: string): string;
255
245
  /** Fresh random id (matches DurableObjectNamespace.newUniqueId()). */
@@ -258,25 +248,33 @@ export declare class NimbusDurableObjectNamespace extends WorkerEntrypoint<unkno
258
248
  idFromString(s: string): string;
259
249
  /** Return a stub bound to the given id. */
260
250
  get(id: string): unknown;
251
+ /**
252
+ * The member of object `id` at `path` (names from the object down), called
253
+ * with `args`: its answer, or what it throws, as the object gave it.
254
+ */
255
+ callOn(id: string, path: string[], args: unknown[]): Promise<unknown>;
256
+ /** The member of object `id` at `path`, read. */
257
+ getOn(id: string, path: string[]): Promise<unknown>;
261
258
  }
262
259
  /** Props the DO stub carries: which binding, which supervisor, which id. */
263
260
  interface NimbusDoStubProps extends NimbusDoNamespaceProps {
264
261
  id?: string;
265
262
  }
263
+ /** What the session's innerDoFetch answers: the object's response, as fields. */
264
+ export interface InnerDoFetchAnswer {
265
+ status: number;
266
+ statusText: string;
267
+ headers: [string, string][];
268
+ body: ArrayBuffer | null;
269
+ }
266
270
  /**
267
- * A Durable-Object-namespace-stub for a specific id. Exposes fetch()
268
- * and will, if we later need it, forward RPC method calls through a
269
- * dispatch helper. The important invariant: EVERY call resolves the
270
- * inner DO class via getInnerDoClass() (./inner-do-registry.js) and
271
- * spins up / attaches to a facet via the supervisor's ctx.facets in
272
- * the SAME outer request context — never reusing stubs across requests.
271
+ * A Durable-Object-namespace-stub for a specific id, for a caller of the
272
+ * binding's own `get`: its fetch. The important invariant: EVERY call
273
+ * resolves the inner DO class via getInnerDoClass() (./inner-do-registry.js)
274
+ * and spins up / attaches to a facet via the supervisor's ctx.facets in the
275
+ * SAME outer request context — never reusing stubs across requests.
273
276
  */
274
277
  export declare class NimbusDOStub extends WorkerEntrypoint<object, NimbusDoStubProps> {
275
- /**
276
- * Resolve the supervisor DO through the composed host namespace and
277
- * dispatch the innerDoFetch op through its one supervisorOp entrypoint —
278
- * a host forwards envelopes, not private _rpc* methods.
279
- */
280
278
  fetch(request: Request): Promise<Response>;
281
279
  }
282
280
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
package/dist/bindings.js CHANGED
@@ -27,6 +27,7 @@ import { z } from 'zod/v4';
27
27
  import { disposeRpcResource, useRpcResource } from '@nimbus-sh/platform/rpc-dispose.js';
28
28
  import { supervisorEntrypoint, supervisorEntrypointName, stagedBootAssembler } from './composition.js';
29
29
  import { hostNamespaceBinding, hostOpDispatch } from './host-dispatch.js';
30
+ import { innerDoIdFromName } from './inner-do-env.js';
30
31
  import { assertModuleMapWithinCodeLimit } from './budgets.js';
31
32
  /**
32
33
  * `ctx.exports` — workerd's loopback bag, which the installed
@@ -586,46 +587,23 @@ export class NimbusLoadedEntrypoint extends WorkerEntrypoint {
586
587
  }
587
588
  }
588
589
  /**
589
- * `env.MY_DO` shim — a DurableObjectNamespace-like WorkerEntrypoint.
590
+ * The binding the loader passes for `env.MY_DO` (a WorkerEntrypoint of the
591
+ * session's isolate). The inner Worker does not use it as its namespace: a
592
+ * DurableObjectNamespace's API is synchronous, and this one's answers are
593
+ * RpcPromises, which cannot travel as arguments. The inner Worker replaces it
594
+ * with a local namespace (inner-do-env.ts, innerWorkerModules) that makes ids
595
+ * and stubs itself, and relays each member a stub's caller reaches, its
596
+ * fetch included, to `callOn` or `getOn`.
590
597
  *
591
- * Usage from inner Worker:
592
- * const id = await env.MY_DO.idFromName('x'); // AWAIT required
593
- * const stub = env.MY_DO.get(id);
594
- * await stub.fetch(request);
595
- *
596
- * IMPORTANT: unlike the real DurableObjectNamespace, idFromName /
597
- * newUniqueId / idFromString here return **Promises**, because they're
598
- * RPC-backed WorkerEntrypoint methods. The inner caller MUST `await`
599
- * them before passing the result to `.get()`. Workers RPC pipelining
600
- * does not currently allow passing an RpcPromise as a method argument
601
- * — the no-await form fails with:
602
- * "Could not serialize object of type \"RpcPromise\"."
603
- *
604
- * Typical real-Worker code written for Cloudflare's synchronous
605
- * DurableObjectNamespace needs a one-word change (add `await`).
606
- *
607
- * idFromName produces prefix `name:` (deterministic FNV-style hash);
608
- * newUniqueId uses `uniq:` (random). The prefixes keep the two id
609
- * spaces distinct so a name-derived id can't collide with a random
610
- * one.
598
+ * `idFromName`, `newUniqueId`, `idFromString` and `get` answer as before, for
599
+ * a caller that awaits them. idFromName produces prefix `name:` (a
600
+ * deterministic hash, innerDoIdFromName); newUniqueId uses `uniq:`; the
601
+ * prefixes keep the two id spaces distinct.
611
602
  */
612
603
  export class NimbusDurableObjectNamespace extends WorkerEntrypoint {
613
604
  /** Stable string id derived from a name. Hash is deterministic. */
614
605
  idFromName(name) {
615
- // Simple 64-bit-ish FNV-style hash → hex. Stable across runs;
616
- // distinct names → distinct strings; same name → same string.
617
- let h1 = 0xdeadbeef ^ name.length;
618
- let h2 = 0x41c6ce57 ^ name.length;
619
- for (let i = 0; i < name.length; i++) {
620
- const ch = name.charCodeAt(i);
621
- h1 = Math.imul(h1 ^ ch, 2654435761);
622
- h2 = Math.imul(h2 ^ ch, 1597334677);
623
- }
624
- h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
625
- h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
626
- const high = (h1 >>> 0).toString(16).padStart(8, '0');
627
- const low = (h2 >>> 0).toString(16).padStart(8, '0');
628
- return 'name:' + high + low;
606
+ return innerDoIdFromName(name);
629
607
  }
630
608
  /** Fresh random id (matches DurableObjectNamespace.newUniqueId()). */
631
609
  newUniqueId() {
@@ -650,72 +628,105 @@ export class NimbusDurableObjectNamespace extends WorkerEntrypoint {
650
628
  },
651
629
  });
652
630
  }
631
+ /**
632
+ * The member of object `id` at `path` (names from the object down), called
633
+ * with `args`: its answer, or what it throws, as the object gave it.
634
+ */
635
+ callOn(id, path, args) {
636
+ return innerDoMember(this.env, { ...(this.ctx.props || {}), id: String(id) }, path, args);
637
+ }
638
+ /** The member of object `id` at `path`, read. */
639
+ getOn(id, path) {
640
+ return innerDoMember(this.env, { ...(this.ctx.props || {}), id: String(id) }, path, null);
641
+ }
653
642
  }
654
643
  /**
655
- * A Durable-Object-namespace-stub for a specific id. Exposes fetch()
656
- * and will, if we later need it, forward RPC method calls through a
657
- * dispatch helper. The important invariant: EVERY call resolves the
658
- * inner DO class via getInnerDoClass() (./inner-do-registry.js) and
659
- * spins up / attaches to a facet via the supervisor's ctx.facets in
660
- * the SAME outer request context — never reusing stubs across requests.
644
+ * The session Durable Object, through the composed host namespace, and its
645
+ * one supervisorOp entrypoint: a host forwards envelopes, not private _rpc*
646
+ * methods. Throws when the binding cannot reach it; `release` drops the stub.
661
647
  */
662
- export class NimbusDOStub extends WorkerEntrypoint {
663
- /**
664
- * Resolve the supervisor DO through the composed host namespace and
665
- * dispatch the innerDoFetch op through its one supervisorOp entrypoint —
666
- * a host forwards envelopes, not private _rpc* methods.
667
- */
668
- async fetch(request) {
669
- const props = this.ctx.props || {};
670
- const supervisorDoId = String(props.supervisorDoId || '');
671
- if (!supervisorDoId)
672
- return new Response('Nimbus: supervisorDoId missing', { status: 500 });
673
- const bindingName = String(props.bindingName || '');
674
- const id = String(props.id || '');
675
- let stub = null;
676
- let dispatch;
677
- try {
678
- const ns = hostNamespaceBinding(this.env ?? {}, 'NimbusDOStub', props.route);
679
- stub = ns.get(ns.idFromString(supervisorDoId));
680
- dispatch = hostOpDispatch(stub, 'NimbusDOStub', props.route);
681
- }
682
- catch (e) {
683
- disposeRpcResource(stub);
684
- return new Response(`Nimbus: ${e instanceof Error ? e.message : String(e)}`, { status: 500 });
685
- }
686
- // Forward the full request (method, body, headers preserved) by
687
- // serializing what's needed and reconstructing on the other side.
688
- // The supervisor reconstitutes the Request from these fields and
689
- // invokes the facet.
690
- const body = request.method !== 'GET' && request.method !== 'HEAD'
691
- ? await request.arrayBuffer()
692
- : null;
648
+ function supervisorOf(env, props) {
649
+ const supervisorDoId = String(props.supervisorDoId || '');
650
+ if (!supervisorDoId)
651
+ throw new Error('supervisorDoId missing');
652
+ let stub = null;
653
+ try {
654
+ const ns = hostNamespaceBinding(env ?? {}, 'NimbusDOStub', props.route);
655
+ stub = ns.get(ns.idFromString(supervisorDoId));
656
+ const held = stub;
657
+ return { dispatch: hostOpDispatch(stub, 'NimbusDOStub', props.route), release: () => disposeRpcResource(held) };
658
+ }
659
+ catch (e) {
660
+ disposeRpcResource(stub);
661
+ throw e;
662
+ }
663
+ }
664
+ function isInnerDoFetchAnswer(value) {
665
+ return value !== null && typeof value === 'object'
666
+ && 'status' in value && typeof value.status === 'number'
667
+ && 'statusText' in value && typeof value.statusText === 'string'
668
+ && 'headers' in value && Array.isArray(value.headers)
669
+ && 'body' in value && (value.body === null || value.body instanceof ArrayBuffer);
670
+ }
671
+ /**
672
+ * The inner object's fetch: the request forwarded whole (method, body,
673
+ * headers) as fields the session reconstructs, and its response rebuilt here
674
+ * from the fields the session answers. A binding that cannot reach the
675
+ * session answers 500.
676
+ */
677
+ async function innerDoFetch(env, props, request) {
678
+ let supervisor;
679
+ try {
680
+ supervisor = supervisorOf(env, props);
681
+ }
682
+ catch (e) {
683
+ return new Response(`Nimbus: ${e instanceof Error ? e.message : String(e)}`, { status: 500 });
684
+ }
685
+ try {
686
+ const body = request.method !== 'GET' && request.method !== 'HEAD' ? await request.arrayBuffer() : null;
693
687
  const headerList = [];
694
688
  request.headers.forEach((v, k) => { headerList.push([k, v]); });
695
- try {
696
- return await useRpcResource(dispatch({
697
- op: 'innerDoFetch',
698
- args: [{
699
- bindingName,
700
- id,
701
- method: request.method,
702
- url: request.url,
703
- headers: headerList,
704
- body,
705
- }],
706
- }), (res) => {
707
- if (!(res instanceof Response)) {
708
- return new Response('Nimbus: innerDoFetch returned an invalid result', { status: 502 });
709
- }
710
- return new Response(res.body, {
711
- status: res.status,
712
- statusText: res.statusText,
713
- headers: res.headers,
714
- });
715
- });
716
- }
717
- finally {
718
- disposeRpcResource(stub);
719
- }
689
+ return await useRpcResource(supervisor.dispatch({
690
+ op: 'innerDoFetch',
691
+ args: [{ bindingName: String(props.bindingName || ''), id: String(props.id || ''), method: request.method, url: request.url, headers: headerList, body }],
692
+ }), (res) => {
693
+ if (!isInnerDoFetchAnswer(res)) {
694
+ return new Response('Nimbus: innerDoFetch returned an invalid result', { status: 502 });
695
+ }
696
+ return new Response(res.body, { status: res.status, statusText: res.statusText, headers: res.headers });
697
+ });
698
+ }
699
+ finally {
700
+ supervisor.release();
701
+ }
702
+ }
703
+ /**
704
+ * A member of the inner object, called with `args` or read (`args` null): the
705
+ * session reaches it on the object's facet and answers what it answered (a
706
+ * stub, function or stream travels as one) or rejects with what it threw,
707
+ * type and message kept.
708
+ */
709
+ async function innerDoMember(env, props, path, args) {
710
+ const supervisor = supervisorOf(env, props);
711
+ try {
712
+ return await supervisor.dispatch({
713
+ op: 'innerDoCall',
714
+ args: [{ bindingName: String(props.bindingName || ''), id: String(props.id || ''), path, args }],
715
+ });
716
+ }
717
+ finally {
718
+ supervisor.release();
719
+ }
720
+ }
721
+ /**
722
+ * A Durable-Object-namespace-stub for a specific id, for a caller of the
723
+ * binding's own `get`: its fetch. The important invariant: EVERY call
724
+ * resolves the inner DO class via getInnerDoClass() (./inner-do-registry.js)
725
+ * and spins up / attaches to a facet via the supervisor's ctx.facets in the
726
+ * SAME outer request context — never reusing stubs across requests.
727
+ */
728
+ export class NimbusDOStub extends WorkerEntrypoint {
729
+ async fetch(request) {
730
+ return innerDoFetch(this.env, this.ctx.props || {}, request);
720
731
  }
721
732
  }
package/dist/budgets.d.ts CHANGED
@@ -15,7 +15,9 @@
15
15
  * the width fan-outs have claimed and not yet released. A fan-out spends only
16
16
  * the {@link dynamicWorkerHeadroom} that leaves, so work a Durable Object
17
17
  * already has in flight — a resident process, the esbuild facet, a git
18
- * network op, another fan-out — keeps its slots.
18
+ * network op, another fan-out — keeps its slots. Work that would rather wait
19
+ * than be refused waits on the ledger ({@link beginLoaderFetchWhenFree}) and
20
+ * is let in, in the order it asked, by whichever release makes room.
19
21
  *
20
22
  * Keyed weakly off the hosting actor's `ctx`, like the facet slot books: the
21
23
  * limit is per Durable Object, and dynamic workers die with the isolate that
@@ -29,11 +31,29 @@
29
31
  * https://developers.cloudflare.com/changelog/post/2026-08-28-durable-objects-dynamic-workers-limit/
30
32
  */
31
33
  export declare const DO_DYNAMIC_WORKER_LIMIT = 10;
34
+ /**
35
+ * Ends one hold, idempotently. Pass the error the call failed with, if it
36
+ * did: a "Dynamic worker concurrency limit exceeded" refusal pauses the
37
+ * ledger's admissions (see {@link beginLoaderFetchWhenFree}); anything else,
38
+ * or nothing, just ends the hold.
39
+ */
40
+ export type EndLoaderFetch = (failure?: unknown) => void;
41
+ /**
42
+ * A width one fan-out reserved with {@link claimDynamicWorkers}. Holds taken
43
+ * under it (`beginLoaderFetch(ctx, key, claim)`) count inside that width, not
44
+ * on top of it, until `release` (idempotent).
45
+ */
46
+ export interface DynamicWorkerClaim {
47
+ release(): void;
48
+ }
32
49
  /**
33
50
  * Hold the Dynamic Worker `workerKey` in flight on this actor's ledger; the
34
51
  * returned function ends the hold (idempotently), from the caller's own
35
52
  * `finally`. Holds on one key nest: the worker counts once until the last
36
- * one ends, as the platform counts it.
53
+ * one ends, as the platform counts it. Under a `claim`, the hold counts
54
+ * inside the claim's width. This never waits: it is for work the actor
55
+ * starts regardless (a resident process); {@link beginLoaderFetchWhenFree}
56
+ * waits for room.
37
57
  *
38
58
  * A begin/end pair rather than a wrapper on purpose, and the shape is
39
59
  * load-bearing: wrapping the stub call in a ledger-owned async frame
@@ -46,22 +66,50 @@ export declare const DO_DYNAMIC_WORKER_LIMIT = 10;
46
66
  * workers: an RPC stub call must stay a direct property call awaited by the
47
67
  * frame that made it, so the ledger only brackets it.
48
68
  */
49
- export declare function beginLoaderFetch(ctx: object, workerKey: string): () => void;
69
+ export declare function beginLoaderFetch(ctx: object, workerKey: string, claim?: DynamicWorkerClaim): EndLoaderFetch;
70
+ /**
71
+ * {@link beginLoaderFetch} once the ledger has room: resolves, holding
72
+ * `workerKey`, as soon as that worker is already in flight (holds on it
73
+ * count once) or a distinct worker more fits — within the `claim`'s width,
74
+ * or the actor's headroom. Waits are let in in the order they asked, by
75
+ * whoever's release makes the room: a hold's end, a claim's release, a
76
+ * pause's end. The hold is taken as the wait is let in, so a freed slot
77
+ * wakes one waiter and no other caller can take it first; once resolved, it
78
+ * is the caller's to end.
79
+ *
80
+ * A call refused with "Dynamic worker concurrency limit exceeded" ends its
81
+ * hold with the refusal (`end(error)`) and waits again: the refusal pauses
82
+ * admission (50 ms, doubling to 2 s while refusals continue), because the
83
+ * platform counts a worker for a moment after its call returns and no
84
+ * release can show that.
85
+ *
86
+ * `signal` abandons the wait: it rejects with the signal's reason and holds
87
+ * nothing. A wait outlives nothing on its own: bound it with a signal when
88
+ * room may never come (a resident process holds its worker for as long as
89
+ * it runs).
90
+ *
91
+ * const end = await beginLoaderFetchWhenFree(ctx, key, { signal });
92
+ * try { return await worker.getEntrypoint().run(); }
93
+ * catch (error) { end(error); throw error; }
94
+ * finally { end(); }
95
+ */
96
+ export declare function beginLoaderFetchWhenFree(ctx: object, workerKey: string, options?: {
97
+ signal?: AbortSignal;
98
+ claim?: DynamicWorkerClaim;
99
+ }): Promise<EndLoaderFetch>;
50
100
  /**
51
101
  * Distinct Dynamic Workers this actor may still put in flight: the limit
52
- * less what is held and claimed right now. Never negative.
102
+ * less what is held and claimed right now, and none while a limit refusal's
103
+ * pause lasts. Never negative.
53
104
  */
54
105
  export declare function dynamicWorkerHeadroom(ctx: object): number;
55
106
  /**
56
107
  * Claim `width` distinct Dynamic Workers for one fan-out, or null when the
57
108
  * headroom cannot hold it. The claim counts until `release` (idempotent), so
58
109
  * a second fan-out sizing itself meanwhile sees it; the claimant's own
59
- * dispatches are held as well while they run, which only ever over-counts
60
- * toward sending that second fan-out elsewhere.
110
+ * dispatches, held under the claim, count inside it.
61
111
  */
62
- export declare function claimDynamicWorkers(ctx: object, width: number): {
63
- release(): void;
64
- } | null;
112
+ export declare function claimDynamicWorkers(ctx: object, width: number): DynamicWorkerClaim | null;
65
113
  /** Snapshot for the diag surface. Pure read; no I/O. */
66
114
  export declare function loaderLedgerStats(ctx: object): {
67
115
  limit: number;
@@ -69,6 +117,10 @@ export declare function loaderLedgerStats(ctx: object): {
69
117
  claimed: number;
70
118
  headroom: number;
71
119
  peak: number;
120
+ /** Waits not yet admitted. */
121
+ waiting: number;
122
+ /** Length of the pause a limit refusal started, while it lasts; 0 when admitting. */
123
+ pauseMs: number;
72
124
  };
73
125
  /**
74
126
  * Name the per-DO accounting on a "Dynamic worker concurrency limit exceeded"
@@ -1 +1 @@
1
- {"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../src/budgets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AA0B1C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,IAAI,CAY3E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,IAAI,IAAI,CAAA;CAAE,GAAG,IAAI,CAa1F;AAED,wDAAwD;AACxD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CASA;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAU7E;AAID;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,WAAa,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAoBrF;AA4BD;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,sEAAsE;AACtE,eAAO,MAAM,yBAAyB,iCAAiC,CAAC;AAExE,mEAAmE;AACnE,UAAU,sBAAsB;IAC9B,OAAO,EAAE;QACP,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;QAC7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACjD,CAAC;CACH;AAqCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAatF;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,GAAG,EAAE,sBAAsB,GAAG,MAAM,CAGlE;AAED,4EAA4E;AAC5E,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxF;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,sBAAsB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAK/C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAU9E"}
1
+ {"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../src/budgets.ts"],"names":[],"mappings":"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"}