@zlink-systems/framework 0.29.0 → 0.30.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 (168) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  3. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  4. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  5. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  6. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  7. package/dist/contracts/Configuration/index.d.ts +1 -1
  8. package/dist/internal.d.ts +1 -0
  9. package/dist/internal.js +3 -1
  10. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  11. package/dist/runtime/actors/actor-handoff.js +9 -4
  12. package/dist/runtime/actors/actor-runtime-contracts.d.ts +1 -0
  13. package/dist/runtime/actors/index.d.ts +2 -0
  14. package/dist/runtime/actors/index.js +21 -6
  15. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +3 -1
  16. package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
  17. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
  18. package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
  19. package/dist/runtime/application-jobs/contracts.d.ts +5 -1
  20. package/dist/runtime/backend/contracts/index.d.ts +10 -19
  21. package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
  22. package/dist/runtime/backend/mesh-completion-table.js +28 -18
  23. package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
  24. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  25. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  26. package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
  27. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  28. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  29. package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
  30. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
  31. package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
  32. package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
  33. package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
  34. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  35. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  36. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  37. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  38. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  39. package/dist/runtime/diagnostics/message-flow.js +3 -3
  40. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
  41. package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
  42. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  43. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  44. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  45. package/dist/runtime/foundation/service-mailbox.js +2 -1
  46. package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
  47. package/dist/runtime/foundation/service-stateful-runtime.js +60 -41
  48. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
  49. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  50. package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
  51. package/dist/runtime/foundation/service-topology-registry.js +9 -4
  52. package/dist/runtime/handlers/handler-instance-scope.js +1 -1
  53. package/dist/runtime/host/actor-packet-relay.js +7 -7
  54. package/dist/runtime/host/actor-placement-coordinator.d.ts +2 -1
  55. package/dist/runtime/host/actor-placement-coordinator.js +2 -1
  56. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -1
  57. package/dist/runtime/host/actor-runtime-options-factory.js +2 -1
  58. package/dist/runtime/host/application-job-queue.d.ts +11 -4
  59. package/dist/runtime/host/application-job-queue.js +66 -10
  60. package/dist/runtime/host/entry-actor-runtime.js +1 -1
  61. package/dist/runtime/host/index.d.ts +1 -1
  62. package/dist/runtime/host/index.js +18 -13
  63. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  64. package/dist/runtime/host/instance-activation-authority.js +89 -25
  65. package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
  66. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  67. package/dist/runtime/host/spot-address-transport.js +25 -12
  68. package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
  69. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  70. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  71. package/dist/runtime/locations/domain-store-contract.d.ts +3 -2
  72. package/dist/runtime/locations/in-memory-authority-store.d.ts +5 -2
  73. package/dist/runtime/locations/in-memory-authority-store.js +107 -14
  74. package/dist/runtime/locations/in-memory-location-store.d.ts +3 -3
  75. package/dist/runtime/locations/in-memory-location-store.js +31 -13
  76. package/dist/runtime/locations/internal-location-contracts.d.ts +8 -0
  77. package/dist/runtime/locations/location-store-repository.d.ts +4 -2
  78. package/dist/runtime/locations/location-store-repository.js +209 -33
  79. package/dist/runtime/locations/resolvers.d.ts +2 -1
  80. package/dist/runtime/locations/resolvers.js +10 -1
  81. package/dist/runtime/messaging/submission-result.d.ts +1 -1
  82. package/dist/runtime/messaging/submission-result.js +2 -2
  83. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
  84. package/dist/runtime/spots/index.d.ts +4 -3
  85. package/dist/runtime/spots/index.js +14 -14
  86. package/dist/runtime/spots/spot-activation.d.ts +2 -1
  87. package/dist/runtime/spots/spot-activation.js +4 -4
  88. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  89. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  90. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  91. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  92. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  93. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  94. package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
  95. package/dist/runtime/spots/spot-entry-activation.js +6 -1
  96. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +3 -1
  97. package/dist/runtime/spots/spot-node-runtime-manager.js +10 -11
  98. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  99. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
  100. package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
  101. package/dist/runtime/spots/spot-serial-executor.js +10 -1
  102. package/dist/runtime/streams/stream-session-runtime.js +1 -1
  103. package/package.json +3 -3
  104. package/src/contracts/Configuration/Builders.ts +1 -2
  105. package/src/contracts/Configuration/Configs.ts +0 -6
  106. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  107. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  108. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  109. package/src/contracts/Configuration/index.ts +1 -6
  110. package/src/internal.ts +1 -0
  111. package/src/runtime/actors/actor-handoff.ts +13 -4
  112. package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
  113. package/src/runtime/actors/index.ts +77 -42
  114. package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
  115. package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
  116. package/src/runtime/application-jobs/contracts.ts +14 -1
  117. package/src/runtime/backend/contracts/index.ts +10 -18
  118. package/src/runtime/backend/mesh-completion-table.ts +36 -19
  119. package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
  120. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  121. package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
  122. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  123. package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
  124. package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
  125. package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
  126. package/src/runtime/backend/raw-binding-port.ts +12 -2
  127. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  128. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  129. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  130. package/src/runtime/diagnostics/message-flow.ts +1 -1
  131. package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
  132. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  133. package/src/runtime/foundation/service-mailbox.ts +7 -1
  134. package/src/runtime/foundation/service-stateful-runtime.ts +109 -77
  135. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
  136. package/src/runtime/foundation/service-topology-registry.ts +13 -7
  137. package/src/runtime/handlers/handler-instance-scope.ts +2 -1
  138. package/src/runtime/host/actor-packet-relay.ts +7 -0
  139. package/src/runtime/host/actor-placement-coordinator.ts +8 -2
  140. package/src/runtime/host/actor-runtime-options-factory.ts +7 -0
  141. package/src/runtime/host/application-job-queue.ts +77 -10
  142. package/src/runtime/host/entry-actor-runtime.ts +1 -0
  143. package/src/runtime/host/index.ts +30 -7
  144. package/src/runtime/host/instance-activation-authority.ts +132 -27
  145. package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
  146. package/src/runtime/host/spot-address-transport.ts +45 -22
  147. package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
  148. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  149. package/src/runtime/locations/domain-store-contract.ts +6 -2
  150. package/src/runtime/locations/in-memory-authority-store.ts +153 -12
  151. package/src/runtime/locations/in-memory-location-store.ts +39 -13
  152. package/src/runtime/locations/internal-location-contracts.ts +10 -0
  153. package/src/runtime/locations/location-store-repository.ts +295 -36
  154. package/src/runtime/locations/resolvers.ts +25 -2
  155. package/src/runtime/messaging/submission-result.ts +2 -2
  156. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
  157. package/src/runtime/spots/index.ts +16 -0
  158. package/src/runtime/spots/spot-activation.ts +5 -0
  159. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  160. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  161. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  162. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  163. package/src/runtime/spots/spot-entry-activation.ts +7 -0
  164. package/src/runtime/spots/spot-node-runtime-manager.ts +14 -12
  165. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  166. package/src/runtime/spots/spot-runtime-ports.ts +2 -0
  167. package/src/runtime/spots/spot-serial-executor.ts +10 -4
  168. package/src/runtime/streams/stream-session-runtime.ts +1 -1
