@zlink-systems/framework 0.30.3 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActor.d.ts +2 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.d.ts +6 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.js +2 -0
- package/dist/contracts/Actors/index.d.ts +1 -0
- package/dist/contracts/Actors/index.js +1 -0
- package/dist/contracts/Common/CoreTypes.d.ts +1 -0
- package/dist/contracts/Common/HandlerMessageType.d.ts +8 -0
- package/dist/contracts/Common/HandlerMessageType.js +41 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +1 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.js +12 -20
- package/dist/contracts/Common/ZLinkMessage.js +11 -7
- package/dist/contracts/Common/encoded-payload-storage.d.ts +0 -2
- package/dist/contracts/Common/encoded-payload-storage.js +4 -16
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/payload-slab.d.ts +4 -0
- package/dist/contracts/Common/payload-slab.js +30 -0
- package/dist/contracts/Configuration/RegistrationBuilders.js +15 -9
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +19 -0
- package/dist/contracts/Handlers/Contexts.d.ts +1 -0
- package/dist/contracts/Locations/Authority.d.ts +2 -0
- package/dist/internal.d.ts +9 -0
- package/dist/internal.js +23 -1
- package/dist/nest-integration.d.ts +1 -0
- package/dist/nest-integration.js +3 -1
- package/dist/runtime/actors/actor-client.d.ts +6 -2
- package/dist/runtime/actors/actor-client.js +120 -82
- package/dist/runtime/actors/actor-context.js +16 -5
- package/dist/runtime/actors/actor-execution-context.js +2 -2
- package/dist/runtime/actors/actor-handoff.d.ts +12 -1
- package/dist/runtime/actors/actor-handoff.js +79 -34
- package/dist/runtime/actors/actor-join-deferred-scope.js +6 -6
- package/dist/runtime/actors/actor-local-native-join.d.ts +2 -2
- package/dist/runtime/actors/actor-local-native-join.js +19 -17
- package/dist/runtime/actors/actor-mailbox.d.ts +1 -1
- package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
- package/dist/runtime/actors/actor-remote-joiner.js +4 -4
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +9 -3
- package/dist/runtime/actors/actor-routed-json-request.d.ts +3 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -2
- package/dist/runtime/actors/actor-runtime-state.d.ts +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +9 -5
- package/dist/runtime/actors/spot-actor-dispatch.js +60 -38
- package/dist/runtime/admission.d.ts +6 -4
- package/dist/runtime/admission.js +21 -10
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +1 -0
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +3 -0
- package/dist/runtime/backend/contracts/index.d.ts +26 -10
- package/dist/runtime/backend/mesh-completion-table.d.ts +7 -1
- package/dist/runtime/backend/mesh-completion-table.js +84 -20
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +19 -6
- package/dist/runtime/backend/mesh-dispatch-pump.js +246 -147
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +27 -19
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +5 -2
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +70 -13
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +4 -3
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +5 -1
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +7 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +99 -63
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +34 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +210 -106
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +20 -6
- package/dist/runtime/backend/raw-binding-port.d.ts +6 -3
- package/dist/runtime/channels/channel-clients.js +3 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +11 -7
- package/dist/runtime/channels/channel-dispatch-pipeline.js +40 -22
- package/dist/runtime/channels/channel-dispatch-services.d.ts +3 -1
- package/dist/runtime/channels/channel-dispatch-services.js +7 -6
- package/dist/runtime/channels/channel-dispatchers.d.ts +13 -6
- package/dist/runtime/channels/channel-dispatchers.js +57 -36
- package/dist/runtime/channels/channel-envelope.d.ts +2 -2
- package/dist/runtime/channels/channel-envelope.js +609 -83
- package/dist/runtime/channels/channel-multipart.d.ts +1 -0
- package/dist/runtime/channels/channel-multipart.js +10 -6
- package/dist/runtime/channels/channel-outbound-operations.d.ts +6 -9
- package/dist/runtime/channels/channel-outbound-operations.js +107 -105
- package/dist/runtime/channels/channel-receive-loops.d.ts +9 -7
- package/dist/runtime/channels/channel-receive-loops.js +126 -90
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +23 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.js +47 -38
- package/dist/runtime/channels/channel-runtime-manager.d.ts +13 -6
- package/dist/runtime/channels/channel-runtime-manager.js +32 -14
- package/dist/runtime/channels/channel-socket-registry.d.ts +28 -4
- package/dist/runtime/channels/channel-socket-registry.js +9 -1
- package/dist/runtime/channels/channel-transports.d.ts +23 -16
- package/dist/runtime/channels/channel-transports.js +139 -119
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +4 -4
- package/dist/runtime/channels/dispatch-error-reporter.js +5 -5
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.d.ts +5 -2
- package/dist/runtime/channels/local-spot-route-transport.js +15 -18
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +6 -3
- package/dist/runtime/channels/router-socket-spot-route-transport.js +33 -19
- package/dist/runtime/channels/source-spot-router.d.ts +6 -3
- package/dist/runtime/channels/source-spot-router.js +34 -23
- package/dist/runtime/channels/spot-node-route-transport.d.ts +6 -3
- package/dist/runtime/channels/spot-node-route-transport.js +23 -17
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +6 -3
- package/dist/runtime/channels/spot-route-bridge-transport.js +38 -24
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +8 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +36 -23
- package/dist/runtime/diagnostics/dispatch-error-details.js +9 -3
- package/dist/runtime/diagnostics/message-flow-bootstrap.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow-bootstrap.js +8 -0
- package/dist/runtime/diagnostics/message-flow-delivery.d.ts +47 -0
- package/dist/runtime/diagnostics/message-flow-delivery.js +149 -0
- package/dist/runtime/diagnostics/message-flow-record.d.ts +50 -0
- package/dist/runtime/diagnostics/message-flow-record.js +228 -0
- package/dist/runtime/diagnostics/message-flow-worker.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow-worker.js +118 -0
- package/dist/runtime/diagnostics/message-flow.d.ts +7 -19
- package/dist/runtime/diagnostics/message-flow.js +42 -290
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +4 -3
- package/dist/runtime/diagnostics/runtime-metrics.js +8 -4
- package/dist/runtime/execution/index.d.ts +1 -0
- package/dist/runtime/execution/index.js +6 -3
- package/dist/runtime/execution/serial-execution-queue.d.ts +26 -13
- package/dist/runtime/execution/serial-execution-queue.js +75 -71
- package/dist/runtime/foundation/durable-service-request.d.ts +12 -3
- package/dist/runtime/foundation/durable-service-request.js +158 -73
- package/dist/runtime/foundation/operation-registry.d.ts +33 -3
- package/dist/runtime/foundation/operation-registry.js +272 -33
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +62 -23
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +373 -194
- package/dist/runtime/foundation/request-runtime.d.ts +17 -0
- package/dist/runtime/foundation/request-runtime.js +163 -0
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +6 -0
- package/dist/runtime/foundation/service-liveness-registry.d.ts +1 -1
- package/dist/runtime/foundation/service-mailbox.d.ts +4 -2
- package/dist/runtime/foundation/service-mailbox.js +4 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -2
- package/dist/runtime/foundation/service-relocation-object-owner.js +12 -5
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +7 -2
- package/dist/runtime/foundation/service-stateful-registry.d.ts +6 -2
- package/dist/runtime/foundation/service-stateful-registry.js +38 -17
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +91 -26
- package/dist/runtime/foundation/service-stateful-runtime.js +245 -120
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -0
- package/dist/runtime/foundation/service-stateful-wire-codec.js +15 -0
- package/dist/runtime/foundation/service-topology-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-topology-registry.js +13 -3
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +12 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +5 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.js +50 -15
- package/dist/runtime/host/actor-packet-relay.d.ts +5 -6
- package/dist/runtime/host/actor-packet-relay.js +58 -57
- package/dist/runtime/host/actor-placement-coordinator.d.ts +1 -1
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +3 -2
- package/dist/runtime/host/actor-transfer-runtime.d.ts +3 -3
- package/dist/runtime/host/application-job-queue.d.ts +7 -5
- package/dist/runtime/host/application-job-queue.js +33 -21
- package/dist/runtime/host/bound-session-relay.js +0 -1
- package/dist/runtime/host/channel-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -0
- package/dist/runtime/host/entry-actor-runtime.d.ts +5 -2
- package/dist/runtime/host/entry-actor-runtime.js +2 -2
- package/dist/runtime/host/index.d.ts +106 -37
- package/dist/runtime/host/index.js +303 -151
- package/dist/runtime/host/location-runtime-owner.d.ts +2 -2
- package/dist/runtime/host/location-runtime-owner.js +1 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +195 -45
- package/dist/runtime/host/service-relocation-host-runtime.js +257 -144
- package/dist/runtime/host/spot-address-transport.d.ts +3 -0
- package/dist/runtime/host/spot-address-transport.js +73 -76
- package/dist/runtime/host/spot-runtime-options-factory.js +2 -0
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -1
- package/dist/runtime/host/user-spot-creation-coordinator.js +49 -21
- package/dist/runtime/internal-observation.d.ts +1 -0
- package/dist/runtime/internal-observation.js +5 -0
- package/dist/runtime/locations/actor-location-claims.d.ts +1 -1
- package/dist/runtime/locations/actor-location-claims.js +15 -6
- package/dist/runtime/locations/auto-connect-loop.d.ts +0 -1
- package/dist/runtime/locations/auto-connect-loop.js +25 -19
- package/dist/runtime/locations/auto-connect-planner.js +2 -5
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +1 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +35 -23
- package/dist/runtime/locations/in-memory-authority-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.js +15 -5
- package/dist/runtime/locations/in-memory-location-store.d.ts +0 -2
- package/dist/runtime/locations/in-memory-location-store.js +1 -38
- package/dist/runtime/locations/lifecycle.d.ts +1 -1
- package/dist/runtime/locations/lifecycle.js +2 -2
- package/dist/runtime/locations/location-store-repository.d.ts +0 -1
- package/dist/runtime/locations/location-store-repository.js +163 -246
- package/dist/runtime/locations/resolvers.d.ts +8 -1
- package/dist/runtime/locations/resolvers.js +16 -2
- package/dist/runtime/locations/runtime.d.ts +3 -3
- package/dist/runtime/locations/runtime.js +12 -16
- package/dist/runtime/messaging/creation-payload-codec.js +8 -7
- package/dist/runtime/messaging/framework-json-v1.d.ts +1 -1
- package/dist/runtime/messaging/framework-json-v1.js +6 -2
- package/dist/runtime/messaging/payload-codec.js +21 -35
- package/dist/runtime/messaging/request-deadline.d.ts +4 -2
- package/dist/runtime/messaging/request-deadline.js +40 -25
- package/dist/runtime/messaging/request-result.d.ts +14 -1
- package/dist/runtime/messaging/request-result.js +74 -13
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +4 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +17 -7
- package/dist/runtime/spots/index.d.ts +28 -7
- package/dist/runtime/spots/index.js +31 -6
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -2
- package/dist/runtime/spots/spot-activation-registry.js +13 -8
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -0
- package/dist/runtime/spots/spot-activation-state.js +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +9 -4
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +33 -12
- package/dist/runtime/spots/spot-actor-ingress-admission.d.ts +40 -0
- package/dist/runtime/spots/spot-actor-ingress-admission.js +78 -0
- package/dist/runtime/spots/spot-actor-membership.js +3 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +16 -43
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +56 -113
- package/dist/runtime/spots/spot-actor-packet-drain.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -5
- package/dist/runtime/spots/spot-entry-activation.d.ts +4 -3
- package/dist/runtime/spots/spot-entry-activation.js +7 -12
- package/dist/runtime/spots/spot-handler-registry.d.ts +5 -1
- package/dist/runtime/spots/spot-handler-registry.js +31 -15
- package/dist/runtime/spots/spot-manager-public.js +3 -2
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +11 -6
- package/dist/runtime/spots/spot-node-runtime-manager.js +6 -1
- package/dist/runtime/spots/spot-outbound.d.ts +8 -2
- package/dist/runtime/spots/spot-outbound.js +5 -5
- package/dist/runtime/spots/spot-route-packet-dispatch.js +13 -8
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +3 -3
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +9 -5
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -2
- package/dist/runtime/spots/spot-serial-executor.d.ts +2 -1
- package/dist/runtime/spots/spot-serial-turn-executor.js +20 -26
- package/dist/runtime/spots/spot-subscription-dispatch.js +5 -2
- package/dist/runtime/spots/spot-timer.d.ts +1 -1
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +11 -3
- package/dist/runtime/streams/actor-session-binding-registry.js +28 -0
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +3 -4
- package/dist/runtime/streams/bound-session-service.js +6 -7
- package/dist/runtime/streams/index.d.ts +3 -3
- package/dist/runtime/streams/index.js +22 -2
- package/dist/runtime/streams/managed-stream.js +2 -1
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +3 -9
- package/dist/runtime/streams/session-context.d.ts +2 -2
- package/dist/runtime/streams/session-context.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -0
- package/dist/runtime/streams/stream-session-runtime.js +64 -33
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActor.ts +6 -0
- package/src/contracts/Actors/ZLinkSessionBindingIdentity.ts +7 -0
- package/src/contracts/Actors/index.ts +1 -0
- package/src/contracts/Common/CoreTypes.ts +1 -0
- package/src/contracts/Common/HandlerMessageType.ts +50 -0
- package/src/contracts/Common/ZLinkEncodedPayload.ts +13 -25
- package/src/contracts/Common/ZLinkMessage.ts +11 -7
- package/src/contracts/Common/encoded-payload-storage.ts +4 -16
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Common/payload-slab.ts +29 -0
- package/src/contracts/Configuration/RegistrationBuilders.ts +29 -15
- package/src/contracts/Configuration/RegistrationTypes.ts +19 -0
- package/src/contracts/Handlers/Contexts.ts +1 -0
- package/src/contracts/Locations/Authority.ts +7 -1
- package/src/internal.ts +17 -0
- package/src/nest-integration.ts +1 -0
- package/src/runtime/actors/actor-client.ts +257 -163
- package/src/runtime/actors/actor-context.ts +26 -14
- package/src/runtime/actors/actor-execution-context.ts +2 -2
- package/src/runtime/actors/actor-handoff.ts +86 -51
- package/src/runtime/actors/actor-join-deferred-scope.ts +6 -6
- package/src/runtime/actors/actor-local-native-join.ts +38 -17
- package/src/runtime/actors/actor-mailbox.ts +1 -1
- package/src/runtime/actors/actor-remote-joiner.ts +8 -4
- package/src/runtime/actors/actor-routed-join-transport.ts +13 -5
- package/src/runtime/actors/actor-routed-json-request.ts +3 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -2
- package/src/runtime/actors/actor-runtime-state.ts +1 -1
- package/src/runtime/actors/spot-actor-dispatch.ts +70 -68
- package/src/runtime/admission.ts +42 -15
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +4 -0
- package/src/runtime/backend/contracts/index.ts +77 -10
- package/src/runtime/backend/mesh-completion-table.ts +106 -15
- package/src/runtime/backend/mesh-dispatch-pump.ts +294 -146
- package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -32
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +91 -34
- package/src/runtime/backend/node/node-event-loop-poller.ts +14 -5
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +5 -1
- package/src/runtime/backend/node/node-raw-binding-port.ts +180 -69
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +386 -157
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +56 -11
- package/src/runtime/backend/raw-binding-port.ts +13 -5
- package/src/runtime/channels/channel-clients.ts +26 -11
- package/src/runtime/channels/channel-dispatch-pipeline.ts +77 -65
- package/src/runtime/channels/channel-dispatch-services.ts +7 -12
- package/src/runtime/channels/channel-dispatchers.ts +93 -39
- package/src/runtime/channels/channel-envelope.ts +680 -144
- package/src/runtime/channels/channel-multipart.ts +17 -13
- package/src/runtime/channels/channel-outbound-operations.ts +204 -178
- package/src/runtime/channels/channel-receive-loops.ts +160 -107
- package/src/runtime/channels/channel-runtime-lifecycle.ts +64 -59
- package/src/runtime/channels/channel-runtime-manager.ts +74 -27
- package/src/runtime/channels/channel-socket-registry.ts +20 -5
- package/src/runtime/channels/channel-transports.ts +414 -287
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -9
- package/src/runtime/channels/local-spot-route-transport.ts +27 -29
- package/src/runtime/channels/router-socket-spot-route-transport.ts +63 -32
- package/src/runtime/channels/source-spot-router.ts +75 -38
- package/src/runtime/channels/spot-node-route-transport.ts +67 -37
- package/src/runtime/channels/spot-route-bridge-transport.ts +62 -30
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +105 -34
- package/src/runtime/diagnostics/dispatch-error-details.ts +10 -2
- package/src/runtime/diagnostics/message-flow-bootstrap.ts +6 -0
- package/src/runtime/diagnostics/message-flow-delivery.ts +171 -0
- package/src/runtime/diagnostics/message-flow-record.ts +295 -0
- package/src/runtime/diagnostics/message-flow-worker.ts +146 -0
- package/src/runtime/diagnostics/message-flow.ts +49 -362
- package/src/runtime/diagnostics/runtime-metrics.ts +10 -4
- package/src/runtime/execution/index.ts +6 -0
- package/src/runtime/execution/serial-execution-queue.ts +94 -96
- package/src/runtime/foundation/durable-service-request.ts +212 -89
- package/src/runtime/foundation/operation-registry.ts +287 -38
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +617 -292
- package/src/runtime/foundation/request-runtime.ts +227 -0
- package/src/runtime/foundation/service-discovery-registry.ts +7 -0
- package/src/runtime/foundation/service-liveness-registry.ts +1 -1
- package/src/runtime/foundation/service-mailbox.ts +7 -2
- package/src/runtime/foundation/service-relocation-object-owner.ts +21 -6
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -2
- package/src/runtime/foundation/service-stateful-registry.ts +52 -19
- package/src/runtime/foundation/service-stateful-runtime.ts +365 -198
- package/src/runtime/foundation/service-stateful-wire-codec.ts +18 -0
- package/src/runtime/foundation/service-topology-registry.ts +21 -3
- package/src/runtime/foundation/service-wire-constants.generated.ts +10 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -17
- package/src/runtime/host/actor-packet-relay.ts +160 -156
- package/src/runtime/host/actor-placement-coordinator.ts +1 -1
- package/src/runtime/host/actor-runtime-options-factory.ts +7 -2
- package/src/runtime/host/actor-transfer-runtime.ts +3 -3
- package/src/runtime/host/application-job-queue.ts +56 -27
- package/src/runtime/host/bound-session-relay.ts +0 -1
- package/src/runtime/host/channel-runtime-options-factory.ts +3 -0
- package/src/runtime/host/entry-actor-runtime.ts +14 -6
- package/src/runtime/host/index.ts +388 -113
- package/src/runtime/host/location-runtime-owner.ts +3 -3
- package/src/runtime/host/service-relocation-host-runtime.ts +380 -252
- package/src/runtime/host/spot-address-transport.ts +110 -95
- package/src/runtime/host/spot-runtime-options-factory.ts +3 -0
- package/src/runtime/host/user-spot-creation-coordinator.ts +69 -22
- package/src/runtime/internal-observation.ts +2 -0
- package/src/runtime/locations/actor-location-claims.ts +42 -16
- package/src/runtime/locations/auto-connect-loop.ts +24 -16
- package/src/runtime/locations/auto-connect-planner.ts +2 -5
- package/src/runtime/locations/auto-connect-reconciler.ts +37 -24
- package/src/runtime/locations/in-memory-authority-store.ts +27 -7
- package/src/runtime/locations/in-memory-location-store.ts +1 -74
- package/src/runtime/locations/lifecycle.ts +4 -2
- package/src/runtime/locations/location-store-repository.ts +228 -308
- package/src/runtime/locations/resolvers.ts +20 -8
- package/src/runtime/locations/runtime.ts +16 -28
- package/src/runtime/messaging/creation-payload-codec.ts +12 -10
- package/src/runtime/messaging/framework-json-v1.ts +10 -1
- package/src/runtime/messaging/payload-codec.ts +50 -75
- package/src/runtime/messaging/request-deadline.ts +47 -39
- package/src/runtime/messaging/request-result.ts +88 -17
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/index.ts +57 -10
- package/src/runtime/spots/spot-activation-registry.ts +12 -8
- package/src/runtime/spots/spot-activation-state.ts +2 -0
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +62 -37
- package/src/runtime/spots/spot-actor-ingress-admission.ts +157 -0
- package/src/runtime/spots/spot-actor-membership.ts +8 -5
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +122 -206
- package/src/runtime/spots/spot-actor-packet-drain.ts +21 -6
- package/src/runtime/spots/spot-entry-activation.ts +25 -35
- package/src/runtime/spots/spot-handler-registry.ts +72 -15
- package/src/runtime/spots/spot-manager-public.ts +4 -2
- package/src/runtime/spots/spot-node-runtime-manager.ts +16 -7
- package/src/runtime/spots/spot-outbound.ts +26 -10
- package/src/runtime/spots/spot-route-packet-dispatch.ts +18 -8
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +14 -8
- package/src/runtime/spots/spot-runtime-ports.ts +5 -2
- package/src/runtime/spots/spot-serial-executor.ts +1 -1
- package/src/runtime/spots/spot-serial-turn-executor.ts +25 -40
- package/src/runtime/spots/spot-subscription-dispatch.ts +9 -2
- package/src/runtime/spots/spot-timer.ts +1 -1
- package/src/runtime/streams/actor-session-binding-registry.ts +46 -3
- package/src/runtime/streams/bound-actor-relay-sender.ts +16 -5
- package/src/runtime/streams/bound-session-service.ts +10 -7
- package/src/runtime/streams/index.ts +30 -4
- package/src/runtime/streams/managed-stream.ts +2 -1
- package/src/runtime/streams/session-calls.ts +9 -14
- package/src/runtime/streams/session-context.ts +6 -11
- package/src/runtime/streams/stream-session-runtime.ts +79 -40
- package/dist/runtime/spots/spot-lifecycle-metrics.d.ts +0 -8
- package/dist/runtime/spots/spot-lifecycle-metrics.js +0 -17
- package/src/runtime/spots/spot-lifecycle-metrics.ts +0 -16
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
1
|
import { awaitWithAbort } from '../abort';
|
|
3
2
|
import { availableParallelism } from 'node:os';
|
|
4
3
|
import {
|
|
@@ -10,9 +9,10 @@ import type {
|
|
|
10
9
|
ApplicationJobPermitPort,
|
|
11
10
|
ApplicationJobQueuePort
|
|
12
11
|
} from '../application-jobs/contracts';
|
|
13
|
-
import { runZLinkExecutionArea } from '../execution';
|
|
12
|
+
import { detachedMeshDispatchScope, runZLinkExecutionArea } from '../execution';
|
|
14
13
|
import {
|
|
15
14
|
ReadyDomain,
|
|
15
|
+
ReceiveKind,
|
|
16
16
|
type Claim,
|
|
17
17
|
type ReadyBatch,
|
|
18
18
|
type ReadyRecord,
|
|
@@ -39,15 +39,9 @@ const MESH_DISPATCH_YIELD_INTERVAL_MS = 2;
|
|
|
39
39
|
const MESH_DISPATCH_LIFECYCLE_CLAIM_BUDGET = 4;
|
|
40
40
|
const MESH_DISPATCH_RECEIVE_CAPACITY = 64;
|
|
41
41
|
const MESH_DISPATCH_MAX_APPLICATION_WORKERS = Math.max(2, availableParallelism());
|
|
42
|
-
// Captured while the runtime module is loaded, before any application owner
|
|
43
|
-
// exists. A ready callback may run inside a Spot turn; the shared Mesh pump
|
|
44
|
-
// must enter like an independent receive-loop task, without inheriting that
|
|
45
|
-
// owner's AsyncLocalStorage identity.
|
|
46
|
-
const detachedMeshDispatchScope = AsyncLocalStorage.snapshot();
|
|
47
42
|
|
|
48
43
|
export interface ZLinkMeshDispatchPumpOptions {
|
|
49
44
|
readonly readyCapacity?: number;
|
|
50
|
-
readonly messageCapacity?: number;
|
|
51
45
|
readonly partCapacity?: number;
|
|
52
46
|
readonly dispatch: (owner: ReadyRecord, record: ReceiveRecord) => void | Promise<void>;
|
|
53
47
|
readonly applicationJobQueue: ApplicationJobQueuePort;
|
|
@@ -63,12 +57,26 @@ export interface ZLinkMeshDispatchFailureContext {
|
|
|
63
57
|
readonly commandId?: number;
|
|
64
58
|
}
|
|
65
59
|
|
|
60
|
+
interface MeshClaimDrainState {
|
|
61
|
+
readonly suppliedReceiveBatch: ReceiveBatch | undefined;
|
|
62
|
+
receiveBatch: ReceiveBatch | undefined;
|
|
63
|
+
domain: number;
|
|
64
|
+
owner: ReadyRecord | undefined;
|
|
65
|
+
claim: Claim | undefined;
|
|
66
|
+
claimPermit: ApplicationJobPermitPort | undefined;
|
|
67
|
+
records: readonly ReceiveRecord[] | undefined;
|
|
68
|
+
index: number;
|
|
69
|
+
readonly receive: (permit?: ApplicationJobPermitPort) => Promise<void> | undefined;
|
|
70
|
+
readonly dispatchRecords: () => Promise<void> | undefined;
|
|
71
|
+
readonly finish: () => void;
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
export class ZLinkMeshDispatchPump {
|
|
67
75
|
private pendingDomains: number = ReadyDomain.None;
|
|
68
76
|
private infrastructureScheduled = false;
|
|
69
77
|
private disposed = false;
|
|
70
78
|
private readonly activeDrains = new Set<Promise<void>>();
|
|
71
|
-
private readonly idleApplicationWorkers
|
|
79
|
+
private readonly idleApplicationWorkers: Array<() => void> = [];
|
|
72
80
|
private applicationWorkerCount = 0;
|
|
73
81
|
private readonly capacityStop = new AbortController();
|
|
74
82
|
private recordsSinceYield = 0;
|
|
@@ -102,7 +110,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
102
110
|
this.capacityStop.abort();
|
|
103
111
|
this.pendingDomains = ReadyDomain.None;
|
|
104
112
|
for (const wake of this.idleApplicationWorkers) wake();
|
|
105
|
-
this.idleApplicationWorkers.
|
|
113
|
+
this.idleApplicationWorkers.length = 0;
|
|
106
114
|
while (this.activeDrains.size > 0) {
|
|
107
115
|
await awaitWithAbort(Promise.all([...this.activeDrains]), signal);
|
|
108
116
|
}
|
|
@@ -124,18 +132,21 @@ export class ZLinkMeshDispatchPump {
|
|
|
124
132
|
if (startInfrastructure) this.scheduleInfrastructure();
|
|
125
133
|
if (startApplication) {
|
|
126
134
|
if ((domains & ReadyDomain.Infrastructure) !== 0) {
|
|
127
|
-
|
|
135
|
+
this.scheduleApplicationWorker();
|
|
128
136
|
} else {
|
|
129
137
|
this.wakeApplicationWorker();
|
|
130
138
|
}
|
|
131
139
|
}
|
|
132
140
|
}
|
|
133
141
|
|
|
142
|
+
private scheduleApplicationWorker(): void {
|
|
143
|
+
setImmediate(() => this.wakeApplicationWorker());
|
|
144
|
+
}
|
|
145
|
+
|
|
134
146
|
private wakeApplicationWorker(): void {
|
|
135
147
|
if (this.disposed || (this.pendingDomains & ReadyDomain.Application) === 0) return;
|
|
136
|
-
const idle = this.idleApplicationWorkers.
|
|
148
|
+
const idle = this.idleApplicationWorkers.shift();
|
|
137
149
|
if (idle !== undefined) {
|
|
138
|
-
this.idleApplicationWorkers.delete(idle);
|
|
139
150
|
this.pendingDomains &= ~ReadyDomain.Application;
|
|
140
151
|
idle();
|
|
141
152
|
return;
|
|
@@ -157,79 +168,61 @@ export class ZLinkMeshDispatchPump {
|
|
|
157
168
|
this.activeDrains.add(worker);
|
|
158
169
|
}
|
|
159
170
|
|
|
160
|
-
private async runApplicationWorker(): Promise<void> {
|
|
161
|
-
// A worker claims one owner at a time so a suspended handler cannot hold
|
|
162
|
-
// unrelated owners. Each owner may supply up to 64 pre-admitted records.
|
|
163
|
-
const readyBatch = this.node.createReadyBatch(1);
|
|
164
|
-
const receiveBatch = this.node.createReceiveBatch(
|
|
165
|
-
MESH_DISPATCH_RECEIVE_CAPACITY,
|
|
166
|
-
this.options.partCapacity ?? DEFAULT_MESH_PART_CAPACITY
|
|
167
|
-
);
|
|
168
|
-
try {
|
|
169
|
-
for (;;) {
|
|
170
|
-
await this.waitForApplicationReady();
|
|
171
|
-
this.beginDrain();
|
|
172
|
-
try {
|
|
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
|
-
}
|
|
198
|
-
} catch (error) {
|
|
199
|
-
this.reportDispatchError(error);
|
|
200
|
-
} finally {
|
|
201
|
-
readyBatch.reset();
|
|
202
|
-
this.draining -= 1;
|
|
203
|
-
}
|
|
204
|
-
if (this.disposed) return;
|
|
205
|
-
}
|
|
206
|
-
} finally {
|
|
207
|
-
receiveBatch.close();
|
|
208
|
-
readyBatch.close();
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
171
|
private waitForApplicationReady(): Promise<void> {
|
|
213
172
|
if (this.disposed) return Promise.resolve();
|
|
214
173
|
if ((this.pendingDomains & ReadyDomain.Application) !== 0) {
|
|
215
174
|
this.pendingDomains &= ~ReadyDomain.Application;
|
|
216
175
|
return Promise.resolve();
|
|
217
176
|
}
|
|
218
|
-
return new Promise((resolve) => this.idleApplicationWorkers.
|
|
177
|
+
return new Promise((resolve) => this.idleApplicationWorkers.push(resolve));
|
|
219
178
|
}
|
|
220
179
|
|
|
221
180
|
/**
|
|
222
181
|
* Starts one record in this worker's turn; a permit's scope covers the
|
|
223
|
-
* synchronous dispatch. Returns `false` when
|
|
224
|
-
* reported), `true` when
|
|
225
|
-
*
|
|
182
|
+
* synchronous dispatch. Returns `false` when preparation rejects the record,
|
|
183
|
+
* shutdown starts, or dispatch throws (already reported), `true` when dispatch
|
|
184
|
+
* returns synchronously, or the pending preparation/handler completion,
|
|
185
|
+
* which the draining turn awaits itself before
|
|
226
186
|
* {@link finishRecord}.
|
|
227
187
|
*/
|
|
228
188
|
private dispatchRecord(
|
|
229
189
|
owner: ReadyRecord,
|
|
230
190
|
record: ReceiveRecord,
|
|
231
191
|
permit: ApplicationJobPermitPort | undefined
|
|
192
|
+
): boolean | PromiseLike<void | boolean> {
|
|
193
|
+
if (record.prepareDispatch === undefined) return this.invokeRecord(owner, record, permit);
|
|
194
|
+
try {
|
|
195
|
+
const preparation = record.prepareDispatch(this.capacityStop.signal);
|
|
196
|
+
return preparation instanceof Promise
|
|
197
|
+
? this.continuePreparingRecord(owner, record, permit, preparation)
|
|
198
|
+
: this.invokeRecord(owner, record, permit, preparation);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
this.failRecord(error, record, permit);
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private continuePreparingRecord(
|
|
206
|
+
owner: ReadyRecord,
|
|
207
|
+
record: ReceiveRecord,
|
|
208
|
+
permit: ApplicationJobPermitPort | undefined,
|
|
209
|
+
preparation: Promise<boolean>
|
|
210
|
+
): Promise<void | boolean> {
|
|
211
|
+
return preparation.then<void | boolean>((accepted) =>
|
|
212
|
+
this.invokeRecord(owner, record, permit, accepted)
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private invokeRecord(
|
|
217
|
+
owner: ReadyRecord,
|
|
218
|
+
record: ReceiveRecord,
|
|
219
|
+
permit: ApplicationJobPermitPort | undefined,
|
|
220
|
+
accepted = true
|
|
232
221
|
): boolean | PromiseLike<void> {
|
|
222
|
+
if (!accepted || this.capacityStop.signal.aborted) {
|
|
223
|
+
releaseApplicationJobPermitTurn(permit);
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
233
226
|
const previous = permit === undefined ? undefined : enterApplicationJobPermitScope(permit);
|
|
234
227
|
let result: void | PromiseLike<void>;
|
|
235
228
|
try {
|
|
@@ -267,6 +260,14 @@ export class ZLinkMeshDispatchPump {
|
|
|
267
260
|
releaseApplicationJobPermitTurn(permit);
|
|
268
261
|
return;
|
|
269
262
|
}
|
|
263
|
+
return this.finishPendingRecord(result, record, permit);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private finishPendingRecord(
|
|
267
|
+
result: Promise<void>,
|
|
268
|
+
record: ReceiveRecord,
|
|
269
|
+
permit: ApplicationJobPermitPort | undefined
|
|
270
|
+
): Promise<void> {
|
|
270
271
|
return Promise.resolve(result).then(
|
|
271
272
|
() => releaseApplicationJobPermitTurn(permit),
|
|
272
273
|
(error) => {
|
|
@@ -323,7 +324,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
323
324
|
}
|
|
324
325
|
this.pendingDomains &= ~ReadyDomain.Infrastructure;
|
|
325
326
|
if ((this.pendingDomains & ReadyDomain.Application) !== 0) {
|
|
326
|
-
|
|
327
|
+
this.scheduleApplicationWorker();
|
|
327
328
|
}
|
|
328
329
|
const lifecycleBudgetExhausted = await this.drainDomain(readyBatch);
|
|
329
330
|
if (lifecycleBudgetExhausted) {
|
|
@@ -360,9 +361,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
360
361
|
claimsDrained += 1;
|
|
361
362
|
const owner = drained.records[index]!;
|
|
362
363
|
this.beginDrain();
|
|
363
|
-
const drain = this.drainClaim(ReadyDomain.Infrastructure, owner, claim
|
|
364
|
-
(error) => this.reportDispatchError(error)
|
|
365
|
-
);
|
|
364
|
+
const drain = this.drainClaim(ReadyDomain.Infrastructure, owner, claim);
|
|
366
365
|
this.activeDrains.add(drain);
|
|
367
366
|
void drain.finally(() => {
|
|
368
367
|
this.draining -= 1;
|
|
@@ -398,98 +397,238 @@ export class ZLinkMeshDispatchPump {
|
|
|
398
397
|
this.draining += 1;
|
|
399
398
|
}
|
|
400
399
|
|
|
401
|
-
/**
|
|
400
|
+
/** Each worker owns claim continuations for its entire lifetime. */
|
|
401
|
+
private async runApplicationWorker(): Promise<void> {
|
|
402
|
+
const readyBatch = this.node.createReadyBatch(1);
|
|
403
|
+
const receiveBatch = this.node.createReceiveBatch(
|
|
404
|
+
MESH_DISPATCH_RECEIVE_CAPACITY,
|
|
405
|
+
this.options.partCapacity ?? DEFAULT_MESH_PART_CAPACITY
|
|
406
|
+
);
|
|
407
|
+
const claimDrain = this.createClaimDrain(receiveBatch);
|
|
408
|
+
try {
|
|
409
|
+
for (;;) {
|
|
410
|
+
// This boundary also keeps the first handler off the receive stack.
|
|
411
|
+
await this.waitForApplicationReady();
|
|
412
|
+
this.beginDrain();
|
|
413
|
+
try {
|
|
414
|
+
while (!this.disposed) {
|
|
415
|
+
readyBatch.reset();
|
|
416
|
+
const drained = this.node.drainReady(
|
|
417
|
+
ReadyDomain.Application,
|
|
418
|
+
readyBatch,
|
|
419
|
+
ZLINK_BACKEND_RECV_DONT_WAIT
|
|
420
|
+
);
|
|
421
|
+
if (!drained.ok || drained.records.length === 0) break;
|
|
422
|
+
if (drained.hasResidue) this.markReady(ReadyDomain.Application);
|
|
423
|
+
const pending = this.dispatchClaim(
|
|
424
|
+
ReadyDomain.Application,
|
|
425
|
+
drained.records[0]!,
|
|
426
|
+
readyBatch.takeClaim(0),
|
|
427
|
+
claimDrain
|
|
428
|
+
);
|
|
429
|
+
if (pending !== undefined) await pending;
|
|
430
|
+
// Returning a claim remains an asynchronous worker boundary without
|
|
431
|
+
// allocating a separate async drain task for a synchronous claim.
|
|
432
|
+
await this.yieldIfNeeded();
|
|
433
|
+
// Empty ready claims count toward the shared pump budget too.
|
|
434
|
+
this.recordsSinceYield += 1;
|
|
435
|
+
const nextTurn = this.yieldIfNeeded();
|
|
436
|
+
if (nextTurn !== undefined) await nextTurn;
|
|
437
|
+
}
|
|
438
|
+
} catch (error) {
|
|
439
|
+
this.reportDispatchError(error);
|
|
440
|
+
} finally {
|
|
441
|
+
readyBatch.reset();
|
|
442
|
+
this.draining -= 1;
|
|
443
|
+
}
|
|
444
|
+
if (this.disposed) return;
|
|
445
|
+
}
|
|
446
|
+
} finally {
|
|
447
|
+
receiveBatch.close();
|
|
448
|
+
readyBatch.close();
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
402
452
|
private async drainClaim(
|
|
403
453
|
domain: number,
|
|
404
454
|
owner: ReadyRecord,
|
|
405
455
|
claim: Claim,
|
|
406
|
-
receiveBatch
|
|
456
|
+
receiveBatch?: ReceiveBatch
|
|
407
457
|
): Promise<void> {
|
|
408
|
-
let ownerReceiveBatch = receiveBatch;
|
|
409
458
|
try {
|
|
410
|
-
|
|
459
|
+
const pending = this.dispatchClaim(domain, owner, claim, this.createClaimDrain(receiveBatch));
|
|
460
|
+
if (pending !== undefined) await pending;
|
|
461
|
+
await this.yieldIfNeeded();
|
|
462
|
+
} catch (error) {
|
|
463
|
+
this.reportDispatchError(error);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
private createClaimDrain(suppliedReceiveBatch?: ReceiveBatch): MeshClaimDrainState {
|
|
468
|
+
const state: MeshClaimDrainState = {
|
|
469
|
+
suppliedReceiveBatch,
|
|
470
|
+
receiveBatch: suppliedReceiveBatch,
|
|
471
|
+
domain: ReadyDomain.None,
|
|
472
|
+
owner: undefined,
|
|
473
|
+
claim: undefined,
|
|
474
|
+
claimPermit: undefined,
|
|
475
|
+
records: undefined,
|
|
476
|
+
index: 0,
|
|
477
|
+
receive: (permit) => this.receiveClaim(state, permit),
|
|
478
|
+
dispatchRecords: () => this.dispatchClaimRecords(state),
|
|
479
|
+
finish: () => this.finishClaim(state)
|
|
480
|
+
};
|
|
481
|
+
return state;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** A synchronous claim finishes without an async wrapper or a Promise. */
|
|
485
|
+
private dispatchClaim(
|
|
486
|
+
domain: number,
|
|
487
|
+
owner: ReadyRecord,
|
|
488
|
+
claim: Claim,
|
|
489
|
+
state: MeshClaimDrainState = this.createClaimDrain()
|
|
490
|
+
): Promise<void> | undefined {
|
|
491
|
+
state.domain = domain;
|
|
492
|
+
state.owner = owner;
|
|
493
|
+
state.claim = claim;
|
|
494
|
+
state.index = 0;
|
|
495
|
+
let pending: Promise<void> | undefined;
|
|
496
|
+
try {
|
|
497
|
+
state.receiveBatch ??= this.node.createReceiveBatch(
|
|
411
498
|
MESH_DISPATCH_RECEIVE_CAPACITY,
|
|
412
499
|
this.options.partCapacity ?? DEFAULT_MESH_PART_CAPACITY
|
|
413
500
|
);
|
|
414
|
-
|
|
415
|
-
owner.ordinaryIngressPreAdmitted === true ? MESH_DISPATCH_RECEIVE_CAPACITY : 1;
|
|
416
|
-
let claimPermit =
|
|
501
|
+
pending =
|
|
417
502
|
owner.terminalCompletion === true ||
|
|
418
503
|
owner.ordinaryIngressPreAdmitted === true ||
|
|
419
504
|
domain === ReadyDomain.Infrastructure
|
|
420
|
-
?
|
|
421
|
-
:
|
|
505
|
+
? state.receive()
|
|
506
|
+
: this.acquirePermit().then(state.receive);
|
|
507
|
+
if (pending !== undefined) return pending.finally(state.finish);
|
|
508
|
+
return undefined;
|
|
509
|
+
} finally {
|
|
510
|
+
if (pending === undefined) state.finish();
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
private receiveClaim(
|
|
515
|
+
state: MeshClaimDrainState,
|
|
516
|
+
permit?: ApplicationJobPermitPort
|
|
517
|
+
): Promise<void> | undefined {
|
|
518
|
+
state.claimPermit = permit;
|
|
519
|
+
if (this.capacityStop.signal.aborted) return undefined;
|
|
520
|
+
const capacity =
|
|
521
|
+
state.owner!.ordinaryIngressPreAdmitted === true ? MESH_DISPATCH_RECEIVE_CAPACITY : 1;
|
|
522
|
+
state.receiveBatch!.reset(capacity);
|
|
523
|
+
const received = state.claim!.recvBatch(state.receiveBatch!, ZLINK_BACKEND_RECV_DONT_WAIT);
|
|
524
|
+
if (!received.ok) return undefined;
|
|
525
|
+
state.records = received.records;
|
|
526
|
+
return this.dispatchClaimRecords(state);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
private dispatchClaimRecords(state: MeshClaimDrainState): Promise<void> | undefined {
|
|
530
|
+
const records = state.records!;
|
|
531
|
+
const owner = state.owner!;
|
|
532
|
+
while (state.index < records.length && !this.disposed) {
|
|
533
|
+
const record = records[state.index++]!;
|
|
534
|
+
const permit = record.applicationJobPermit ?? state.claimPermit;
|
|
535
|
+
if (owner.ordinaryIngressPreAdmitted === true && permit === undefined) {
|
|
536
|
+
throw new Error('Pre-admitted raw ingress record lost its Application Job Queue permit.');
|
|
537
|
+
}
|
|
538
|
+
this.recordsSinceYield += 1;
|
|
539
|
+
if (permit !== undefined) {
|
|
540
|
+
if (state.domain === ReadyDomain.Application && record.applicationJobPermit === undefined)
|
|
541
|
+
permit.markApplicationQueued();
|
|
542
|
+
// Only reservations not transferred to a record remain claim-owned.
|
|
543
|
+
if (permit === state.claimPermit) state.claimPermit = undefined;
|
|
544
|
+
}
|
|
545
|
+
const dispatched = this.dispatchRecord(owner, record, permit);
|
|
546
|
+
if (dispatched === false) {
|
|
547
|
+
if (isNodeOrChannelRecord(record)) this.releaseRecord(record);
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
let terminal: Promise<void>;
|
|
551
|
+
if (dispatched === true) {
|
|
552
|
+
const finished = this.finishRecord(record, permit);
|
|
553
|
+
if (finished === undefined) {
|
|
554
|
+
if (isNodeOrChannelRecord(record)) this.releaseRecord(record);
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
terminal = finished;
|
|
558
|
+
} else {
|
|
559
|
+
terminal = this.continuePendingClaim(dispatched, record, permit);
|
|
560
|
+
}
|
|
561
|
+
if (isNodeOrChannelRecord(record)) {
|
|
562
|
+
// Return the receive claim for the next batch; the existing terminal observer owns record lifetime.
|
|
563
|
+
this.observeRecordTerminal(terminal, record);
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
return terminal.then(state.dispatchRecords);
|
|
567
|
+
}
|
|
568
|
+
return undefined;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
private observeRecordTerminal(terminal: Promise<void>, record: ReceiveRecord): void {
|
|
572
|
+
const tracked = terminal.finally(() => this.releaseRecord(record));
|
|
573
|
+
this.activeDrains.add(tracked);
|
|
574
|
+
void tracked.then(
|
|
575
|
+
() => this.activeDrains.delete(tracked),
|
|
576
|
+
(error) => {
|
|
577
|
+
this.activeDrains.delete(tracked);
|
|
578
|
+
this.reportDispatchError(error, meshDispatchFailureContext(record));
|
|
579
|
+
}
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
private continuePendingClaim(
|
|
584
|
+
dispatched: PromiseLike<void | boolean>,
|
|
585
|
+
record: ReceiveRecord,
|
|
586
|
+
permit: ApplicationJobPermitPort | undefined
|
|
587
|
+
): Promise<void> {
|
|
588
|
+
return Promise.resolve(dispatched).then(
|
|
589
|
+
(accepted) => {
|
|
590
|
+
if (accepted !== false) return this.finishRecord(record, permit);
|
|
591
|
+
},
|
|
592
|
+
(error) => this.failRecord(error, record, permit)
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
private releaseRecord(record: ReceiveRecord): void {
|
|
597
|
+
for (let index = 0; index < record.parts.length; index++) record.parts[index]!.close();
|
|
598
|
+
record.releaseRetainedIngress?.();
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
private finishClaim(state: MeshClaimDrainState): void {
|
|
602
|
+
try {
|
|
422
603
|
try {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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
|
-
}
|
|
604
|
+
// Ownership includes records whose dispatch never began on failure or shutdown.
|
|
605
|
+
const records = state.records;
|
|
606
|
+
if (records !== undefined) {
|
|
607
|
+
for (let recordIndex = 0; recordIndex < records.length; recordIndex += 1) {
|
|
608
|
+
const record = records[recordIndex]!;
|
|
609
|
+
// Started Node and Channel records are cleaned up at their own terminals.
|
|
610
|
+
if (recordIndex < state.index && isNodeOrChannelRecord(record)) continue;
|
|
611
|
+
this.releaseRecord(record);
|
|
482
612
|
}
|
|
483
613
|
}
|
|
484
614
|
} finally {
|
|
485
|
-
claimPermit?.releaseAfterInternalProcessing();
|
|
615
|
+
state.claimPermit?.releaseAfterInternalProcessing();
|
|
486
616
|
}
|
|
487
617
|
} finally {
|
|
488
|
-
|
|
489
|
-
|
|
618
|
+
try {
|
|
619
|
+
state.claim!.release();
|
|
620
|
+
} finally {
|
|
621
|
+
try {
|
|
622
|
+
if (state.suppliedReceiveBatch === undefined) state.receiveBatch?.close();
|
|
623
|
+
} finally {
|
|
624
|
+
// An idle worker must not retain the previous claim's payload or owner.
|
|
625
|
+
state.records = undefined;
|
|
626
|
+
state.owner = undefined;
|
|
627
|
+
state.claim = undefined;
|
|
628
|
+
state.claimPermit = undefined;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
490
631
|
}
|
|
491
|
-
const yieldTurn = this.yieldIfNeeded();
|
|
492
|
-
if (yieldTurn !== undefined) await yieldTurn;
|
|
493
632
|
}
|
|
494
633
|
|
|
495
634
|
/**
|
|
@@ -557,3 +696,12 @@ function yieldToEventLoop(): Promise<void> {
|
|
|
557
696
|
function yieldToTimers(): Promise<void> {
|
|
558
697
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
559
698
|
}
|
|
699
|
+
|
|
700
|
+
function isNodeOrChannelRecord(record: ReceiveRecord): boolean {
|
|
701
|
+
return (
|
|
702
|
+
record.kind === ReceiveKind.NodeSend ||
|
|
703
|
+
record.kind === ReceiveKind.NodeRequest ||
|
|
704
|
+
record.kind === ReceiveKind.ChannelSend ||
|
|
705
|
+
record.kind === ReceiveKind.ChannelRequest
|
|
706
|
+
);
|
|
707
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { constants as osConstants } from 'node:os';
|
|
2
|
-
import {
|
|
2
|
+
import type { PendingOperation } from '../../foundation/operation-registry';
|
|
3
|
+
import { remainingRequestTimeout } from '../../messaging/request-deadline';
|
|
3
4
|
import {
|
|
4
5
|
requireClassicFanoutCompletion,
|
|
5
6
|
ZLinkSubmitStatus
|
|
@@ -179,14 +180,15 @@ export function submitBindingSyncSend(
|
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
export
|
|
183
|
+
export function submitBindingRequest(
|
|
183
184
|
operation: ZLinkBindingRequestOperation,
|
|
184
185
|
payload: unknown,
|
|
185
186
|
timeoutMs: number | undefined,
|
|
186
|
-
recordReceived
|
|
187
|
-
onAdmitted
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
recordReceived: (() => void) | undefined,
|
|
188
|
+
onAdmitted: (() => void) | undefined,
|
|
189
|
+
pending: PendingOperation<unknown>,
|
|
190
|
+
receiver: import('../../foundation/operation-registry').OperationObserver<unknown, unknown>
|
|
191
|
+
): void {
|
|
190
192
|
try {
|
|
191
193
|
let current: ZLinkBindingRequestSubmitOperation | undefined;
|
|
192
194
|
if (Array.isArray(payload)) {
|
|
@@ -200,45 +202,53 @@ export async function submitBindingRequest(
|
|
|
200
202
|
}
|
|
201
203
|
current ??= operation.message(Buffer.alloc(0));
|
|
202
204
|
if (timeoutMs !== undefined) {
|
|
203
|
-
current = current.timeout(
|
|
205
|
+
current = current.timeout(
|
|
206
|
+
Math.min(timeoutMs, remainingRequestTimeout('Request', pending.deadlineMs) ?? timeoutMs)
|
|
207
|
+
);
|
|
204
208
|
}
|
|
205
|
-
|
|
209
|
+
bindingRequestReply(current.submit(), receiver, pending, recordReceived, onAdmitted);
|
|
206
210
|
} catch (error) {
|
|
207
|
-
|
|
211
|
+
receiver.operationFailed(pending.id, translateBindingResultError(error), undefined);
|
|
208
212
|
}
|
|
209
213
|
}
|
|
210
214
|
|
|
211
|
-
export
|
|
215
|
+
export function bindingRequestReply(
|
|
212
216
|
submission: import('@zlink-systems/zlink').RequestSubmission,
|
|
213
|
-
|
|
217
|
+
receiver: import('../../foundation/operation-registry').OperationObserver<unknown, unknown>,
|
|
218
|
+
pending: PendingOperation<unknown>,
|
|
214
219
|
recordReceived?: () => void,
|
|
215
220
|
onAdmitted?: () => void
|
|
216
|
-
):
|
|
217
|
-
|
|
221
|
+
): void {
|
|
222
|
+
// The physical receiver remains reachable independently of admission failure.
|
|
223
|
+
void submission.reply.then(
|
|
224
|
+
(replies) => {
|
|
225
|
+
try {
|
|
226
|
+
recordReceived?.();
|
|
227
|
+
} catch (error) {
|
|
228
|
+
receiver.operationFailed(pending.id, error, undefined);
|
|
229
|
+
}
|
|
230
|
+
receiver.operationCompleted(pending.id, replies, undefined);
|
|
231
|
+
},
|
|
232
|
+
(error) => receiver.operationFailed(pending.id, translateBindingResultError(error), undefined)
|
|
233
|
+
);
|
|
218
234
|
if (submission.result === SubmitResult.Backpressured) {
|
|
235
|
+
void submission.admitted.then(
|
|
236
|
+
() => {
|
|
237
|
+
try {
|
|
238
|
+
onAdmitted?.();
|
|
239
|
+
} catch (error) {
|
|
240
|
+
receiver.operationFailed(pending.id, error, undefined);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
(error) => receiver.operationFailed(pending.id, error, undefined)
|
|
244
|
+
);
|
|
245
|
+
} else {
|
|
219
246
|
try {
|
|
220
|
-
|
|
221
|
-
Promise.all([submission.admitted.then(() => onAdmitted?.()), reply]),
|
|
222
|
-
'Request',
|
|
223
|
-
deadlineMs
|
|
224
|
-
);
|
|
225
|
-
recordReceived?.();
|
|
226
|
-
return replies;
|
|
247
|
+
onAdmitted?.();
|
|
227
248
|
} catch (error) {
|
|
228
|
-
|
|
229
|
-
(parts) => {
|
|
230
|
-
recordReceived?.();
|
|
231
|
-
closeBindingReply(parts);
|
|
232
|
-
},
|
|
233
|
-
() => undefined
|
|
234
|
-
);
|
|
235
|
-
throw error;
|
|
249
|
+
receiver.operationFailed(pending.id, error, undefined);
|
|
236
250
|
}
|
|
237
251
|
}
|
|
238
|
-
onAdmitted?.();
|
|
239
|
-
const replies = await reply;
|
|
240
|
-
recordReceived?.();
|
|
241
|
-
return replies;
|
|
242
252
|
}
|
|
243
253
|
|
|
244
254
|
export function closeBindingReply(
|