@zlink-systems/framework 0.11.0 → 0.13.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.
Files changed (119) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Configuration/EndpointNotation.d.ts +5 -4
  3. package/dist/contracts/Configuration/EndpointNotation.js +5 -4
  4. package/dist/contracts/Configuration/InternalDefaults.d.ts +0 -1
  5. package/dist/contracts/Configuration/InternalDefaults.js +1 -2
  6. package/dist/contracts/Configuration/RegistrationNormalizers.js +1 -2
  7. package/dist/contracts/Configuration/RegistrationTypes.d.ts +2 -5
  8. package/dist/contracts/Configuration/RegistrationValidators.js +0 -1
  9. package/dist/contracts/Errors/ZLinkFrameworkException.d.ts +6 -7
  10. package/dist/contracts/Errors/ZLinkFrameworkException.js +6 -7
  11. package/dist/runtime/actors/actor-client.js +1 -1
  12. package/dist/runtime/actors/actor-mailbox.js +1 -5
  13. package/dist/runtime/backend/contracts/index.d.ts +2 -0
  14. package/dist/runtime/backend/mesh-completion-table.d.ts +1 -3
  15. package/dist/runtime/backend/mesh-completion-table.js +11 -15
  16. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +11 -4
  17. package/dist/runtime/backend/mesh-dispatch-pump.js +201 -134
  18. package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +3 -4
  19. package/dist/runtime/backend/node/node-backend-adapter-factory.js +51 -37
  20. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
  21. package/dist/runtime/backend/node/node-backend-adapter-support.js +2 -2
  22. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +2 -2
  23. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +16 -0
  24. package/dist/runtime/backend/node/node-event-loop-poller.js +49 -0
  25. package/dist/runtime/backend/node/node-raw-binding-port.js +24 -41
  26. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +8 -8
  27. package/dist/runtime/backend/node/node-raw-mesh-backend.js +100 -107
  28. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +3 -2
  29. package/dist/runtime/backend/node/node-socket-backend-adapter.js +18 -67
  30. package/dist/runtime/backend/raw-binding-port.d.ts +1 -0
  31. package/dist/runtime/backend/runtime-values.d.ts +5 -1
  32. package/dist/runtime/channels/channel-dispatchers.js +2 -2
  33. package/dist/runtime/channels/channel-envelope.js +324 -121
  34. package/dist/runtime/channels/channel-multipart.d.ts +8 -1
  35. package/dist/runtime/channels/channel-outbound-operations.js +0 -2
  36. package/dist/runtime/channels/channel-receive-loops.d.ts +1 -3
  37. package/dist/runtime/channels/channel-receive-loops.js +25 -65
  38. package/dist/runtime/channels/channel-socket-registry.js +3 -1
  39. package/dist/runtime/channels/channel-transports.d.ts +2 -1
  40. package/dist/runtime/channels/channel-transports.js +12 -10
  41. package/dist/runtime/execution/serial-execution-queue.d.ts +5 -18
  42. package/dist/runtime/execution/serial-execution-queue.js +16 -80
  43. package/dist/runtime/foundation/event-loop-resources.d.ts +0 -3
  44. package/dist/runtime/foundation/event-loop-resources.js +2 -11
  45. package/dist/runtime/foundation/operation-registry.d.ts +2 -8
  46. package/dist/runtime/foundation/operation-registry.js +3 -21
  47. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +19 -7
  48. package/dist/runtime/foundation/raw-service-mesh-runtime.js +56 -10
  49. package/dist/runtime/foundation/service-mailbox.d.ts +1 -7
  50. package/dist/runtime/foundation/service-mailbox.js +3 -2
  51. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -1
  52. package/dist/runtime/foundation/service-stateful-registry.d.ts +1 -1
  53. package/dist/runtime/foundation/service-stateful-registry.js +2 -2
  54. package/dist/runtime/foundation/service-stateful-runtime.js +14 -14
  55. package/dist/runtime/framework-errors-internal.d.ts +4 -4
  56. package/dist/runtime/framework-errors-internal.js +8 -10
  57. package/dist/runtime/host/actor-placement-coordinator.js +1 -1
  58. package/dist/runtime/host/index.js +1 -1
  59. package/dist/runtime/host/service-relocation-host-runtime.js +0 -4
  60. package/dist/runtime/host/spot-address-transport.js +1 -1
  61. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -1
  62. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +0 -12
  63. package/dist/runtime/spots/spot-node-runtime-manager.js +6 -166
  64. package/dist/runtime/spots/spot-serial-turn-executor.js +1 -4
  65. package/dist/runtime/spots/spot-timer.d.ts +3 -0
  66. package/dist/runtime/spots/spot-timer.js +87 -18
  67. package/dist/runtime/streams/session-serial-executor.js +1 -3
  68. package/dist/runtime/streams/stream-session-runtime.d.ts +2 -2
  69. package/dist/runtime/streams/stream-session-runtime.js +13 -19
  70. package/dist/runtime/workers/index.d.ts +0 -1
  71. package/dist/runtime/workers/index.js +1 -9
  72. package/package.json +3 -3
  73. package/src/contracts/Configuration/EndpointNotation.ts +5 -4
  74. package/src/contracts/Configuration/InternalDefaults.ts +0 -1
  75. package/src/contracts/Configuration/RegistrationNormalizers.ts +2 -4
  76. package/src/contracts/Configuration/RegistrationTypes.ts +2 -5
  77. package/src/contracts/Configuration/RegistrationValidators.ts +0 -1
  78. package/src/contracts/Errors/ZLinkFrameworkException.ts +6 -7
  79. package/src/runtime/actors/actor-client.ts +1 -1
  80. package/src/runtime/actors/actor-mailbox.ts +1 -12
  81. package/src/runtime/backend/contracts/index.ts +2 -0
  82. package/src/runtime/backend/mesh-completion-table.ts +12 -23
  83. package/src/runtime/backend/mesh-dispatch-pump.ts +206 -138
  84. package/src/runtime/backend/node/node-backend-adapter-factory.ts +66 -35
  85. package/src/runtime/backend/node/node-backend-adapter-support.ts +4 -4
  86. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +2 -2
  87. package/src/runtime/backend/node/node-event-loop-poller.ts +55 -0
  88. package/src/runtime/backend/node/node-raw-binding-port.ts +30 -45
  89. package/src/runtime/backend/node/node-raw-mesh-backend.ts +97 -110
  90. package/src/runtime/backend/node/node-socket-backend-adapter.ts +23 -69
  91. package/src/runtime/backend/raw-binding-port.ts +1 -0
  92. package/src/runtime/backend/runtime-values.ts +7 -1
  93. package/src/runtime/channels/channel-dispatchers.ts +2 -2
  94. package/src/runtime/channels/channel-envelope.ts +379 -109
  95. package/src/runtime/channels/channel-multipart.ts +9 -1
  96. package/src/runtime/channels/channel-outbound-operations.ts +0 -1
  97. package/src/runtime/channels/channel-receive-loops.ts +24 -75
  98. package/src/runtime/channels/channel-socket-registry.ts +4 -1
  99. package/src/runtime/channels/channel-transports.ts +20 -10
  100. package/src/runtime/execution/serial-execution-queue.ts +16 -108
  101. package/src/runtime/foundation/event-loop-resources.ts +2 -11
  102. package/src/runtime/foundation/operation-registry.ts +2 -22
  103. package/src/runtime/foundation/raw-service-mesh-runtime.ts +74 -19
  104. package/src/runtime/foundation/service-mailbox.ts +3 -13
  105. package/src/runtime/foundation/service-runtime-contracts.ts +2 -1
  106. package/src/runtime/foundation/service-stateful-registry.ts +2 -2
  107. package/src/runtime/foundation/service-stateful-runtime.ts +14 -14
  108. package/src/runtime/framework-errors-internal.ts +8 -10
  109. package/src/runtime/host/actor-placement-coordinator.ts +1 -1
  110. package/src/runtime/host/index.ts +2 -1
  111. package/src/runtime/host/service-relocation-host-runtime.ts +0 -4
  112. package/src/runtime/host/spot-address-transport.ts +1 -1
  113. package/src/runtime/host/user-spot-creation-coordinator.ts +1 -1
  114. package/src/runtime/spots/spot-node-runtime-manager.ts +13 -233
  115. package/src/runtime/spots/spot-serial-turn-executor.ts +1 -8
  116. package/src/runtime/spots/spot-timer.ts +109 -18
  117. package/src/runtime/streams/session-serial-executor.ts +1 -7
  118. package/src/runtime/streams/stream-session-runtime.ts +13 -17
  119. package/src/runtime/workers/index.ts +2 -17