@@ -12,7 +12,6 @@ const EndpointNotation_1 = require("../../../contracts/Configuration/EndpointNot
12
12
  const InternalDefaults_1 = require("../../../contracts/Configuration/InternalDefaults");
13
13
  const Registration_1 = require("../../../contracts/Configuration/Registration");
14
14
  const RegistrationBuilderPolicy_1 = require("../../../contracts/Configuration/RegistrationBuilderPolicy");
15
- const admission_1 = require("../../admission");
16
15
  const operation_identity_1 = require("../../foundation/operation-identity");
17
16
  const operation_registry_1 = require("../../foundation/operation-registry");
18
17
  const raw_service_mesh_runtime_1 = require("../../foundation/raw-service-mesh-runtime");
@@ -58,12 +57,11 @@ class ZLinkNodeRawMeshBackend {
58
57
  applicationJobQueue;
59
58
  applicationJobReceiveFlowFailureSink;
60
59
  peerAdmissionSealed;
60
+ infrastructureTaskRunner;
61
61
  nativeInstance = this;
62
62
  channels = new Map();
63
63
  peerIntents = new Map();
64
- completions = [];
65
- completionHead = 0;
66
- completionCount = 0;
64
+ completionHandler;
67
65
  routingId;
68
66
  lifecycleGeneration;
69
67
  bindEndpoint;
@@ -107,12 +105,13 @@ class ZLinkNodeRawMeshBackend {
107
105
  messageFollowHandler;
108
106
  dispatchErrors;
109
107
  peerDisconnectedHandlers = new Set();
110
- constructor(meshName, routingId, bindingPort, applicationJobQueue, applicationJobReceiveFlowFailureSink, peerAdmissionSealed) {
108
+ constructor(meshName, routingId, bindingPort, applicationJobQueue, applicationJobReceiveFlowFailureSink, peerAdmissionSealed, infrastructureTaskRunner) {
111
109
  this.meshName = meshName;
112
110
  this.bindingPort = bindingPort;
113
111
  this.applicationJobQueue = applicationJobQueue;
114
112
  this.applicationJobReceiveFlowFailureSink = applicationJobReceiveFlowFailureSink;
115
113
  this.peerAdmissionSealed = peerAdmissionSealed;
114
+ this.infrastructureTaskRunner = infrastructureTaskRunner;
116
115
  if (meshName.length === 0)
117
116
  throw new TypeError('MeshName must be non-empty.');
118
117
  if (routingId === undefined || routingId.length === 0) {
@@ -203,6 +202,8 @@ class ZLinkNodeRawMeshBackend {
203
202
  resolveAdvertisedEndpoint: (boundEndpoint) => this.resolveAdvertisedEndpoint(boundEndpoint),
204
203
  bindingPort: this.bindingPort,
205
204
  applicationJobQueue: this.requireApplicationJobQueue(),
205
+ onReceiveReady: () => this.onReadable(true, false),
206
+ infrastructureTaskRunner: this.infrastructureTaskRunner,
206
207
  peerAdmissionSealed: this.peerAdmissionSealed,
207
208
  onReceiveFlowConfigFailure: this.applicationJobReceiveFlowFailureSink,
208
209
  onMailboxReady: (domain) => this.readyHandler?.(domain === 'application' ? service_runtime_contracts_1.ReadyDomain.Application : service_runtime_contracts_1.ReadyDomain.Infrastructure),
@@ -275,7 +276,6 @@ class ZLinkNodeRawMeshBackend {
275
276
  this.stateful = undefined;
276
277
  this.runtime?.close();
277
278
  this.runtime = undefined;
278
- this.clearCompletions();
279
279
  this.closed = true;
280
280
  }
281
281
  addChannelName(name) {
@@ -426,7 +426,7 @@ class ZLinkNodeRawMeshBackend {
426
426
  admittedPeerCount: peers.length,
427
427
  drainingPeerCount: peers.filter((peer) => peer.descriptor.state === 'draining').length,
428
428
  pendingApplicationMessages: BigInt(this.runtime?.mailbox.pendingMessages('application') ?? 0),
429
- pendingInfrastructureMessages: BigInt((this.runtime?.mailbox.pendingMessages('infrastructure') ?? 0) + this.completionCount),
429
+ pendingInfrastructureMessages: BigInt(this.runtime?.mailbox.pendingMessages('infrastructure') ?? 0),
430
430
  pendingBytes: BigInt((this.runtime?.mailbox.pendingBytes('application') ?? 0) +
431
431
  (this.runtime?.mailbox.pendingBytes('infrastructure') ?? 0)),
432
432
  lastError: 0,
@@ -519,6 +519,9 @@ class ZLinkNodeRawMeshBackend {
519
519
  }
520
520
  };
521
521
  }
522
+ setCompletionHandler(handler) {
523
+ this.completionHandler = handler;
524
+ }
522
525
  setReadyHandler(handler) {
523
526
  this.readyHandler = handler;
524
527
  this.notifyReady();
@@ -532,7 +535,6 @@ class ZLinkNodeRawMeshBackend {
532
535
  drainReady(domains, batch) {
533
536
  const target = requireRawReadyBatch(batch);
534
537
  if ((domains & service_runtime_contracts_1.ReadyDomain.Infrastructure) !== 0) {
535
- this.drainCompletions(target);
536
538
  this.drainMailbox('infrastructure', target);
537
539
  }
538
540
  if ((domains & service_runtime_contracts_1.ReadyDomain.Application) !== 0) {
@@ -540,7 +542,7 @@ class ZLinkNodeRawMeshBackend {
540
542
  }
541
543
  const runtime = this.runtime;
542
544
  const infrastructureResidue = (domains & service_runtime_contracts_1.ReadyDomain.Infrastructure) !== 0 &&
543
- (this.completionCount > 0 || (runtime?.mailbox.pendingMessages('infrastructure') ?? 0) > 0);
545
+ (runtime?.mailbox.pendingMessages('infrastructure') ?? 0) > 0;
544
546
  const applicationResidue = (domains & service_runtime_contracts_1.ReadyDomain.Application) !== 0 &&
545
547
  (runtime?.mailbox.pendingMessages('application') ?? 0) > 0;
546
548
  return {
@@ -719,7 +721,7 @@ class ZLinkNodeRawMeshBackend {
719
721
  closeActorBoundSession(actor, expectedBindingGeneration, timeoutMs = Registration_1.DEFAULT_REQUEST_TIMEOUT_MS) {
720
722
  const binding = this.requireStateful().registry.binding(actor);
721
723
  if (binding === undefined) {
722
- return this.enqueueImmediateFailure(service_runtime_contracts_1.OperationKind.StreamUnbind, zlink_1.RequestResult.NotFound);
724
+ return this.observeImmediateFailure(service_runtime_contracts_1.OperationKind.StreamUnbind, zlink_1.RequestResult.NotFound);
723
725
  }
724
726
  return this.observeStateful(service_runtime_contracts_1.OperationKind.StreamUnbind, this.requireStateful().unbindSession(binding.sessionRid, actor, expectedBindingGeneration, timeoutMs));
725
727
  }
@@ -824,7 +826,7 @@ class ZLinkNodeRawMeshBackend {
824
826
  notifyReady() {
825
827
  const runtime = this.runtime;
826
828
  let domains = service_runtime_contracts_1.ReadyDomain.None;
827
- if (this.completionCount > 0 || (runtime?.mailbox.pendingMessages('infrastructure') ?? 0) > 0) {
829
+ if ((runtime?.mailbox.pendingMessages('infrastructure') ?? 0) > 0) {
828
830
  domains |= service_runtime_contracts_1.ReadyDomain.Infrastructure;
829
831
  }
830
832
  if ((runtime?.mailbox.pendingMessages('application') ?? 0) > 0) {
@@ -835,61 +837,31 @@ class ZLinkNodeRawMeshBackend {
835
837
  }
836
838
  observeCompletion(low, operationKind, promise) {
837
839
  const id = { high: 1n, low };
838
- void promise.then((result) => this.enqueueCompletion(id, operationKind, result), (error) => this.enqueueCompletion(id, operationKind, requestFailureResult(error)));
840
+ void promise.then((result) => this.deliverCompletion(id, operationKind, result), (error) => this.deliverCompletion(id, operationKind, requestFailureResult(error)));
839
841
  return id;
840
842
  }
841
843
  observeStateful(operationKind, pending) {
842
844
  const id = { high: operation_identity_1.ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE, low: pending.id };
843
- void pending.promise.then((result) => this.enqueueCompletion(id, operationKind, result), (error) => this.enqueueCompletion(id, operationKind, requestFailureResult(error)));
845
+ void pending.promise.then((result) => this.deliverCompletion(id, operationKind, result), (error) => this.deliverCompletion(id, operationKind, requestFailureResult(error)));
844
846
  return id;
845
847
  }
846
- enqueueImmediateFailure(operationKind, terminalResult) {
848
+ observeImmediateFailure(operationKind, terminalResult) {
847
849
  const low = this.nextPeerIntent++;
848
- const id = { high: 1n, low };
849
- this.enqueueCompletion(id, operationKind, { terminalResult, failureCode: 0 });
850
- return id;
850
+ return this.observeCompletion(low, operationKind, Promise.resolve({ terminalResult, failureCode: 0 }));
851
851
  }
852
- enqueueCompletion(operationId, operationKind, result) {
853
- if (this.closed)
852
+ deliverCompletion(operationId, operationKind, result) {
853
+ if (this.completionHandler !== undefined) {
854
+ this.completionHandler({ operationId, terminalResult: result.terminalResult }, () => completionRecord(operationId, operationKind, result));
854
855
  return;
855
- this.completions.push({ operationId, operationKind, result });
856
- this.completionCount += 1;
857
- this.readyHandler?.(service_runtime_contracts_1.ReadyDomain.Infrastructure);
858
- }
859
- drainCompletions(batch) {
860
- while (!batch.full && this.completionCount > 0) {
861
- const completion = this.takeCompletion();
862
- if (completion === undefined)
863
- continue;
864
- batch.push({
865
- ownerKind: service_runtime_contracts_1.ReadyOwnerKind.Node,
866
- domain: service_runtime_contracts_1.ReadyDomain.Infrastructure,
867
- spotId: null,
868
- actor: null,
869
- terminalCompletion: true
870
- }, new CompletionClaim(completion));
871
856
  }
872
- }
873
- takeCompletion() {
874
- const completion = this.completions[this.completionHead];
875
- if (completion === undefined)
876
- return undefined;
877
- this.completions[this.completionHead] = undefined;
878
- this.completionHead += 1;
879
- this.completionCount -= 1;
880
- if (this.completionCount === 0) {
881
- this.clearCompletions();
882
- }
883
- else if ((0, admission_1.shouldCompactBackingArray)(this.completionHead, this.completions.length)) {
884
- this.completions.splice(0, this.completionHead);
885
- this.completionHead = 0;
886
- }
887
- return completion;
888
- }
889
- clearCompletions() {
890
- this.completions.length = 0;
891
- this.completionHead = 0;
892
- this.completionCount = 0;
857
+ // The raw pull contract uses the existing infrastructure mailbox. A
858
+ // registered Framework owner receives the terminal directly above.
859
+ this.runtime?.mailbox.tryEnqueue({
860
+ owner: this.routingId,
861
+ domain: 'infrastructure',
862
+ parts: [],
863
+ completion: completionRecord(operationId, operationKind, result)
864
+ });
893
865
  }
894
866
  drainMailbox(domain, batch) {
895
867
  const runtime = this.runtime;
@@ -899,7 +871,15 @@ class ZLinkNodeRawMeshBackend {
899
871
  const claim = runtime.mailbox.tryClaim(domain, MAX_DRAIN_RECORDS, Number.MAX_SAFE_INTEGER);
900
872
  if (claim === undefined)
901
873
  break;
902
- const owner = readyOwner(claim.owner, this.routingId, this.stateful, domain);
874
+ const owner = claim.records[0]?.completion === undefined
875
+ ? readyOwner(claim.owner, this.routingId, this.stateful, domain)
876
+ : {
877
+ ownerKind: service_runtime_contracts_1.ReadyOwnerKind.Node,
878
+ domain: service_runtime_contracts_1.ReadyDomain.Infrastructure,
879
+ spotId: null,
880
+ actor: null,
881
+ terminalCompletion: true
882
+ };
903
883
  batch.push(owner, new MailboxClaim(runtime, claim));
904
884
  }
905
885
  }
@@ -1259,49 +1239,35 @@ class MailboxClaim {
1259
1239
  this.runtime.mailbox.release(this.claim, this.remaining);
1260
1240
  }
1261
1241
  }
1262
- class CompletionClaim {
1263
- completion;
1264
- consumed = false;
1265
- constructor(completion) {
1266
- this.completion = completion;
1267
- }
1268
- recvBatch() {
1269
- if (this.consumed)
1270
- return { ok: false, records: [] };
1271
- this.consumed = true;
1272
- const payload = this.completion.result.payload;
1273
- return {
1274
- ok: true,
1275
- records: [
1276
- {
1277
- kind: service_runtime_contracts_1.ReceiveKind.Completion,
1278
- domain: service_runtime_contracts_1.ReadyDomain.Infrastructure,
1279
- sourceNodeRid: null,
1280
- sourceSpotId: null,
1281
- sourceBindingGeneration: 0n,
1282
- sourceActor: null,
1283
- operationId: this.completion.operationId,
1284
- operationKind: this.completion.operationKind,
1285
- channelName: null,
1286
- topic: null,
1287
- applicationMetadata: null,
1288
- kindData: 'kindData' in this.completion.result ? (this.completion.result.kindData ?? null) : null,
1289
- terminalResult: this.completion.result.terminalResult,
1290
- failureErrno: this.completion.result.failureCode,
1291
- parts: payload === undefined
1292
- ? []
1293
- : payload.contentType === MULTIPART_CONTENT_TYPE
1294
- ? decodeMultipart(payload.payload)
1295
- : [zlink_1.Message.from(payload.payload)],
1296
- reply: () => zlink_1.SubmitResult.InvalidState,
1297
- replyActorJoin: () => zlink_1.SubmitResult.NotSupported
1298
- }
1299
- ]
1300
- };
1301
- }
1302
- release() { }
1242
+ function completionRecord(operationId, operationKind, result) {
1243
+ const payload = result.payload;
1244
+ return {
1245
+ kind: service_runtime_contracts_1.ReceiveKind.Completion,
1246
+ domain: service_runtime_contracts_1.ReadyDomain.Infrastructure,
1247
+ sourceNodeRid: null,
1248
+ sourceSpotId: null,
1249
+ sourceBindingGeneration: 0n,
1250
+ sourceActor: null,
1251
+ operationId,
1252
+ operationKind,
1253
+ channelName: null,
1254
+ topic: null,
1255
+ applicationMetadata: null,
1256
+ kindData: 'kindData' in result ? (result.kindData ?? null) : null,
1257
+ terminalResult: result.terminalResult,
1258
+ failureErrno: result.failureCode,
1259
+ parts: payload === undefined
1260
+ ? []
1261
+ : payload.contentType === MULTIPART_CONTENT_TYPE
1262
+ ? decodeMultipart(payload.payload)
1263
+ : [runtime_message_1.ZLinkBufferMessage.from(payload.payload)],
1264
+ reply: () => zlink_1.SubmitResult.InvalidState,
1265
+ replyActorJoin: () => zlink_1.SubmitResult.NotSupported
1266
+ };
1303
1267
  }
1304
1268
  function decodeMultipartRecord(runtime, record) {
1269
+ if (record.completion !== undefined)
1270
+ return record.completion;
1305
1271
  const stateful = (0, service_stateful_runtime_1.statefulMailboxData)(record);
1306
1272
  if (stateful !== undefined) {
1307
1273
  return decodeStatefulRecord(record, stateful);
@@ -10,6 +10,8 @@ const node_event_loop_poller_1 = require("./node-event-loop-poller");
10
10
  const eventLoopPollers = new WeakMap();
11
11
  function wrapSocket(nativeInstance, pollCompletion) {
12
12
  const socket = nativeInstance;
13
+ if (socket.options !== undefined)
14
+ socket.options.linger = 0;
13
15
  const hasRequest = typeof nativeInstance.request === 'function';
14
16
  const hasRoutedPeer = hasRequest && typeof nativeInstance.reply === 'function';
15
17
  const hasStream = typeof nativeInstance.recvPacket === 'function';
@@ -18,9 +20,9 @@ function wrapSocket(nativeInstance, pollCompletion) {
18
20
  : new node_event_loop_poller_1.ZLinkNodeEventLoopPoller(nativeInstance, pollCompletion, () => { });
19
21
  const adapter = {
20
22
  nativeInstance,
23
+ receiveAdmission: undefined,
21
24
  async dispose() {
22
25
  eventLoopPoller?.dispose();
23
- (0, node_backend_adapter_support_1.disableSocketLinger)(nativeInstance);
24
26
  (0, node_backend_adapter_support_1.closeBindingHandle)(nativeInstance);
25
27
  },
26
28
  close() {
@@ -44,9 +46,6 @@ function wrapSocket(nativeInstance, pollCompletion) {
44
46
  .setChannelName;
45
47
  setChannelName?.call(nativeInstance, channelName);
46
48
  },
47
- setReceiveFlowState(state) {
48
- nativeInstance.setReceiveFlowState(state);
49
- },
50
49
  setProbe(enabled) {
51
50
  requireSocketOptions(socket).probe = enabled;
52
51
  },
@@ -68,6 +67,12 @@ function wrapSocket(nativeInstance, pollCompletion) {
68
67
  setRoutingId(routingId) {
69
68
  nativeInstance.setRoutingId((0, node_backend_adapter_support_1.toNativeRoutingId)(routingId));
70
69
  },
70
+ get lingerMs() {
71
+ return requireSocketOptions(socket).linger;
72
+ },
73
+ set lingerMs(value) {
74
+ requireSocketOptions(socket).linger = value;
75
+ },
71
76
  get peerWeight() {
72
77
  return socket.options?.peerWeight ?? RegistrationBuilderPolicy_1.ZLINK_DEFAULT_PUBLIC_WEIGHT;
73
78
  },
@@ -144,7 +149,7 @@ function wrapSocket(nativeInstance, pollCompletion) {
144
149
  }
145
150
  if (hasRequest) {
146
151
  const [payload, timeoutMs] = args;
147
- return (0, node_backend_adapter_support_1.submitBindingRequest)(nativeInstance.request(), payload, timeoutMs);
152
+ return (0, node_backend_adapter_support_1.submitBindingRequest)(nativeInstance.request(), payload, timeoutMs, adapter.receiveAdmission?.recordReceived);
148
153
  }
149
154
  throw new TypeError('Backend request requires a DEALER or ROUTER socket.');
150
155
  },
@@ -1,3 +1,8 @@
1
+ import type { SubmitResult } from './runtime-values';
2
+ export interface ZLinkRawSendSubmission {
3
+ readonly result: typeof SubmitResult.Ok | typeof SubmitResult.Backpressured;
4
+ readonly admitted: Promise<void>;
5
+ }
1
6
  export interface ZLinkRawReceivedRecord {
2
7
  readonly sourceRid: string;
3
8
  readonly sourceRoute: Uint8Array;
@@ -29,7 +34,6 @@ export interface ZLinkRawSocketPort {
29
34
  unbind(endpoint: string): void;
30
35
  connect(endpoint: string): void;
31
36
  disconnect(endpoint: string): void;
32
- setReceiveFlowState(state: 'running' | 'paused'): void;
33
37
  monitor(): ZLinkRawMonitorPort;
34
38
  close(): void;
35
39
  }
@@ -44,12 +48,15 @@ export interface ZLinkRawRouterRoute {
44
48
  readonly routeGeneration: bigint;
45
49
  }
46
50
  export interface ZLinkRawRouterPort extends ZLinkRawSocketPort {
51
+ setReceiveFlowState(state: 'running' | 'paused'): void;
52
+ /** Reports Core submit synchronously; admitted observes only pending admission. */
53
+ submitSend(targetRid: string, parts: readonly Uint8Array[]): ZLinkRawSendSubmission;
47
54
  disconnectRid?(routingId: string): void;
48
55
  localEndpoint(): string;
49
56
  setRoutingId(routingId: string): void;
50
57
  connectToRoutingId(routingId: string, endpoint: string): void;
51
58
  send(targetRid: string, parts: readonly Uint8Array[]): Promise<void>;
52
- request(targetRid: string, parts: readonly Uint8Array[], timeoutMs: number): Promise<readonly Buffer[]>;
59
+ request(targetRid: string, parts: readonly Uint8Array[], timeoutMs: number, recordReceived?: () => void): Promise<readonly Buffer[]>;
53
60
  receive(dontWait?: boolean): ZLinkRawReceivedRecord | undefined;
54
61
  /** The selected route of every RID. The socket's one route observer calls it. */
55
62
  routesSnapshot(): readonly ZLinkRawRouterRoute[];
@@ -258,7 +258,7 @@ class ZLinkChannelReceiveLoop {
258
258
  }
259
259
  async acquirePermit(signal) {
260
260
  try {
261
- return await this.applicationJobQueue.acquire(signal);
261
+ return await this.applicationJobQueue.acquire(signal, 'remote');
262
262
  }
263
263
  catch (error) {
264
264
  if (this.isStopped() || signal.aborted)
@@ -448,7 +448,7 @@ class ZLinkSubscriberReceiveLoop {
448
448
  }
449
449
  async acquirePermit(signal) {
450
450
  try {
451
- return await this.applicationJobQueue.acquire(signal);
451
+ return await this.applicationJobQueue.acquire(signal, 'remote');
452
452
  }
453
453
  catch (error) {
454
454
  if (this.isStopped() || signal.aborted)
@@ -640,7 +640,7 @@ class ZLinkRouteReceiveLoop {
640
640
  }
641
641
  async acquirePermit(signal) {
642
642
  try {
643
- return await this.applicationJobQueue.acquire(signal);
643
+ return await this.applicationJobQueue.acquire(signal, 'remote');
644
644
  }
645
645
  catch (error) {
646
646
  if (this.isStopped() || signal.aborted)
@@ -332,7 +332,8 @@ class ZLinkChannelRuntimeLifecycle {
332
332
  unhandled: this.options.registration.dispatch?.unhandled
333
333
  });
334
334
  const spotRouteBridge = this.createSpotRouteBridgeForRouter(channelName, router);
335
- const loop = new channel_receive_loops_1.ZLinkChannelReceiveLoop(channelName, router, dispatcher, spotRouteBridge, (received, socket) => this.options.sockets.tryHandleClientServerControl(channelName, received, socket), this.options.adapter.createReadablePoller(router), this.options.applicationJobQueue, (error) => taskRunner.errorSink.reportRuntimeTaskException(`channel:${channelName}:dispatch`, error), this.receiveRoundRobin, this.applicationDispatchQueue(channelName));
335
+ const serverPeers = this.options.sockets.clientServerServerPeersForChannel(channelName);
336
+ const loop = new channel_receive_loops_1.ZLinkChannelReceiveLoop(channelName, router, dispatcher, spotRouteBridge, (received, socket) => this.options.sockets.tryHandleClientServerControl(channelName, received, socket, serverPeers), this.options.adapter.createReadablePoller(router), this.options.applicationJobQueue, (error) => taskRunner.errorSink.reportRuntimeTaskException(`channel:${channelName}:dispatch`, error), this.receiveRoundRobin, this.applicationDispatchQueue(channelName));
336
337
  this.channelReceiveLoops.push(loop);
337
338
  tasks.push(taskRunner.run(`channel:${channelName}`, (signal) => loop.run(signal)));
338
339
  }
@@ -1,9 +1,10 @@
1
- import { type ZLinkClientServerServerDescriptor, type ZLinkFanoutPublisherDescriptor } from '../../contracts';
1
+ import { type RoutingId, type ZLinkClientServerServerDescriptor, type ZLinkFanoutPublisherDescriptor } from '../../contracts';
2
2
  import type { Message } from '../../contracts/Common/Message';
3
3
  import type { ZLinkBackendContext, ZLinkBackendDealerSocket, ZLinkBackendPublisherSocket, ZLinkBackendRouterSocket, ZLinkBackendSocketMonitor, ZLinkBackendSubscriberSocket, ZLinkChannelBackendAdapter, ZLinkMonitoringBackendAdapter } from '../backend/contracts';
4
4
  import { type ZLinkFrameworkRegistration } from '../configuration';
5
5
  import { ZLinkListenerRecords } from '../foundation/listener-records';
6
6
  import { ServiceDiscoveryRegistry } from '../foundation/service-discovery-registry';
7
+ import { ServiceLivenessConnection } from '../foundation/service-liveness-registry';
7
8
  import type { ApplicationJobQueue } from '../host/application-job-queue';
8
9
  import type { ZLinkChannelEnvelopeHeader } from './channel-envelope';
9
10
  export interface ZLinkClientServerServerSocketIdentity {
@@ -20,6 +21,12 @@ export interface ZLinkFanoutConnectionCallbacks {
20
21
  readonly onReady: () => void;
21
22
  readonly onTerminated: (reason: 'disconnect' | 'deadline' | 'protocol') => void;
22
23
  }
24
+ interface ClientServerServerPeer {
25
+ readonly channelName: string;
26
+ readonly routingId: RoutingId;
27
+ readonly normalizedEffectiveMaxMessageBytes: number;
28
+ readonly liveness: ServiceLivenessConnection;
29
+ }
23
30
  export declare class ZLinkChannelSocketRegistry {
24
31
  private readonly registration;
25
32
  private readonly adapter;
@@ -39,7 +46,6 @@ export declare class ZLinkChannelSocketRegistry {
39
46
  private readonly clientServerServerDescriptors;
40
47
  private readonly clientServerPublicWeights;
41
48
  private readonly routeMeshPublicWeights;
42
- private readonly clientServerAdmittedClients;
43
49
  private readonly clientServerServerPeers;
44
50
  private readonly disposal;
45
51
  private readonly ownedResources;
@@ -83,11 +89,12 @@ export declare class ZLinkChannelSocketRegistry {
83
89
  removeFanoutPublisher(descriptor: ZLinkFanoutPublisherDescriptor, connectionId: string): boolean;
84
90
  setClientServerServerDescriptor(descriptor: ZLinkClientServerServerDescriptor | undefined, channelName: string): void;
85
91
  private notifyClientServerTopology;
92
+ clientServerServerPeersForChannel(channelName: string): Map<RoutingId, ClientServerServerPeer>;
86
93
  tryHandleClientServerControl(channelName: string, received: {
87
94
  readonly parts: readonly Message[];
88
95
  readonly replyToken: unknown | null;
89
96
  readonly routingId: unknown;
90
- }, router: ZLinkBackendRouterSocket): boolean;
97
+ }, router: ZLinkBackendRouterSocket, peers?: Map<string, ClientServerServerPeer>): boolean;
91
98
  tickClientServerLiveness(nowMs?: number): void;
92
99
  openFanoutSubscriberConnection(channelName: string, connectionId: string, endpoint: string, callbacks: ZLinkFanoutConnectionCallbacks): ZLinkBackendSubscriberSocket;
93
100
  closeFanoutSubscriberConnection(connectionId: string): Promise<void>;