@zlink-systems/framework 0.30.1 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +4 -0
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +0 -1
- package/dist/runtime/actors/actor-client.js +38 -45
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +7 -3
- package/dist/runtime/actors/actor-handoff.js +212 -88
- package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
- package/dist/runtime/actors/actor-local-native-join.js +4 -0
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +6 -2
- package/dist/runtime/actors/index.js +37 -21
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +55 -32
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
- package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
- package/dist/runtime/application-jobs/contracts.d.ts +2 -0
- package/dist/runtime/backend/contracts/index.d.ts +19 -3
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.js +5 -0
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
- package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +20 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
- package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatchers.js +44 -37
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +74 -31
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
- package/dist/runtime/channels/channel-runtime-manager.js +4 -4
- package/dist/runtime/channels/channel-transports.d.ts +0 -1
- package/dist/runtime/channels/channel-transports.js +35 -33
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
- package/dist/runtime/execution/serial-execution-queue.js +21 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
- package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +24 -3
- package/dist/runtime/host/application-job-queue.js +28 -41
- package/dist/runtime/host/index.d.ts +5 -1
- package/dist/runtime/host/index.js +171 -97
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +71 -190
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +5 -3
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
- package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
- package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +6 -2
- package/dist/runtime/locations/runtime.js +37 -30
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.js +29 -26
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
- package/dist/runtime/spots/index.d.ts +18 -11
- package/dist/runtime/spots/index.js +234 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +6 -3
- package/dist/runtime/spots/spot-activation.js +123 -44
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +14 -9
- package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
- package/dist/runtime/spots/spot-handler-registry.js +6 -2
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.js +3 -3
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +287 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.js +1 -4
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +8 -0
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +61 -70
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +282 -106
- package/src/runtime/actors/actor-join-relocation.ts +2 -0
- package/src/runtime/actors/actor-local-native-join.ts +4 -0
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +41 -27
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/admission.ts +69 -34
- package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
- package/src/runtime/application-jobs/contracts.ts +2 -0
- package/src/runtime/backend/contracts/index.ts +39 -4
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +4 -0
- package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
- package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
- package/src/runtime/channels/channel-clients.ts +49 -24
- package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
- package/src/runtime/channels/channel-dispatchers.ts +116 -72
- package/src/runtime/channels/channel-envelope.ts +105 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +12 -5
- package/src/runtime/channels/channel-transports.ts +49 -58
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
- package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +29 -44
- package/src/runtime/host/index.ts +286 -129
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +86 -248
- package/src/runtime/host/route-mesh-runtime.ts +11 -5
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
- package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +70 -40
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +33 -29
- package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
- package/src/runtime/spots/index.ts +375 -281
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +170 -86
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +24 -19
- package/src/runtime/spots/spot-handler-registry.ts +15 -4
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +3 -3
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-runtime-ports.ts +0 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
- package/src/runtime/spots/spot-timer.ts +413 -157
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +1 -5
- package/src/runtime/workers/index.ts +1 -1
|
@@ -61,13 +61,32 @@ export type ZLinkBackendObjectPlacement =
|
|
|
61
61
|
| { readonly kind: 'capacity' }
|
|
62
62
|
| { readonly kind: 'unavailable' };
|
|
63
63
|
|
|
64
|
+
export type ZLinkBackendRequestSourceAcceptance = (
|
|
65
|
+
nodeRid: string,
|
|
66
|
+
nodeGeneration: bigint,
|
|
67
|
+
nodeRidStorageHex: string,
|
|
68
|
+
signal?: AbortSignal
|
|
69
|
+
) =>
|
|
70
|
+
| import('../../locations/request-source-resolver').ZLinkRequestSourceFence
|
|
71
|
+
| undefined
|
|
72
|
+
| Promise<import('../../locations/request-source-resolver').ZLinkRequestSourceFence | undefined>;
|
|
73
|
+
|
|
64
74
|
export interface ZLinkBackendMeshNode {
|
|
75
|
+
acceptRelocatedActorTerminal?(
|
|
76
|
+
operation: { readonly high: bigint; readonly low: bigint },
|
|
77
|
+
replyRouteId: bigint,
|
|
78
|
+
result: import('../../foundation/service-stateful-runtime').ServiceStatefulResult
|
|
79
|
+
): 'terminalReceived' | 'alreadyTerminal' | undefined;
|
|
65
80
|
readonly routingId?: RoutingId;
|
|
81
|
+
cancelPendingOperations?(reason: unknown): void;
|
|
66
82
|
completeClosedInstance?(spotId: string, objectGeneration: bigint): void;
|
|
67
83
|
setDispatchErrorReporter?(
|
|
68
84
|
reporter: import('../../channels/dispatch-error-reporter').ZLinkDispatchErrorReporter,
|
|
69
85
|
meshName: string
|
|
70
86
|
): void;
|
|
87
|
+
setSessionOwnerDescriptors?(
|
|
88
|
+
source: import('../../foundation/service-stateful-runtime').ServiceSessionOwnerDescriptors
|
|
89
|
+
): void;
|
|
71
90
|
setRoutingId(routingId: unknown): void;
|
|
72
91
|
setBind(endpoint: string): void;
|
|
73
92
|
setAdvertiseHost(host: string): void;
|
|
@@ -98,9 +117,9 @@ export interface ZLinkBackendMeshNode {
|
|
|
98
117
|
'kind'
|
|
99
118
|
>
|
|
100
119
|
): Promise<boolean>;
|
|
101
|
-
shutdown(timeoutMs: number): RequestResult
|
|
120
|
+
shutdown(timeoutMs: number): Promise<RequestResult>;
|
|
102
121
|
publishDraining?(): Promise<void>;
|
|
103
|
-
close(): void
|
|
122
|
+
close(): Promise<void>;
|
|
104
123
|
addChannelName(name: string): void;
|
|
105
124
|
setChannelWeight(name: string, weight: number): Promise<void>;
|
|
106
125
|
setPlacementWeight(weight: number): Promise<void>;
|
|
@@ -184,12 +203,23 @@ export interface ZLinkBackendMeshNode {
|
|
|
184
203
|
readonly securityIdentity?: string;
|
|
185
204
|
readonly lifecycleGeneration: bigint;
|
|
186
205
|
}): void;
|
|
206
|
+
/**
|
|
207
|
+
* Installs the source request owner check the first accepting owner runs on Actor and Spot
|
|
208
|
+
* ingress (Location runtime §9.3). Undefined from the check ends the request Unavailable.
|
|
209
|
+
*/
|
|
210
|
+
setRequestSourceAcceptance?(acceptance: ZLinkBackendRequestSourceAcceptance): void;
|
|
187
211
|
isObjectClientNodeDirectTarget?(targetRid: unknown): boolean;
|
|
188
212
|
observePeerRoute?(
|
|
189
213
|
targetRid: unknown
|
|
190
214
|
): import('../../foundation/durable-service-request').PeerRouteObservation;
|
|
191
215
|
hasPeerRouteOrConnectionIntent?(targetRid: unknown, endpoint: string): boolean;
|
|
192
216
|
isPeerRouteReady?(targetRid: unknown, lifecycleGeneration?: bigint): boolean;
|
|
217
|
+
waitForPeerRoute?(
|
|
218
|
+
targetRid: unknown,
|
|
219
|
+
lifecycleGeneration: bigint,
|
|
220
|
+
deadlineUnixMs: bigint,
|
|
221
|
+
signal?: AbortSignal
|
|
222
|
+
): Promise<void>;
|
|
193
223
|
sendToNode(
|
|
194
224
|
targetRid: unknown,
|
|
195
225
|
parts: MessageLike | readonly MessageLike[],
|
|
@@ -317,9 +347,10 @@ export interface ZLinkBackendMeshNode {
|
|
|
317
347
|
source: ServiceDirectSpotRouteFence
|
|
318
348
|
): ServiceSpotMessageFollowSeal | undefined;
|
|
319
349
|
abortSpotMessageFollowIngress?(seal: ServiceSpotMessageFollowSeal): boolean;
|
|
350
|
+
/** A null target consumes the committed seal without installing a Follow route. */
|
|
320
351
|
commitSpotMessageFollowIngress?(
|
|
321
352
|
seal: ServiceSpotMessageFollowSeal,
|
|
322
|
-
target: ServiceDirectSpotRouteFence,
|
|
353
|
+
target: ServiceDirectSpotRouteFence | null,
|
|
323
354
|
durationMs: number
|
|
324
355
|
): Promise<boolean>;
|
|
325
356
|
joinActorSpot(
|
|
@@ -365,7 +396,10 @@ export interface ZLinkBackendMeshNode {
|
|
|
365
396
|
sendToActor(
|
|
366
397
|
actor: ZLinkBackendActorRef,
|
|
367
398
|
parts: MessageLike | readonly MessageLike[],
|
|
368
|
-
options?: {
|
|
399
|
+
options?: {
|
|
400
|
+
flags?: number;
|
|
401
|
+
routeFence?: import('../../foundation/service-stateful-wire-codec').ServiceActorRouteFence;
|
|
402
|
+
}
|
|
369
403
|
): Promise<SubmitResult>;
|
|
370
404
|
requestToActor(
|
|
371
405
|
actor: ZLinkBackendActorRef,
|
|
@@ -375,6 +409,7 @@ export interface ZLinkBackendMeshNode {
|
|
|
375
409
|
timeoutMs?: number;
|
|
376
410
|
applicationMetadata?: Buffer;
|
|
377
411
|
onAdmitted?: () => void;
|
|
412
|
+
routeFence?: import('../../foundation/service-stateful-wire-codec').ServiceActorRouteFence;
|
|
378
413
|
}
|
|
379
414
|
): MeshOperationId;
|
|
380
415
|
actorSendToActor(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { wireReplyFailureException } from '../framework-errors-internal';
|
|
1
2
|
import { classifySubmitResult } from '../messaging/submission-result';
|
|
2
3
|
import type { ZLinkBackendActorSessionNode, ZLinkBackendMeshNode } from './contracts';
|
|
3
4
|
import { closeMeshCompletion, type ZLinkMeshCompletionTable } from './mesh-completion-table';
|
|
@@ -26,9 +27,10 @@ export function meshActorSessionNodeAdapter(
|
|
|
26
27
|
);
|
|
27
28
|
try {
|
|
28
29
|
if (completion.terminalResult !== 0 || completion.failureErrno !== 0) {
|
|
29
|
-
throw
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
throw wireReplyFailureException(
|
|
31
|
+
completion.terminalResult,
|
|
32
|
+
completion.failureErrno,
|
|
33
|
+
`Actor '${actor.actorId}' bound-session close failed.`
|
|
32
34
|
);
|
|
33
35
|
}
|
|
34
36
|
} finally {
|
|
@@ -71,7 +71,11 @@ export class ZLinkMeshCompletionTable {
|
|
|
71
71
|
this.slots.push(slot);
|
|
72
72
|
this.free = index;
|
|
73
73
|
}
|
|
74
|
+
// New slots hold no identity yet. Only a larger bucket array needs the
|
|
75
|
+
// pending identities placed again; it doubles, so growth to N pending
|
|
76
|
+
// operations re-indexes O(N) slots in total.
|
|
74
77
|
const minimumBuckets = this.slots.length * COMPLETION_HASH_BUCKETS_PER_SLOT;
|
|
78
|
+
if (minimumBuckets <= this.buckets.length) return;
|
|
75
79
|
this.buckets = new Int32Array(2 ** Math.ceil(Math.log2(minimumBuckets))).fill(-1);
|
|
76
80
|
for (let index = 0; index < this.slots.length; index++) {
|
|
77
81
|
const slot = this.slots[index]!;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { awaitWithAbort } from '../abort';
|
|
2
3
|
import { availableParallelism } from 'node:os';
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
enterApplicationJobPermitScope,
|
|
6
|
+
leaveApplicationJobPermitScope,
|
|
7
|
+
releaseApplicationJobPermitTurn
|
|
8
|
+
} from '../application-jobs/application-job-queue-scope';
|
|
4
9
|
import type {
|
|
5
10
|
ApplicationJobPermitPort,
|
|
6
11
|
ApplicationJobQueuePort
|
|
@@ -8,6 +13,7 @@ import type {
|
|
|
8
13
|
import { runZLinkExecutionArea } from '../execution';
|
|
9
14
|
import {
|
|
10
15
|
ReadyDomain,
|
|
16
|
+
type Claim,
|
|
11
17
|
type ReadyBatch,
|
|
12
18
|
type ReadyRecord,
|
|
13
19
|
type ReceiveBatch,
|
|
@@ -58,7 +64,6 @@ export interface ZLinkMeshDispatchFailureContext {
|
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
export class ZLinkMeshDispatchPump {
|
|
61
|
-
private readonly dispatchOwnedRecord = this.dispatchRecord.bind(this);
|
|
62
67
|
private pendingDomains: number = ReadyDomain.None;
|
|
63
68
|
private infrastructureScheduled = false;
|
|
64
69
|
private disposed = false;
|
|
@@ -68,6 +73,10 @@ export class ZLinkMeshDispatchPump {
|
|
|
68
73
|
private readonly capacityStop = new AbortController();
|
|
69
74
|
private recordsSinceYield = 0;
|
|
70
75
|
private yieldStartedAtMs = 0;
|
|
76
|
+
/** Drains in progress; the batch budget begins when work starts on an idle pump. */
|
|
77
|
+
private draining = 0;
|
|
78
|
+
/** The macrotask boundary every drain waits for once the shared budget is spent. */
|
|
79
|
+
private pendingYield?: Promise<void>;
|
|
71
80
|
|
|
72
81
|
constructor(
|
|
73
82
|
private readonly node: ZLinkBackendMeshNode,
|
|
@@ -85,7 +94,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
85
94
|
});
|
|
86
95
|
}
|
|
87
96
|
|
|
88
|
-
async dispose(): Promise<void> {
|
|
97
|
+
async dispose(signal?: AbortSignal): Promise<void> {
|
|
89
98
|
if (this.disposed) {
|
|
90
99
|
return;
|
|
91
100
|
}
|
|
@@ -95,7 +104,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
95
104
|
for (const wake of this.idleApplicationWorkers) wake();
|
|
96
105
|
this.idleApplicationWorkers.clear();
|
|
97
106
|
while (this.activeDrains.size > 0) {
|
|
98
|
-
await Promise.all([...this.activeDrains]);
|
|
107
|
+
await awaitWithAbort(Promise.all([...this.activeDrains]), signal);
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
|
|
@@ -159,12 +168,40 @@ export class ZLinkMeshDispatchPump {
|
|
|
159
168
|
try {
|
|
160
169
|
for (;;) {
|
|
161
170
|
await this.waitForApplicationReady();
|
|
162
|
-
|
|
171
|
+
this.beginDrain();
|
|
163
172
|
try {
|
|
164
|
-
|
|
173
|
+
while (!this.disposed) {
|
|
174
|
+
readyBatch.reset();
|
|
175
|
+
const drained = this.node.drainReady(
|
|
176
|
+
ReadyDomain.Application,
|
|
177
|
+
readyBatch,
|
|
178
|
+
ZLINK_BACKEND_RECV_DONT_WAIT
|
|
179
|
+
);
|
|
180
|
+
if (!drained.ok || drained.records.length === 0) break;
|
|
181
|
+
if (drained.hasResidue) this.markReady(ReadyDomain.Application);
|
|
182
|
+
for (let index = 0; index < drained.records.length; index += 1) {
|
|
183
|
+
const claim = readyBatch.takeClaim(index);
|
|
184
|
+
// Raw ingress already attached one host permit to each record.
|
|
185
|
+
// A claim reserving admission may receive only that permit's record.
|
|
186
|
+
await this.drainClaim(
|
|
187
|
+
ReadyDomain.Application,
|
|
188
|
+
drained.records[index]!,
|
|
189
|
+
claim,
|
|
190
|
+
receiveBatch
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
// Empty ready claims count toward the shared pump budget too.
|
|
194
|
+
this.recordsSinceYield += 1;
|
|
195
|
+
const yieldTurn = this.yieldIfNeeded();
|
|
196
|
+
if (yieldTurn !== undefined) await yieldTurn;
|
|
197
|
+
}
|
|
165
198
|
} catch (error) {
|
|
166
199
|
this.reportDispatchError(error);
|
|
200
|
+
} finally {
|
|
201
|
+
readyBatch.reset();
|
|
202
|
+
this.draining -= 1;
|
|
167
203
|
}
|
|
204
|
+
if (this.disposed) return;
|
|
168
205
|
}
|
|
169
206
|
} finally {
|
|
170
207
|
receiveBatch.close();
|
|
@@ -181,34 +218,62 @@ export class ZLinkMeshDispatchPump {
|
|
|
181
218
|
return new Promise((resolve) => this.idleApplicationWorkers.add(resolve));
|
|
182
219
|
}
|
|
183
220
|
|
|
184
|
-
|
|
185
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Starts one record in this worker's turn; a permit's scope covers the
|
|
223
|
+
* synchronous dispatch. Returns `false` when the dispatch threw (already
|
|
224
|
+
* reported), `true` when it returned synchronously, or the handler's pending
|
|
225
|
+
* completion, which the draining turn awaits itself before
|
|
226
|
+
* {@link finishRecord}.
|
|
227
|
+
*/
|
|
228
|
+
private dispatchRecord(
|
|
229
|
+
owner: ReadyRecord,
|
|
230
|
+
record: ReceiveRecord,
|
|
231
|
+
permit: ApplicationJobPermitPort | undefined
|
|
232
|
+
): boolean | PromiseLike<void> {
|
|
233
|
+
const previous = permit === undefined ? undefined : enterApplicationJobPermitScope(permit);
|
|
234
|
+
let result: void | PromiseLike<void>;
|
|
186
235
|
try {
|
|
187
236
|
result = this.options.dispatch(owner, record);
|
|
188
237
|
} catch (error) {
|
|
189
|
-
this.
|
|
190
|
-
return;
|
|
238
|
+
this.failRecord(error, record, permit);
|
|
239
|
+
return false;
|
|
240
|
+
} finally {
|
|
241
|
+
if (permit !== undefined) leaveApplicationJobPermitScope(previous);
|
|
191
242
|
}
|
|
192
|
-
return result
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
243
|
+
return result ?? true;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private failRecord(
|
|
247
|
+
error: unknown,
|
|
248
|
+
record: ReceiveRecord,
|
|
249
|
+
permit: ApplicationJobPermitPort | undefined
|
|
250
|
+
): void {
|
|
251
|
+
releaseApplicationJobPermitTurn(permit);
|
|
252
|
+
this.reportDispatchError(error, meshDispatchFailureContext(record));
|
|
198
253
|
}
|
|
199
254
|
|
|
200
|
-
|
|
201
|
-
|
|
255
|
+
/** Runs the record's terminal completion, then releases its permit turn. */
|
|
256
|
+
private finishRecord(
|
|
257
|
+
record: ReceiveRecord,
|
|
258
|
+
permit: ApplicationJobPermitPort | undefined
|
|
259
|
+
): void | Promise<void> {
|
|
260
|
+
let result: void | Promise<void> = undefined;
|
|
202
261
|
try {
|
|
203
262
|
result = record.onTerminalCompletion?.();
|
|
204
263
|
} catch (error) {
|
|
205
264
|
this.reportDispatchError(error, meshDispatchFailureContext(record));
|
|
265
|
+
}
|
|
266
|
+
if (result === undefined) {
|
|
267
|
+
releaseApplicationJobPermitTurn(permit);
|
|
206
268
|
return;
|
|
207
269
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
270
|
+
return Promise.resolve(result).then(
|
|
271
|
+
() => releaseApplicationJobPermitTurn(permit),
|
|
272
|
+
(error) => {
|
|
273
|
+
this.reportDispatchError(error, meshDispatchFailureContext(record));
|
|
274
|
+
releaseApplicationJobPermitTurn(permit);
|
|
275
|
+
}
|
|
276
|
+
);
|
|
212
277
|
}
|
|
213
278
|
|
|
214
279
|
private reportDispatchError(error: unknown, context?: ZLinkMeshDispatchFailureContext): void {
|
|
@@ -260,12 +325,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
260
325
|
if ((this.pendingDomains & ReadyDomain.Application) !== 0) {
|
|
261
326
|
setImmediate(() => this.wakeApplicationWorker());
|
|
262
327
|
}
|
|
263
|
-
const lifecycleBudgetExhausted = await this.drainDomain(
|
|
264
|
-
ReadyDomain.Infrastructure,
|
|
265
|
-
readyBatch,
|
|
266
|
-
undefined,
|
|
267
|
-
MESH_DISPATCH_LIFECYCLE_CLAIM_BUDGET
|
|
268
|
-
);
|
|
328
|
+
const lifecycleBudgetExhausted = await this.drainDomain(readyBatch);
|
|
269
329
|
if (lifecycleBudgetExhausted) {
|
|
270
330
|
this.pendingDomains |= ReadyDomain.Infrastructure;
|
|
271
331
|
await yieldToEventLoop();
|
|
@@ -276,117 +336,40 @@ export class ZLinkMeshDispatchPump {
|
|
|
276
336
|
}
|
|
277
337
|
}
|
|
278
338
|
|
|
279
|
-
private async drainDomain(
|
|
280
|
-
domain: number,
|
|
281
|
-
readyBatch: ReadyBatch,
|
|
282
|
-
receiveBatch: ReceiveBatch | undefined,
|
|
283
|
-
claimBudget?: number
|
|
284
|
-
): Promise<boolean> {
|
|
339
|
+
private async drainDomain(readyBatch: ReadyBatch): Promise<boolean> {
|
|
285
340
|
let claimsDrained = 0;
|
|
341
|
+
this.beginDrain();
|
|
286
342
|
try {
|
|
287
343
|
while (!this.disposed) {
|
|
288
|
-
if (
|
|
344
|
+
if (claimsDrained >= MESH_DISPATCH_LIFECYCLE_CLAIM_BUDGET) {
|
|
289
345
|
// Lifecycle work has priority, but a bounded turn lets application
|
|
290
346
|
// work make progress when lifecycle records keep arriving.
|
|
291
347
|
return true;
|
|
292
348
|
}
|
|
293
349
|
readyBatch.reset();
|
|
294
|
-
const drained = this.node.drainReady(
|
|
350
|
+
const drained = this.node.drainReady(
|
|
351
|
+
ReadyDomain.Infrastructure,
|
|
352
|
+
readyBatch,
|
|
353
|
+
ZLINK_BACKEND_RECV_DONT_WAIT
|
|
354
|
+
);
|
|
295
355
|
if (!drained.ok || drained.records.length === 0) {
|
|
296
356
|
return false;
|
|
297
357
|
}
|
|
298
|
-
if (domain === ReadyDomain.Application && drained.hasResidue) {
|
|
299
|
-
this.markReady(ReadyDomain.Application);
|
|
300
|
-
}
|
|
301
358
|
for (let index = 0; index < drained.records.length; index += 1) {
|
|
302
359
|
const claim = readyBatch.takeClaim(index);
|
|
303
360
|
claimsDrained += 1;
|
|
304
361
|
const owner = drained.records[index]!;
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const capacity =
|
|
315
|
-
owner.ordinaryIngressPreAdmitted === true ? MESH_DISPATCH_RECEIVE_CAPACITY : 1;
|
|
316
|
-
let claimPermit =
|
|
317
|
-
owner.terminalCompletion === true ||
|
|
318
|
-
owner.ordinaryIngressPreAdmitted === true ||
|
|
319
|
-
domain === ReadyDomain.Infrastructure
|
|
320
|
-
? undefined
|
|
321
|
-
: await this.acquirePermit();
|
|
322
|
-
try {
|
|
323
|
-
if (this.capacityStop.signal.aborted) return;
|
|
324
|
-
ownerReceiveBatch.reset(capacity);
|
|
325
|
-
const received = claim.recvBatch(ownerReceiveBatch, ZLINK_BACKEND_RECV_DONT_WAIT);
|
|
326
|
-
if (received.ok) {
|
|
327
|
-
// The bounded batch stays in claim order until its records finish.
|
|
328
|
-
try {
|
|
329
|
-
for (const record of received.records) {
|
|
330
|
-
if (this.disposed) break;
|
|
331
|
-
const permit = record.applicationJobPermit ?? claimPermit;
|
|
332
|
-
if (owner.ordinaryIngressPreAdmitted === true && permit === undefined) {
|
|
333
|
-
throw new Error(
|
|
334
|
-
'Pre-admitted raw ingress record lost its Application Job Queue permit.'
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
this.recordsSinceYield += 1;
|
|
338
|
-
if (permit === undefined) {
|
|
339
|
-
const dispatched = this.dispatchRecord(owner, record);
|
|
340
|
-
if (dispatched !== undefined) await dispatched;
|
|
341
|
-
} else {
|
|
342
|
-
if (
|
|
343
|
-
domain === ReadyDomain.Application &&
|
|
344
|
-
record.applicationJobPermit === undefined
|
|
345
|
-
)
|
|
346
|
-
permit.markApplicationQueued();
|
|
347
|
-
// The scope now owns this reservation, including failure
|
|
348
|
-
// and detached handler handoff. Only unused permits remain
|
|
349
|
-
// owned by the receive attempt's finally block.
|
|
350
|
-
if (permit === claimPermit) claimPermit = undefined;
|
|
351
|
-
const dispatched = runWithApplicationJobPermit(
|
|
352
|
-
permit,
|
|
353
|
-
this.dispatchOwnedRecord,
|
|
354
|
-
owner,
|
|
355
|
-
record
|
|
356
|
-
);
|
|
357
|
-
if (dispatched !== undefined) await dispatched;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
} finally {
|
|
361
|
-
// Batch ownership includes records whose dispatch never began,
|
|
362
|
-
// including on failure or shutdown in the middle of the batch.
|
|
363
|
-
for (const record of received.records) {
|
|
364
|
-
for (const part of record.parts) part.close();
|
|
365
|
-
record.releaseRetainedIngress?.();
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
} finally {
|
|
370
|
-
claimPermit?.releaseAfterInternalProcessing();
|
|
371
|
-
}
|
|
372
|
-
} finally {
|
|
373
|
-
claim.release();
|
|
374
|
-
if (receiveBatch === undefined) ownerReceiveBatch?.close();
|
|
375
|
-
}
|
|
376
|
-
const yieldTurn = this.yieldIfNeeded();
|
|
377
|
-
if (yieldTurn !== undefined) await yieldTurn;
|
|
378
|
-
};
|
|
379
|
-
// An application worker drains the one owner it claimed. Infrastructure owners
|
|
380
|
-
// drain independently, so a suspended owner does not hold the other claims.
|
|
381
|
-
if (receiveBatch !== undefined) {
|
|
382
|
-
await drainClaim();
|
|
383
|
-
} else {
|
|
384
|
-
const drain = drainClaim().catch((error) => this.reportDispatchError(error));
|
|
385
|
-
this.activeDrains.add(drain);
|
|
386
|
-
void drain.finally(() => this.activeDrains.delete(drain));
|
|
387
|
-
}
|
|
362
|
+
this.beginDrain();
|
|
363
|
+
const drain = this.drainClaim(ReadyDomain.Infrastructure, owner, claim, undefined).catch(
|
|
364
|
+
(error) => this.reportDispatchError(error)
|
|
365
|
+
);
|
|
366
|
+
this.activeDrains.add(drain);
|
|
367
|
+
void drain.finally(() => {
|
|
368
|
+
this.draining -= 1;
|
|
369
|
+
this.activeDrains.delete(drain);
|
|
370
|
+
});
|
|
388
371
|
}
|
|
389
|
-
if (
|
|
372
|
+
if (claimsDrained >= MESH_DISPATCH_LIFECYCLE_CLAIM_BUDGET) {
|
|
390
373
|
this.wakeApplicationWorker();
|
|
391
374
|
return true;
|
|
392
375
|
}
|
|
@@ -399,10 +382,123 @@ export class ZLinkMeshDispatchPump {
|
|
|
399
382
|
return false;
|
|
400
383
|
} finally {
|
|
401
384
|
readyBatch.reset();
|
|
385
|
+
this.draining -= 1;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Time the pump spent idle is not batch work: when work starts on an idle
|
|
391
|
+
* pump, its batch budget starts with it (spec 08 §6).
|
|
392
|
+
*/
|
|
393
|
+
private beginDrain(): void {
|
|
394
|
+
if (this.draining === 0) {
|
|
395
|
+
this.recordsSinceYield = 0;
|
|
396
|
+
this.yieldStartedAtMs = this.nowMs();
|
|
397
|
+
}
|
|
398
|
+
this.draining += 1;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/** Drains one claimed owner in this worker's turn, in claim order. */
|
|
402
|
+
private async drainClaim(
|
|
403
|
+
domain: number,
|
|
404
|
+
owner: ReadyRecord,
|
|
405
|
+
claim: Claim,
|
|
406
|
+
receiveBatch: ReceiveBatch | undefined
|
|
407
|
+
): Promise<void> {
|
|
408
|
+
let ownerReceiveBatch = receiveBatch;
|
|
409
|
+
try {
|
|
410
|
+
ownerReceiveBatch ??= this.node.createReceiveBatch(
|
|
411
|
+
MESH_DISPATCH_RECEIVE_CAPACITY,
|
|
412
|
+
this.options.partCapacity ?? DEFAULT_MESH_PART_CAPACITY
|
|
413
|
+
);
|
|
414
|
+
const capacity =
|
|
415
|
+
owner.ordinaryIngressPreAdmitted === true ? MESH_DISPATCH_RECEIVE_CAPACITY : 1;
|
|
416
|
+
let claimPermit =
|
|
417
|
+
owner.terminalCompletion === true ||
|
|
418
|
+
owner.ordinaryIngressPreAdmitted === true ||
|
|
419
|
+
domain === ReadyDomain.Infrastructure
|
|
420
|
+
? undefined
|
|
421
|
+
: await this.acquirePermit();
|
|
422
|
+
try {
|
|
423
|
+
if (this.capacityStop.signal.aborted) return;
|
|
424
|
+
ownerReceiveBatch.reset(capacity);
|
|
425
|
+
const received = claim.recvBatch(ownerReceiveBatch, ZLINK_BACKEND_RECV_DONT_WAIT);
|
|
426
|
+
if (received.ok) {
|
|
427
|
+
// The bounded batch stays in claim order until its records finish.
|
|
428
|
+
try {
|
|
429
|
+
for (const record of received.records) {
|
|
430
|
+
if (this.disposed) break;
|
|
431
|
+
const permit = record.applicationJobPermit ?? claimPermit;
|
|
432
|
+
if (owner.ordinaryIngressPreAdmitted === true && permit === undefined) {
|
|
433
|
+
throw new Error(
|
|
434
|
+
'Pre-admitted raw ingress record lost its Application Job Queue permit.'
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
this.recordsSinceYield += 1;
|
|
438
|
+
if (permit !== undefined) {
|
|
439
|
+
if (domain === ReadyDomain.Application && record.applicationJobPermit === undefined)
|
|
440
|
+
permit.markApplicationQueued();
|
|
441
|
+
// The scope now owns this reservation, including failure
|
|
442
|
+
// and detached handler handoff. Only unused permits remain
|
|
443
|
+
// owned by the receive attempt's finally block.
|
|
444
|
+
if (permit === claimPermit) claimPermit = undefined;
|
|
445
|
+
}
|
|
446
|
+
// The record's terminal and the permit turn release follow the
|
|
447
|
+
// handler in this turn's own continuation.
|
|
448
|
+
if (record.prepareDispatch !== undefined) {
|
|
449
|
+
try {
|
|
450
|
+
const stopSignal = this.capacityStop.signal;
|
|
451
|
+
const preparation = record.prepareDispatch(stopSignal);
|
|
452
|
+
const accepted = preparation instanceof Promise ? await preparation : preparation;
|
|
453
|
+
if (!accepted || stopSignal.aborted) {
|
|
454
|
+
releaseApplicationJobPermitTurn(permit);
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
} catch (error) {
|
|
458
|
+
this.failRecord(error, record, permit);
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const dispatched = this.dispatchRecord(owner, record, permit);
|
|
463
|
+
if (dispatched === false) continue;
|
|
464
|
+
if (dispatched !== true) {
|
|
465
|
+
try {
|
|
466
|
+
await dispatched;
|
|
467
|
+
} catch (error) {
|
|
468
|
+
this.failRecord(error, record, permit);
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const finished = this.finishRecord(record, permit);
|
|
473
|
+
if (finished !== undefined) await finished;
|
|
474
|
+
}
|
|
475
|
+
} finally {
|
|
476
|
+
// Batch ownership includes records whose dispatch never began,
|
|
477
|
+
// including on failure or shutdown in the middle of the batch.
|
|
478
|
+
for (const record of received.records) {
|
|
479
|
+
for (const part of record.parts) part.close();
|
|
480
|
+
record.releaseRetainedIngress?.();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
} finally {
|
|
485
|
+
claimPermit?.releaseAfterInternalProcessing();
|
|
486
|
+
}
|
|
487
|
+
} finally {
|
|
488
|
+
claim.release();
|
|
489
|
+
if (receiveBatch === undefined) ownerReceiveBatch?.close();
|
|
402
490
|
}
|
|
491
|
+
const yieldTurn = this.yieldIfNeeded();
|
|
492
|
+
if (yieldTurn !== undefined) await yieldTurn;
|
|
403
493
|
}
|
|
404
494
|
|
|
495
|
+
/**
|
|
496
|
+
* The batch budget is shared by every drain of this pump, so once it is
|
|
497
|
+
* spent every drain waits for the same macrotask boundary; one drain that
|
|
498
|
+
* keeps running would otherwise hold the event loop the yield was for.
|
|
499
|
+
*/
|
|
405
500
|
private yieldIfNeeded(): Promise<void> | undefined {
|
|
501
|
+
if (this.pendingYield !== undefined) return this.pendingYield;
|
|
406
502
|
const nowMs = this.nowMs();
|
|
407
503
|
if (
|
|
408
504
|
this.recordsSinceYield < MESH_DISPATCH_YIELD_RECORDS &&
|
|
@@ -410,9 +506,12 @@ export class ZLinkMeshDispatchPump {
|
|
|
410
506
|
)
|
|
411
507
|
return undefined;
|
|
412
508
|
this.recordsSinceYield = 0;
|
|
413
|
-
|
|
509
|
+
const pendingYield = yieldToTimers().then(() => {
|
|
510
|
+
this.pendingYield = undefined;
|
|
414
511
|
this.yieldStartedAtMs = this.nowMs();
|
|
415
512
|
});
|
|
513
|
+
this.pendingYield = pendingYield;
|
|
514
|
+
return pendingYield;
|
|
416
515
|
}
|
|
417
516
|
|
|
418
517
|
private nowMs(): number {
|