@@ -152,20 +152,15 @@ class ZLinkChannelReceiveLoop {
152
152
  this.roundRobin?.setReady(this.receiveOwner, false);
153
153
  this.roundRobin?.release(this.receiveOwner);
154
154
  batch.reset();
155
- await waitReceiveLoopIdle();
155
+ if (!await this.poller.waitForReadable(capacitySignal))
156
+ break;
156
157
  continue;
157
158
  }
158
159
  const applicationJobPermit = await this.acquirePermit(capacitySignal);
159
160
  if (applicationJobPermit === undefined)
160
161
  break;
161
- if (!this.poller.wait(0)) {
162
- applicationJobPermit.releaseAfterInternalProcessing();
163
- this.roundRobin?.setReady(this.receiveOwner, false);
164
- this.roundRobin?.release(this.receiveOwner);
165
- batch.reset();
166
- await waitReceiveLoopIdle();
167
- continue;
168
- }
162
+ // Readiness can become stale while admission waits. The nonblocking
163
+ // recv below owns the empty-result check and returns the permit then.
169
164
  this.roundRobin?.setReady(this.receiveOwner, true);
170
165
  if (this.roundRobin?.tryAcquire(this.receiveOwner) === false) {
171
166
  applicationJobPermit.releaseAfterInternalProcessing();
@@ -183,12 +178,14 @@ class ZLinkChannelReceiveLoop {
183
178
  }
184
179
  const received = this.router.recv(1);
185
180
  if (received == null) {
181
+ this.poller.markDrained();
186
182
  applicationJobPermit.releaseAfterInternalProcessing();
187
183
  releaseRawReceive();
188
184
  this.roundRobin?.setReady(this.receiveOwner, false);
189
185
  this.roundRobin?.release(this.receiveOwner);
190
186
  batch.reset();
191
- await waitReceiveLoopIdle();
187
+ if (!await this.poller.waitForReadable(capacitySignal))
188
+ break;
192
189
  continue;
193
190
  }
194
191
  const receivedBytes = messageBytes(received.parts);
@@ -345,20 +342,13 @@ class ZLinkSubscriberReceiveLoop {
345
342
  this.roundRobin?.setReady(this.receiveOwner, false);
346
343
  this.roundRobin?.release(this.receiveOwner);
347
344
  batch.reset();
348
- await waitReceiveLoopIdle();
345
+ if (!await this.poller.waitForReadable(capacitySignal))
346
+ break;
349
347
  continue;
350
348
  }
351
349
  const applicationJobPermit = await this.acquirePermit(capacitySignal);
352
350
  if (applicationJobPermit === undefined)
353
351
  break;
354
- if (!this.poller.wait(0)) {
355
- applicationJobPermit.releaseAfterInternalProcessing();
356
- this.roundRobin?.setReady(this.receiveOwner, false);
357
- this.roundRobin?.release(this.receiveOwner);
358
- batch.reset();
359
- await waitReceiveLoopIdle();
360
- continue;
361
- }
362
352
  this.roundRobin?.setReady(this.receiveOwner, true);
363
353
  if (this.roundRobin?.tryAcquire(this.receiveOwner) === false) {
364
354
  applicationJobPermit.releaseAfterInternalProcessing();
@@ -375,14 +365,16 @@ class ZLinkSubscriberReceiveLoop {
375
365
  continue;
376
366
  }
377
367
  const topicMessage = this.adapter.createTopicMessage();
378
- if (!this.subscriber.subscribe(topicMessage)) {
368
+ if (!this.subscriber.subscribe(topicMessage, 1)) {
369
+ this.poller.markDrained();
379
370
  applicationJobPermit.releaseAfterInternalProcessing();
380
371
  releaseRawReceive();
381
372
  topicMessage.close();
382
373
  this.roundRobin?.setReady(this.receiveOwner, false);
383
374
  this.roundRobin?.release(this.receiveOwner);
384
375
  batch.reset();
385
- await waitReceiveLoopIdle();
376
+ if (!await this.poller.waitForReadable(capacitySignal))
377
+ break;
386
378
  continue;
387
379
  }
388
380
  const receivedBytes = messageBytes(topicMessage.parts);
@@ -526,14 +518,8 @@ class ZLinkRouteReceiveLoop {
526
518
  this.roundRobin?.setReady(this.receiveOwner, false);
527
519
  this.roundRobin?.release(this.receiveOwner);
528
520
  batch.reset();
529
- await waitReceiveLoopIdle();
530
- continue;
531
- }
532
- if (!this.poller.wait(0)) {
533
- this.roundRobin?.setReady(this.receiveOwner, false);
534
- this.roundRobin?.release(this.receiveOwner);
535
- batch.reset();
536
- await waitReceiveLoopIdle();
521
+ if (!await this.poller.waitForReadable(capacitySignal))
522
+ break;
537
523
  continue;
538
524
  }
539
525
  this.roundRobin?.setReady(this.receiveOwner, true);
@@ -551,11 +537,13 @@ class ZLinkRouteReceiveLoop {
551
537
  }
552
538
  const received = this.router.recv(1);
553
539
  if (received == null) {
540
+ this.poller.markDrained();
554
541
  releaseRawReceive();
555
542
  this.roundRobin?.setReady(this.receiveOwner, false);
556
543
  this.roundRobin?.release(this.receiveOwner);
557
544
  batch.reset();
558
- await waitReceiveLoopIdle();
545
+ if (!await this.poller.waitForReadable(capacitySignal))
546
+ break;
559
547
  continue;
560
548
  }
561
549
  const receivedBytes = messageBytes(received.parts);
@@ -659,11 +647,11 @@ class ZLinkRouteReceiveLoop {
659
647
  }
660
648
  exports.ZLinkRouteReceiveLoop = ZLinkRouteReceiveLoop;
661
649
  const RECEIVE_BATCH_MESSAGE_LIMIT = 64;
662
- const RECEIVE_BATCH_BYTE_LIMIT = 4n * 1024n * 1024n;
650
+ const RECEIVE_BATCH_BYTE_LIMIT = 4 * 1024 * 1024;
663
651
  const RECEIVE_BATCH_TIME_LIMIT_MS = 2;
664
652
  class ZLinkReceiveBatchBudget {
665
653
  messages = 0;
666
- bytes = 0n;
654
+ bytes = 0;
667
655
  startedAt = performance.now();
668
656
  record(bytes) {
669
657
  this.messages += 1;
@@ -678,51 +666,23 @@ class ZLinkReceiveBatchBudget {
678
666
  }
679
667
  reset() {
680
668
  this.messages = 0;
681
- this.bytes = 0n;
669
+ this.bytes = 0;
682
670
  this.startedAt = performance.now();
683
671
  }
684
672
  }
685
- class ZLinkSharedIdleWaiter {
686
- delayMs;
687
- pending;
688
- resolvePending;
689
- wake = () => {
690
- const resolve = this.resolvePending;
691
- this.pending = undefined;
692
- this.resolvePending = undefined;
693
- resolve?.();
694
- };
695
- constructor(delayMs) {
696
- this.delayMs = delayMs;
697
- }
698
- wait() {
699
- if (this.pending !== undefined)
700
- return this.pending;
701
- this.pending = new Promise((resolve) => {
702
- this.resolvePending = resolve;
703
- });
704
- setTimeout(this.wake, this.delayMs);
705
- return this.pending;
706
- }
707
- }
708
- const CHANNEL_RECEIVE_IDLE_POLL_INTERVAL_MS = 5;
709
- const receiveLoopIdleWaiter = new ZLinkSharedIdleWaiter(CHANNEL_RECEIVE_IDLE_POLL_INTERVAL_MS);
710
- function waitReceiveLoopIdle() {
711
- return receiveLoopIdleWaiter.wait();
712
- }
713
673
  function waitReceiveLoopTurn() {
714
674
  return new Promise(resolve => setImmediate(resolve));
715
675
  }
716
676
  function messageBytes(parts) {
717
- return parts.reduce((sum, part) => sum + messagePartBytes(part), 0n);
677
+ return parts.reduce((sum, part) => sum + messagePartBytes(part), 0);
718
678
  }
719
679
  function messagePartBytes(part) {
720
680
  if (part === undefined) {
721
- return 0n;
681
+ return 0;
722
682
  }
723
683
  const size = part.size;
724
684
  if (typeof size === 'function') {
725
- return BigInt(size.call(part));
685
+ return size.call(part);
726
686
  }
727
- return BigInt(part.data().byteLength);
687
+ return part.data().byteLength;
728
688
  }
@@ -999,8 +999,10 @@ class ZLinkChannelSocketRegistry {
999
999
  if (!connection.readablePoller.wait(0))
1000
1000
  return;
1001
1001
  const received = connection.dealer.recv(1);
1002
- if (received === undefined)
1002
+ if (received === undefined) {
1003
+ connection.readablePoller.markDrained();
1003
1004
  return;
1005
+ }
1004
1006
  try {
1005
1007
  if (received.parts.length !== 1
1006
1008
  || !(0, client_server_service_wire_1.isClientServerControlFrame)(received.parts[0].data())) {
@@ -62,10 +62,11 @@ export declare class ZLinkRuntimeRouteTransport implements ZLinkRouteClientTrans
62
62
  private readonly manualNodeTarget?;
63
63
  private readonly localNodeSubmit?;
64
64
  private readonly metrics?;
65
+ private readonly flowCreationEnabled;
65
66
  constructor(manager: () => ZLinkChannelTransportRuntime | undefined, routeChannelPredicate?: ((routerChannelId: string) => boolean) | undefined, meshRuntime?: (() => {
66
67
  readonly meshNode: (meshName: string) => ZLinkBackendMeshNode | undefined;
67
68
  readonly meshCompletionTable: (meshName: string) => ZLinkMeshCompletionTable | undefined;
68
- } | undefined) | undefined, codecs?: ZLinkChannelEnvelopeCodecRegistry | undefined, manualNodeTarget?: ((meshName: string, targetNodeRid: string) => boolean | undefined) | undefined, localNodeSubmit?: ((meshName: string, sourceNodeRid: string, parts: readonly MessageLike[]) => ZLinkSubmitResult) | undefined, metrics?: ZLinkRuntimeMetrics | undefined);
69
+ } | undefined) | undefined, codecs?: ZLinkChannelEnvelopeCodecRegistry | undefined, manualNodeTarget?: ((meshName: string, targetNodeRid: string) => boolean | undefined) | undefined, localNodeSubmit?: ((meshName: string, sourceNodeRid: string, parts: readonly MessageLike[]) => ZLinkSubmitResult) | undefined, metrics?: ZLinkRuntimeMetrics | undefined, flowCreationEnabled?: () => boolean);
69
70
  canRouteChannel(routerChannelId: string): boolean;
70
71
  canRoutePacketChannel(routerChannelId: string): boolean;
71
72
  submit(meshName: string, targetNodeRid: string, packetName: string | undefined, message: unknown, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
@@ -22,7 +22,8 @@ class ZLinkRuntimeRouteTransport {
22
22
  manualNodeTarget;
23
23
  localNodeSubmit;
24
24
  metrics;
25
- constructor(manager, routeChannelPredicate = undefined, meshRuntime = undefined, codecs, manualNodeTarget, localNodeSubmit, metrics) {
25
+ flowCreationEnabled;
26
+ constructor(manager, routeChannelPredicate = undefined, meshRuntime = undefined, codecs, manualNodeTarget, localNodeSubmit, metrics, flowCreationEnabled = () => true) {
26
27
  this.manager = manager;
27
28
  this.routeChannelPredicate = routeChannelPredicate;
28
29
  this.meshRuntime = meshRuntime;
@@ -30,6 +31,7 @@ class ZLinkRuntimeRouteTransport {
30
31
  this.manualNodeTarget = manualNodeTarget;
31
32
  this.localNodeSubmit = localNodeSubmit;
32
33
  this.metrics = metrics;
34
+ this.flowCreationEnabled = flowCreationEnabled;
33
35
  }
34
36
  canRouteChannel(routerChannelId) {
35
37
  const manager = this.manager();
@@ -46,10 +48,10 @@ class ZLinkRuntimeRouteTransport {
46
48
  async submit(meshName, targetNodeRid, packetName, message, signal, metadata) {
47
49
  // Call-scoped flow (spec 27 §4): the envelope flow pair lives only for
48
50
  // the duration of this outbound call, never in the caller's context.
49
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.submitNode(meshName, targetNodeRid, packetName, message, signal, metadata, false));
51
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.submitNode(meshName, targetNodeRid, packetName, message, signal, metadata, false));
50
52
  }
51
53
  async submitInfrastructure(meshName, targetNodeRid, packetName, message, signal, metadata) {
52
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.submitNode(meshName, targetNodeRid, packetName, message, signal, metadata, true));
54
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.submitNode(meshName, targetNodeRid, packetName, message, signal, metadata, true));
53
55
  }
54
56
  async submitNode(meshName, targetNodeRid, packetName, message, signal, metadata, allowObjectClientTarget) {
55
57
  const node = this.meshNode(meshName);
@@ -78,7 +80,7 @@ class ZLinkRuntimeRouteTransport {
78
80
  }
79
81
  }
80
82
  request(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata) {
81
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata));
83
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata));
82
84
  }
83
85
  async requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata) {
84
86
  const node = this.meshNode(meshName);
@@ -94,7 +96,7 @@ class ZLinkRuntimeRouteTransport {
94
96
  return this.decodeMeshReply(meshName, completion);
95
97
  }
96
98
  submitToChannel(meshName, channelName, packetName, message, signal, metadata) {
97
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.submitToChannelScoped(meshName, channelName, packetName, message, signal, metadata));
99
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.submitToChannelScoped(meshName, channelName, packetName, message, signal, metadata));
98
100
  }
99
101
  async submitToChannelScoped(meshName, channelName, packetName, message, signal, metadata) {
100
102
  (0, abort_1.throwIfAborted)(signal);
@@ -113,7 +115,7 @@ class ZLinkRuntimeRouteTransport {
113
115
  }
114
116
  }
115
117
  requestToChannel(meshName, channelName, packetName, request, timeoutMs, signal, metadata) {
116
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata));
118
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata));
117
119
  }
118
120
  async requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata) {
119
121
  (0, abort_1.throwIfAborted)(signal);
@@ -149,7 +151,7 @@ class ZLinkRuntimeRouteTransport {
149
151
  }
150
152
  }
151
153
  sendToSpot(spotRouteTarget, message, options) {
152
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.sendToSpotScoped(spotRouteTarget, message, options));
154
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.sendToSpotScoped(spotRouteTarget, message, options));
153
155
  }
154
156
  async sendToSpotScoped(spotRouteTarget, message, options) {
155
157
  const node = this.meshNode(spotRouteTarget.routerChannelId);
@@ -182,7 +184,7 @@ class ZLinkRuntimeRouteTransport {
182
184
  return { status: submission_result_1.ZLinkSubmitStatus.Submitted };
183
185
  }
184
186
  requestToSpot(spotRouteTarget, request, options) {
185
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.requestToSpotScoped(spotRouteTarget, request, options));
187
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestToSpotScoped(spotRouteTarget, request, options));
186
188
  }
187
189
  async requestToSpotScoped(spotRouteTarget, request, options) {
188
190
  const meshName = spotRouteTarget.routerChannelId;
@@ -218,7 +220,7 @@ class ZLinkRuntimeRouteTransport {
218
220
  return this.requireManager().routeRequestRawFromSpotToSpot(sourceSpot, spotRouteTarget, request, options.timeoutMs, options.signal);
219
221
  }
220
222
  requestRawToSpot(spotRouteTarget, request, options) {
221
- return (0, flow_context_1.runWithOutboundFlow)(true, () => this.requestRawToSpotScoped(spotRouteTarget, request, options));
223
+ return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestRawToSpotScoped(spotRouteTarget, request, options));
222
224
  }
223
225
  async requestRawToSpotScoped(spotRouteTarget, request, options) {
224
226
  const meshName = spotRouteTarget.routerChannelId;
@@ -299,7 +301,7 @@ class ZLinkRuntimeRouteTransport {
299
301
  return table;
300
302
  }
301
303
  encodeMessage(kind, channelName, packetName, message, timeoutMs, metadata) {
302
- return (0, channel_envelope_1.encodeChannelEnvelopeParts)(kind, channelName, packetName, message, timeoutMs, undefined, this.codecs, undefined, true, metadata);
304
+ return (0, channel_envelope_1.encodeChannelEnvelopeParts)(kind, channelName, packetName, message, timeoutMs, undefined, this.codecs, undefined, this.flowCreationEnabled(), metadata);
303
305
  }
304
306
  async waitForMeshReply(meshName, completionPromise) {
305
307
  const completion = await completionPromise;
@@ -4,22 +4,15 @@ export interface ZLinkSerialWorkOptions {
4
4
  readonly payloadBytes?: number;
5
5
  readonly metadataBytes?: number;
6
6
  }
7
- /** Internal per-owner reservation limits, never a shared ingress budget. */
7
+ /** Internal per-owner fairness settings; ingress capacity belongs to the host queue. */
8
8
  export interface ZLinkSerialSchedulerOptions {
9
- readonly applicationMessageCapacity?: number;
10
- readonly applicationByteCapacity?: number;
11
- readonly lifecycleMessageCapacity?: number;
12
- readonly lifecycleByteCapacity?: number;
13
9
  readonly ownerTimeBudget?: number;
14
10
  readonly lifecycleBurstLimit?: number;
15
- readonly fixedWorkByteCost?: number;
16
- readonly capacityError?: (lane: ZLinkSerialWorkLane) => unknown;
17
11
  }
18
- export declare const ZLINK_DEFAULT_SERIAL_SCHEDULER_OPTIONS: Required<Omit<ZLinkSerialSchedulerOptions, 'capacityError'>>;
12
+ export declare const ZLINK_DEFAULT_SERIAL_SCHEDULER_OPTIONS: Required<ZLinkSerialSchedulerOptions>;
19
13
  export interface ZLinkSerialWorkRecord<T> {
20
14
  readonly acceptedSequence: bigint;
21
15
  readonly lane: ZLinkSerialWorkLane;
22
- readonly byteCost: number;
23
16
  readonly operation: () => Promise<T> | T;
24
17
  readonly context?: unknown;
25
18
  resolve(value: T): void;
@@ -35,8 +28,7 @@ export interface ZLinkSerialWorkPreparation {
35
28
  }
36
29
  /**
37
30
  * One event-loop serial execution queue per Spot, Actor mailbox, or Stream session.
38
- * Its reservations are owner-local and span queued plus running work until the
39
- * execution owner reaches its terminal transition.
31
+ * Application work carries the host permit through the queue until the handler starts.
40
32
  */
41
33
  export declare class ZLinkSerialExecutionQueue {
42
34
  private readonly executeRecord;
@@ -44,8 +36,6 @@ export declare class ZLinkSerialExecutionQueue {
44
36
  private readonly lifecycle;
45
37
  private readonly ownerTimeBudget;
46
38
  private readonly lifecycleBurstLimit;
47
- private readonly fixedWorkByteCost;
48
- private readonly capacityError;
49
39
  private nextAcceptedSequence;
50
40
  private draining;
51
41
  private drainScheduled;
@@ -58,14 +48,12 @@ export declare class ZLinkSerialExecutionQueue {
58
48
  submit<T>(operation: () => Promise<T> | T, options?: ZLinkSerialWorkOptions, context?: unknown): Promise<T>;
59
49
  submitDetached<T>(operation: () => Promise<T> | T, onError: (error: unknown) => void, options?: ZLinkSerialWorkOptions, context?: unknown): void;
60
50
  /**
61
- * Enqueues a continuation for an already-reserved owner turn. It preserves
62
- * application FIFO order without taking a second owner-local reservation.
51
+ * Enqueues a continuation for an already-admitted owner turn.
63
52
  */
64
53
  submitContinuation<T>(operation: () => Promise<T> | T, context?: unknown): Promise<T>;
65
54
  /**
66
55
  * Enqueues work that already owns the host-wide application job permit.
67
- * Its owner-local reservation transfers from the mailbox without a second
68
- * capacity decision and remains held through handler terminal completion.
56
+ * It remains held through handler terminal completion.
69
57
  */
70
58
  submitPreAdmitted<T>(operation: () => Promise<T> | T, options?: ZLinkSerialWorkOptions, context?: unknown): Promise<T>;
71
59
  snapshot(): {
@@ -79,7 +67,6 @@ export declare class ZLinkSerialExecutionQueue {
79
67
  /** Stops new submissions while allowing the accepted FIFO to finish. */
80
68
  close(): Promise<void>;
81
69
  private admit;
82
- private byteCost;
83
70
  private scheduleDrain;
84
71
  private drain;
85
72
  private selectNext;
@@ -2,19 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkSerialExecutionQueue = exports.ZLINK_DEFAULT_SERIAL_SCHEDULER_OPTIONS = void 0;
4
4
  exports.ZLINK_DEFAULT_SERIAL_SCHEDULER_OPTIONS = Object.freeze({
5
- applicationMessageCapacity: 1_024,
6
- applicationByteCapacity: 64 * 1024 * 1024,
7
- lifecycleMessageCapacity: 128,
8
- lifecycleByteCapacity: 4 * 1024 * 1024,
9
5
  ownerTimeBudget: 10,
10
6
  lifecycleBurstLimit: 8,
11
- fixedWorkByteCost: 256
12
7
  });
13
- const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
14
8
  /**
15
9
  * One event-loop serial execution queue per Spot, Actor mailbox, or Stream session.
16
- * Its reservations are owner-local and span queued plus running work until the
17
- * execution owner reaches its terminal transition.
10
+ * Application work carries the host permit through the queue until the handler starts.
18
11
  */
19
12
  class ZLinkSerialExecutionQueue {
20
13
  executeRecord;
@@ -22,8 +15,6 @@ class ZLinkSerialExecutionQueue {
22
15
  lifecycle;
23
16
  ownerTimeBudget;
24
17
  lifecycleBurstLimit;
25
- fixedWorkByteCost;
26
- capacityError;
27
18
  nextAcceptedSequence = 1n;
28
19
  draining = false;
29
20
  drainScheduled = false;
@@ -35,20 +26,12 @@ class ZLinkSerialExecutionQueue {
35
26
  constructor(executeRecord, options = {}) {
36
27
  this.executeRecord = executeRecord;
37
28
  const configured = { ...exports.ZLINK_DEFAULT_SERIAL_SCHEDULER_OPTIONS, ...options };
38
- validatePositive(configured.applicationMessageCapacity, 'applicationMessageCapacity');
39
- validatePositive(configured.applicationByteCapacity, 'applicationByteCapacity');
40
- validatePositive(configured.lifecycleMessageCapacity, 'lifecycleMessageCapacity');
41
- validatePositive(configured.lifecycleByteCapacity, 'lifecycleByteCapacity');
42
29
  validateNonNegative(configured.ownerTimeBudget, 'ownerTimeBudget');
43
30
  validatePositive(configured.lifecycleBurstLimit, 'lifecycleBurstLimit');
44
- validatePositive(configured.fixedWorkByteCost, 'fixedWorkByteCost');
45
- this.application = createLane(configured.applicationMessageCapacity, configured.applicationByteCapacity);
46
- this.lifecycle = createLane(configured.lifecycleMessageCapacity, configured.lifecycleByteCapacity);
31
+ this.application = createLane();
32
+ this.lifecycle = createLane();
47
33
  this.ownerTimeBudget = configured.ownerTimeBudget;
48
34
  this.lifecycleBurstLimit = configured.lifecycleBurstLimit;
49
- this.fixedWorkByteCost = configured.fixedWorkByteCost;
50
- this.capacityError = options.capacityError
51
- ?? (lane => new Error(`The ${lane} execution queue is full.`));
52
35
  }
53
36
  submit(operation, options = {}, context) {
54
37
  try {
@@ -62,12 +45,11 @@ class ZLinkSerialExecutionQueue {
62
45
  void this.submit(operation, options, context).catch(onError);
63
46
  }
64
47
  /**
65
- * Enqueues a continuation for an already-reserved owner turn. It preserves
66
- * application FIFO order without taking a second owner-local reservation.
48
+ * Enqueues a continuation for an already-admitted owner turn.
67
49
  */
68
50
  submitContinuation(operation, context) {
69
51
  try {
70
- return this.admit(operation, { lane: 'application' }, context, 'none');
52
+ return this.admit(operation, { lane: 'application' }, context);
71
53
  }
72
54
  catch (error) {
73
55
  return Promise.reject(error);
@@ -75,29 +57,26 @@ class ZLinkSerialExecutionQueue {
75
57
  }
76
58
  /**
77
59
  * Atomically transfers an already-accepted durable FIFO prefix into this
78
- * owner queue. Admission failures remain synchronous so the durable owner
79
- * cannot publish a restore linearization point for a prefix that was never
80
- * queued.
60
+ * owner queue.
81
61
  *
82
62
  * @internal
83
63
  */
84
64
  admitDurablePrefix(operation, options = {}, context, preparation) {
85
- return this.admit(operation, { ...options, lane: 'application' }, context, 'transferred', preparation);
65
+ return this.admit(operation, { ...options, lane: 'application' }, context, preparation);
86
66
  }
87
67
  /**
88
68
  * Enqueues work that already owns the host-wide application job permit.
89
- * Its owner-local reservation transfers from the mailbox without a second
90
- * capacity decision and remains held through handler terminal completion.
69
+ * It remains held through handler terminal completion.
91
70
  */
92
71
  submitPreAdmitted(operation, options = {}, context) {
93
- return this.admit(operation, options, context, 'transferred');
72
+ return this.admit(operation, options, context);
94
73
  }
95
74
  snapshot() {
96
75
  return {
97
- applicationMessages: this.application.messageCount,
98
- applicationBytes: this.application.byteCount,
99
- lifecycleMessages: this.lifecycle.messageCount,
100
- lifecycleBytes: this.lifecycle.byteCount
76
+ applicationMessages: this.application.records.length,
77
+ applicationBytes: 0,
78
+ lifecycleMessages: this.lifecycle.records.length,
79
+ lifecycleBytes: 0
101
80
  };
102
81
  }
103
82
  get hasPendingWork() {
@@ -115,18 +94,11 @@ class ZLinkSerialExecutionQueue {
115
94
  this.closed = true;
116
95
  return this.whenIdle();
117
96
  }
118
- admit(operation, options, context, reservationMode = 'enforce-capacity', preparation) {
97
+ admit(operation, options, context, preparation) {
119
98
  if (this.closed)
120
99
  throw new Error('The serial execution queue is closed.');
121
100
  const lane = options.lane ?? 'application';
122
- const reservationHeld = reservationMode !== 'none';
123
- const byteCost = reservationHeld ? this.byteCost(options) : 0;
124
101
  const target = lane === 'application' ? this.application : this.lifecycle;
125
- if (reservationMode === 'enforce-capacity' && !reserve(target, byteCost)) {
126
- throw this.capacityError(lane);
127
- }
128
- if (reservationMode === 'transferred')
129
- reserveTransferred(target, byteCost);
130
102
  let settled = false;
131
103
  let released = false;
132
104
  let resolveResult;
@@ -139,8 +111,6 @@ class ZLinkSerialExecutionQueue {
139
111
  if (released)
140
112
  return;
141
113
  released = true;
142
- if (reservationHeld)
143
- releaseReservation(target, byteCost);
144
114
  };
145
115
  const resolve = (value) => {
146
116
  if (settled)
@@ -157,7 +127,6 @@ class ZLinkSerialExecutionQueue {
157
127
  const record = {
158
128
  acceptedSequence: 0n,
159
129
  lane,
160
- byteCost,
161
130
  operation,
162
131
  context,
163
132
  preparation,
@@ -185,18 +154,6 @@ class ZLinkSerialExecutionQueue {
185
154
  this.scheduleDrain();
186
155
  return result;
187
156
  }
188
- byteCost(options) {
189
- const payloadBytes = options.payloadBytes ?? 0;
190
- const metadataBytes = options.metadataBytes ?? 0;
191
- validateNonNegative(payloadBytes, 'payloadBytes');
192
- validateNonNegative(metadataBytes, 'metadataBytes');
193
- if (payloadBytes > MAX_SAFE_INTEGER - metadataBytes)
194
- return MAX_SAFE_INTEGER;
195
- const payloadAndMetadata = payloadBytes + metadataBytes;
196
- return payloadAndMetadata > MAX_SAFE_INTEGER - this.fixedWorkByteCost
197
- ? MAX_SAFE_INTEGER
198
- : payloadAndMetadata + this.fixedWorkByteCost;
199
- }
200
157
  scheduleDrain() {
201
158
  if (this.drainScheduled || this.draining)
202
159
  return;
@@ -370,32 +327,11 @@ class ZLinkSerialExecutionQueue {
370
327
  }
371
328
  }
372
329
  exports.ZLinkSerialExecutionQueue = ZLinkSerialExecutionQueue;
373
- function createLane(messageCapacity, byteCapacity) {
330
+ function createLane() {
374
331
  return {
375
- records: [],
376
- messageCapacity,
377
- byteCapacity,
378
- messageCount: 0,
379
- byteCount: 0
332
+ records: []
380
333
  };
381
334
  }
382
- function reserve(lane, byteCost) {
383
- if (lane.messageCount >= lane.messageCapacity
384
- || byteCost > lane.byteCapacity - lane.byteCount) {
385
- return false;
386
- }
387
- lane.messageCount += 1;
388
- lane.byteCount += byteCost;
389
- return true;
390
- }
391
- function reserveTransferred(lane, byteCost) {
392
- lane.messageCount += 1;
393
- lane.byteCount += byteCost;
394
- }
395
- function releaseReservation(lane, byteCost) {
396
- lane.messageCount -= 1;
397
- lane.byteCount -= byteCost;
398
- }
399
335
  function validatePositive(value, field) {
400
336
  if (!Number.isSafeInteger(value) || value < 1) {
401
337
  throw new RangeError(`${field} must be a positive safe integer.`);
@@ -11,8 +11,6 @@ export declare class EventLoopResourceStack {
11
11
  export type EventLoopTask = () => void | Promise<void>;
12
12
  /** Keeps infrastructure progress independent from awaiting application handlers. */
13
13
  export declare class EventLoopWorkQueues {
14
- private readonly infrastructureLimit;
15
- private readonly applicationLimit;
16
14
  private readonly infrastructure;
17
15
  private infrastructureHead;
18
16
  private infrastructureCount;
@@ -22,7 +20,6 @@ export declare class EventLoopWorkQueues {
22
20
  private infrastructureScheduled;
23
21
  private applicationScheduled;
24
22
  private accepting;
25
- constructor(infrastructureLimit: number, applicationLimit: number);
26
23
  submitInfrastructure(task: EventLoopTask): boolean;
27
24
  submitApplication(task: EventLoopTask): boolean;
28
25
  stopAdmission(): void;
@@ -37,8 +37,6 @@ async function closeResources(resources) {
37
37
  }
38
38
  /** Keeps infrastructure progress independent from awaiting application handlers. */
39
39
  class EventLoopWorkQueues {
40
- infrastructureLimit;
41
- applicationLimit;
42
40
  infrastructure = [];
43
41
  infrastructureHead = 0;
44
42
  infrastructureCount = 0;
@@ -48,15 +46,8 @@ class EventLoopWorkQueues {
48
46
  infrastructureScheduled = false;
49
47
  applicationScheduled = false;
50
48
  accepting = true;
51
- constructor(infrastructureLimit, applicationLimit) {
52
- this.infrastructureLimit = infrastructureLimit;
53
- this.applicationLimit = applicationLimit;
54
- if (infrastructureLimit < 1 || applicationLimit < 1) {
55
- throw new RangeError('Queue limits must be positive.');
56
- }
57
- }
58
49
  submitInfrastructure(task) {
59
- if (!this.accepting || this.infrastructureCount >= this.infrastructureLimit)
50
+ if (!this.accepting)
60
51
  return false;
61
52
  this.infrastructure.push(task);
62
53
  this.infrastructureCount += 1;
@@ -64,7 +55,7 @@ class EventLoopWorkQueues {
64
55
  return true;
65
56
  }
66
57
  submitApplication(task) {
67
- if (!this.accepting || this.applicationCount >= this.applicationLimit)
58
+ if (!this.accepting)
68
59
  return false;
69
60
  this.application.push(task);
70
61
  this.applicationCount += 1;
@@ -10,10 +10,6 @@ export declare class OperationCancelledError extends Error {
10
10
  readonly operationId: bigint;
11
11
  constructor(operationId: bigint, message?: string);
12
12
  }
13
- export declare class OperationCapacityExceededError extends Error {
14
- readonly maxPendingOperations: number;
15
- constructor(maxPendingOperations: number);
16
- }
17
13
  export interface PendingOperation<T> {
18
14
  readonly id: bigint;
19
15
  readonly promise: Promise<T>;
@@ -21,14 +17,12 @@ export interface PendingOperation<T> {
21
17
  /** Owns request completion so reply, timeout, cancellation, and shutdown race safely. */
22
18
  export declare class OperationRegistry<T> {
23
19
  private readonly clock;
24
- private readonly maxPendingOperations;
25
- static readonly DEFAULT_MAX_PENDING_OPERATIONS = 4096;
26
20
  private readonly entries;
27
21
  private nextId;
28
22
  private generation;
29
23
  private closed;
30
- constructor(clock?: OperationClock, maxPendingOperations?: number);
31
- reserve(timeoutMs: number, timeoutOwner?: 'registry' | 'sender'): PendingOperation<T>;
24
+ constructor(clock?: OperationClock);
25
+ register(timeoutMs: number, timeoutOwner?: 'registry' | 'sender'): PendingOperation<T>;
32
26
  complete(id: bigint, value: T): boolean;
33
27
  fail(id: bigint, reason: unknown): boolean;
34
28
  private failCore;