@zlink-systems/framework 0.21.0 → 0.22.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/Common/ZLinkMessage.js +5 -5
- package/dist/contracts/Configuration/CodecContentType.js +5 -7
- package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
- package/dist/contracts/Configuration/EndpointNotation.js +4 -8
- package/dist/contracts/Configuration/Registration.js +14 -11
- package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
- package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
- package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
- package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/location-store-integration.js +16 -16
- package/dist/nest-integration.js +17 -11
- package/dist/runtime/abort.js +9 -5
- package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
- package/dist/runtime/actors/actor-authority-publication.js +18 -17
- package/dist/runtime/actors/actor-client.js +83 -63
- package/dist/runtime/actors/actor-context.js +24 -18
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-local-native-join.js +18 -19
- package/dist/runtime/actors/actor-mailbox.js +1 -1
- package/dist/runtime/actors/actor-message-follow-context.js +24 -21
- package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
- package/dist/runtime/actors/actor-remote-joiner.js +20 -17
- package/dist/runtime/actors/actor-remote-wire.js +6 -7
- package/dist/runtime/actors/actor-runtime-state.js +87 -81
- package/dist/runtime/actors/actor-transfer-registry.js +3 -5
- package/dist/runtime/actors/bound-session-wire.js +14 -9
- package/dist/runtime/actors/deferred-join-accepted-journal.js +158 -124
- package/dist/runtime/actors/index.js +2 -5
- package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
- package/dist/runtime/actors/post-commit-actor-location.js +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
- package/dist/runtime/admission.js +2 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
- package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
- package/dist/runtime/backend/mesh-completion-table.js +1 -3
- package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
- package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +116 -113
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
- package/dist/runtime/backend/runtime-message.js +3 -3
- package/dist/runtime/backend/runtime-values.d.ts +2 -2
- package/dist/runtime/backend/runtime-values.js +4 -5
- package/dist/runtime/channels/channel-clients.js +27 -24
- package/dist/runtime/channels/channel-dispatch-pipeline.js +10 -18
- package/dist/runtime/channels/channel-dispatch-services.js +7 -4
- package/dist/runtime/channels/channel-dispatchers.js +9 -9
- package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
- package/dist/runtime/channels/channel-envelope.js +83 -47
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-receive-loops.js +20 -22
- package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
- package/dist/runtime/channels/channel-runtime-manager.js +18 -9
- package/dist/runtime/channels/channel-socket-registry.js +126 -123
- package/dist/runtime/channels/channel-transports.js +43 -33
- package/dist/runtime/channels/client-server-location-runtime.js +32 -40
- package/dist/runtime/channels/client-server-service-wire.js +29 -22
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -7
- package/dist/runtime/channels/fanout-location-runtime.js +34 -47
- package/dist/runtime/channels/fanout-service-wire.js +3 -5
- package/dist/runtime/channels/local-spot-route-transport.js +7 -1
- package/dist/runtime/channels/route-member-snapshot.js +3 -3
- package/dist/runtime/channels/source-spot-router.js +6 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
- package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +47 -39
- package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
- package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
- package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
- package/dist/runtime/execution/index.js +7 -6
- package/dist/runtime/execution/serial-execution-queue.js +12 -18
- package/dist/runtime/execution/state-lane.js +2 -2
- package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -23
- package/dist/runtime/foundation/event-loop-resources.js +4 -4
- package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +136 -136
- package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
- package/dist/runtime/foundation/runtime-state-projections.js +22 -11
- package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
- package/dist/runtime/foundation/service-discovery-registry.js +35 -33
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
- package/dist/runtime/foundation/service-liveness-registry.js +16 -12
- package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
- package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
- package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.js +416 -438
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.js +96 -95
- package/dist/runtime/foundation/service-weighted-selection.js +6 -11
- package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
- package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
- package/dist/runtime/framework-errors-internal.js +7 -10
- package/dist/runtime/handlers/handler-instance-scope.js +4 -5
- package/dist/runtime/handlers/index.js +3 -1
- package/dist/runtime/host/actor-packet-relay.js +74 -70
- package/dist/runtime/host/actor-placement-coordinator.js +29 -31
- package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
- package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
- package/dist/runtime/host/actor-transfer-runtime.js +176 -153
- package/dist/runtime/host/application-job-queue.js +18 -22
- package/dist/runtime/host/bound-session-relay.js +3 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
- package/dist/runtime/host/host-capacity-status.js +8 -4
- package/dist/runtime/host/index.js +244 -227
- package/dist/runtime/host/instance-activation-authority.js +93 -96
- package/dist/runtime/host/location-runtime-owner.js +16 -14
- package/dist/runtime/host/mesh-router-resolver.js +11 -13
- package/dist/runtime/host/relocation-direct-transfer.js +10 -9
- package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
- package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
- package/dist/runtime/host/remote-bound-session-relay.js +97 -73
- package/dist/runtime/host/route-mesh-runtime.js +64 -69
- package/dist/runtime/host/runtime-shutdown.js +1 -2
- package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
- package/dist/runtime/host/spot-address-transport.js +69 -71
- package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
- package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
- package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
- package/dist/runtime/locations/actor-location-claims.js +26 -20
- package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
- package/dist/runtime/locations/authority-key-codec.js +7 -7
- package/dist/runtime/locations/auto-connect-loop.js +3 -3
- package/dist/runtime/locations/auto-connect-planner.js +25 -19
- package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
- package/dist/runtime/locations/in-memory-authority-store.js +128 -118
- package/dist/runtime/locations/in-memory-location-store.js +195 -168
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
- package/dist/runtime/locations/key-codec.js +1 -1
- package/dist/runtime/locations/lease-tracker.js +23 -21
- package/dist/runtime/locations/lifecycle.js +4 -5
- package/dist/runtime/locations/location-store-repository.js +368 -324
- package/dist/runtime/locations/opaque-record-key.js +2 -2
- package/dist/runtime/locations/resolvers.js +73 -82
- package/dist/runtime/locations/runtime.js +68 -63
- package/dist/runtime/locations/spot-location-claims.js +39 -35
- package/dist/runtime/messaging/framework-json-v1.js +7 -7
- package/dist/runtime/messaging/packet-name.js +7 -6
- package/dist/runtime/messaging/payload-codec.js +21 -18
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
- package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
- package/dist/runtime/routing-id.js +3 -5
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
- package/dist/runtime/spots/index.js +208 -219
- package/dist/runtime/spots/spot-activation-registry.js +15 -14
- package/dist/runtime/spots/spot-activation-state.js +17 -15
- package/dist/runtime/spots/spot-activation.js +33 -16
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
- package/dist/runtime/spots/spot-actor-membership.js +1 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +23 -20
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -10
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
- package/dist/runtime/spots/spot-closing.js +3 -7
- package/dist/runtime/spots/spot-context.js +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +13 -14
- package/dist/runtime/spots/spot-handle.js +6 -3
- package/dist/runtime/spots/spot-handler-registry.js +12 -12
- package/dist/runtime/spots/spot-manager-public.js +5 -6
- package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
- package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +74 -85
- package/dist/runtime/spots/spot-outbound.js +10 -14
- package/dist/runtime/spots/spot-remote-codec.js +22 -26
- package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
- package/dist/runtime/spots/spot-route-packet-dispatch.js +16 -14
- package/dist/runtime/spots/spot-route-replies.js +4 -6
- package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
- package/dist/runtime/spots/spot-serial-executor.js +5 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
- package/dist/runtime/spots/spot-subscription-dispatch.js +5 -5
- package/dist/runtime/spots/spot-timer.js +25 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +98 -107
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +18 -16
- package/dist/runtime/streams/bound-session-service.js +8 -9
- package/dist/runtime/streams/index.js +20 -19
- package/dist/runtime/streams/managed-stream.js +32 -30
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.js +29 -18
- package/dist/runtime/streams/session-actor-coordinator.js +34 -37
- package/dist/runtime/streams/session-context.js +30 -28
- package/dist/runtime/streams/session-provider.js +2 -2
- package/dist/runtime/streams/session-serial-executor.js +1 -2
- package/dist/runtime/streams/stream-frame-factory.js +11 -5
- package/dist/runtime/streams/stream-session-runtime.js +70 -66
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +2 -2
- package/src/contracts/Channels/RouteCalls.ts +6 -1
- package/src/contracts/Common/ZLinkMessage.ts +5 -5
- package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
- package/src/contracts/Configuration/Builders.ts +14 -14
- package/src/contracts/Configuration/CodecContentType.ts +8 -10
- package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
- package/src/contracts/Configuration/EndpointNotation.ts +11 -11
- package/src/contracts/Configuration/ObjectRoles.ts +1 -3
- package/src/contracts/Configuration/Registration.ts +46 -17
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
- package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
- package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
- package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
- package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
- package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
- package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
- package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -6
- package/src/contracts/Errors/index.ts +1 -4
- package/src/contracts/Handlers/Attributes.ts +15 -9
- package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
- package/src/contracts/Handlers/JsonContract.ts +53 -19
- package/src/contracts/Locations/ActorTransfer.ts +1 -5
- package/src/contracts/Locations/Authority.ts +4 -11
- package/src/contracts/Locations/Keys.ts +6 -1
- package/src/contracts/Locations/Options.ts +3 -2
- package/src/contracts/Locations/RelocationStore.ts +1 -4
- package/src/contracts/Locations/Resolvers.ts +5 -5
- package/src/contracts/Locations/RuntimeQuery.ts +6 -2
- package/src/contracts/Locations/Stores.ts +1 -2
- package/src/contracts/Locations/index.ts +2 -8
- package/src/contracts/RouteMesh/Contracts.ts +1 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
- package/src/contracts/Spots/Contracts.ts +2 -8
- package/src/contracts/Spots/SpotKind.ts +16 -8
- package/src/contracts/Spots/ZLinkSpot.ts +8 -11
- package/src/contracts/Streams/IZLinkSession.ts +0 -1
- package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
- package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
- package/src/internal.ts +5 -4
- package/src/location-store-integration.ts +24 -16
- package/src/nest-integration.ts +40 -25
- package/src/runtime/abort.ts +10 -4
- package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
- package/src/runtime/actors/actor-authority-publication.ts +92 -77
- package/src/runtime/actors/actor-client.ts +162 -133
- package/src/runtime/actors/actor-context.ts +138 -130
- package/src/runtime/actors/actor-creation.ts +47 -44
- package/src/runtime/actors/actor-execution-context.ts +6 -4
- package/src/runtime/actors/actor-handoff.ts +269 -293
- package/src/runtime/actors/actor-join-deferred-scope.ts +5 -4
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
- package/src/runtime/actors/actor-local-native-join.ts +131 -159
- package/src/runtime/actors/actor-mailbox.ts +16 -19
- package/src/runtime/actors/actor-message-follow-context.ts +46 -36
- package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
- package/src/runtime/actors/actor-remote-joiner.ts +50 -54
- package/src/runtime/actors/actor-remote-wire.ts +9 -13
- package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
- package/src/runtime/actors/actor-runtime-state.ts +127 -124
- package/src/runtime/actors/actor-transfer-registry.ts +9 -14
- package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
- package/src/runtime/actors/bound-session-wire.ts +37 -17
- package/src/runtime/actors/deferred-join-accepted-journal.ts +351 -320
- package/src/runtime/actors/index.ts +43 -86
- package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
- package/src/runtime/actors/post-commit-actor-location.ts +30 -23
- package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
- package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
- package/src/runtime/admission.ts +9 -9
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
- package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
- package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
- package/src/runtime/backend/contracts/index.ts +73 -52
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
- package/src/runtime/backend/mesh-completion-table.ts +6 -9
- package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
- package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
- package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
- package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +335 -383
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
- package/src/runtime/backend/runtime-message.ts +5 -3
- package/src/runtime/backend/runtime-values.ts +10 -7
- package/src/runtime/channels/channel-autoconnect.ts +1 -4
- package/src/runtime/channels/channel-clients.ts +93 -73
- package/src/runtime/channels/channel-dispatch-pipeline.ts +40 -42
- package/src/runtime/channels/channel-dispatch-services.ts +51 -49
- package/src/runtime/channels/channel-dispatchers.ts +152 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
- package/src/runtime/channels/channel-envelope.ts +256 -150
- package/src/runtime/channels/channel-multipart.ts +13 -5
- package/src/runtime/channels/channel-outbound-operations.ts +37 -41
- package/src/runtime/channels/channel-receive-loops.ts +102 -98
- package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
- package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
- package/src/runtime/channels/channel-runtime-manager.ts +63 -37
- package/src/runtime/channels/channel-socket-options.ts +3 -10
- package/src/runtime/channels/channel-socket-registry.ts +331 -273
- package/src/runtime/channels/channel-transports.ts +215 -197
- package/src/runtime/channels/client-server-location-runtime.ts +116 -100
- package/src/runtime/channels/client-server-service-wire.ts +37 -36
- package/src/runtime/channels/dispatch-error-reporter.ts +11 -8
- package/src/runtime/channels/fanout-location-runtime.ts +91 -94
- package/src/runtime/channels/fanout-service-wire.ts +5 -12
- package/src/runtime/channels/handler-filter-scope.ts +1 -4
- package/src/runtime/channels/index.ts +1 -4
- package/src/runtime/channels/local-spot-route-transport.ts +20 -5
- package/src/runtime/channels/route-member-snapshot.ts +11 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
- package/src/runtime/channels/source-spot-router.ts +26 -22
- package/src/runtime/channels/spot-direct-envelope.ts +10 -8
- package/src/runtime/channels/spot-node-route-transport.ts +13 -16
- package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
- package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
- package/src/runtime/codecs/index.ts +3 -2
- package/src/runtime/diagnostics/flow-context.ts +12 -3
- package/src/runtime/diagnostics/index.ts +96 -61
- package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
- package/src/runtime/diagnostics/message-flow.ts +95 -76
- package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
- package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
- package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
- package/src/runtime/execution/index.ts +18 -26
- package/src/runtime/execution/serial-execution-queue.ts +31 -40
- package/src/runtime/execution/state-lane.ts +2 -2
- package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -51
- package/src/runtime/foundation/event-loop-resources.ts +8 -4
- package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
- package/src/runtime/foundation/operation-identity.ts +1 -2
- package/src/runtime/foundation/operation-registry.ts +8 -2
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +312 -385
- package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
- package/src/runtime/foundation/runtime-state-projections.ts +24 -23
- package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
- package/src/runtime/foundation/service-discovery-registry.ts +67 -59
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
- package/src/runtime/foundation/service-liveness-registry.ts +18 -13
- package/src/runtime/foundation/service-mailbox.ts +14 -14
- package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
- package/src/runtime/foundation/service-metadata-codec.ts +2 -9
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
- package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
- package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
- package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
- package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1174 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +157 -159
- package/src/runtime/foundation/service-weighted-selection.ts +9 -15
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
- package/src/runtime/framework-errors-internal.ts +31 -30
- package/src/runtime/handlers/handler-instance-scope.ts +18 -29
- package/src/runtime/handlers/index.ts +18 -8
- package/src/runtime/host/actor-packet-relay.ts +290 -261
- package/src/runtime/host/actor-placement-coordinator.ts +165 -150
- package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
- package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
- package/src/runtime/host/actor-transfer-runtime.ts +391 -395
- package/src/runtime/host/application-job-queue.ts +32 -48
- package/src/runtime/host/bound-session-relay.ts +7 -9
- package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
- package/src/runtime/host/host-capacity-status.ts +10 -9
- package/src/runtime/host/index.ts +861 -789
- package/src/runtime/host/instance-activation-authority.ts +125 -143
- package/src/runtime/host/location-runtime-owner.ts +38 -26
- package/src/runtime/host/mesh-router-resolver.ts +30 -23
- package/src/runtime/host/relocation-direct-transfer.ts +15 -15
- package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
- package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
- package/src/runtime/host/remote-bound-session-relay.ts +274 -247
- package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
- package/src/runtime/host/route-mesh-runtime.ts +227 -181
- package/src/runtime/host/runtime-shutdown.ts +4 -3
- package/src/runtime/host/service-relocation-control.ts +14 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
- package/src/runtime/host/spot-address-transport.ts +284 -237
- package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
- package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
- package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
- package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
- package/src/runtime/locations/actor-location-claims.ts +61 -49
- package/src/runtime/locations/actor-session-route-claims.ts +1 -4
- package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
- package/src/runtime/locations/authority-key-codec.ts +13 -10
- package/src/runtime/locations/auto-connect-loop.ts +14 -11
- package/src/runtime/locations/auto-connect-planner.ts +42 -31
- package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
- package/src/runtime/locations/canonical-codec.ts +3 -1
- package/src/runtime/locations/creation-operation-id.ts +4 -3
- package/src/runtime/locations/domain-store-contract.ts +13 -7
- package/src/runtime/locations/in-memory-authority-store.ts +232 -199
- package/src/runtime/locations/in-memory-location-store.ts +432 -250
- package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
- package/src/runtime/locations/internal-store-contracts.ts +95 -38
- package/src/runtime/locations/key-codec.ts +3 -4
- package/src/runtime/locations/lease-tracker.ts +36 -27
- package/src/runtime/locations/lifecycle-runtime.ts +15 -3
- package/src/runtime/locations/lifecycle.ts +33 -28
- package/src/runtime/locations/location-store-repository.ts +1329 -1185
- package/src/runtime/locations/opaque-record-key.ts +4 -9
- package/src/runtime/locations/resolvers.ts +201 -178
- package/src/runtime/locations/runtime.ts +251 -159
- package/src/runtime/locations/spot-location-claims.ts +110 -112
- package/src/runtime/messaging/creation-payload-codec.ts +4 -1
- package/src/runtime/messaging/framework-json-v1.ts +34 -15
- package/src/runtime/messaging/packet-name.ts +8 -6
- package/src/runtime/messaging/payload-codec.ts +70 -50
- package/src/runtime/messaging/submission-result.ts +6 -9
- package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/routing-id.ts +10 -7
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
- package/src/runtime/spots/index.ts +593 -563
- package/src/runtime/spots/spot-activation-registry.ts +38 -34
- package/src/runtime/spots/spot-activation-state.ts +43 -51
- package/src/runtime/spots/spot-activation.ts +179 -116
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
- package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
- package/src/runtime/spots/spot-actor-membership.ts +25 -27
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +184 -153
- package/src/runtime/spots/spot-actor-packet-drain.ts +54 -42
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
- package/src/runtime/spots/spot-closing.ts +11 -12
- package/src/runtime/spots/spot-context.ts +46 -26
- package/src/runtime/spots/spot-entry-activation.ts +84 -65
- package/src/runtime/spots/spot-handle.ts +17 -15
- package/src/runtime/spots/spot-handler-registry.ts +44 -31
- package/src/runtime/spots/spot-location-claim.ts +5 -4
- package/src/runtime/spots/spot-manager-public.ts +62 -82
- package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
- package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
- package/src/runtime/spots/spot-node-runtime-manager.ts +230 -221
- package/src/runtime/spots/spot-outbound.ts +47 -59
- package/src/runtime/spots/spot-publisher-transport.ts +5 -4
- package/src/runtime/spots/spot-remote-codec.ts +66 -65
- package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
- package/src/runtime/spots/spot-route-packet-dispatch.ts +128 -95
- package/src/runtime/spots/spot-route-replies.ts +23 -24
- package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
- package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +11 -17
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
- package/src/runtime/spots/spot-routing-internal.ts +1 -4
- package/src/runtime/spots/spot-runtime-ports.ts +5 -5
- package/src/runtime/spots/spot-serial-executor.ts +5 -9
- package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
- package/src/runtime/spots/spot-subscription-dispatch.ts +56 -46
- package/src/runtime/spots/spot-timer.ts +98 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +277 -235
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +7 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +53 -51
- package/src/runtime/streams/bound-session-response-target.ts +29 -8
- package/src/runtime/streams/bound-session-service.ts +39 -39
- package/src/runtime/streams/index.ts +176 -100
- package/src/runtime/streams/managed-stream.ts +98 -87
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +73 -43
- package/src/runtime/streams/session-actor-coordinator.ts +97 -89
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +66 -48
- package/src/runtime/streams/session-provider.ts +5 -7
- package/src/runtime/streams/session-serial-executor.ts +7 -6
- package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
- package/src/runtime/streams/stream-frame-factory.ts +55 -38
- package/src/runtime/streams/stream-session-runtime.ts +268 -210
- package/src/runtime/workers/index.ts +68 -29
|
@@ -54,9 +54,7 @@ import {
|
|
|
54
54
|
} from './fanout-service-wire';
|
|
55
55
|
import type { ZLinkChannelEnvelopeHeader } from './channel-envelope';
|
|
56
56
|
import type { ApplicationJobQueue } from '../host/application-job-queue';
|
|
57
|
-
import {
|
|
58
|
-
isBackendRequestTimeoutError
|
|
59
|
-
} from '../backend/runtime-values';
|
|
57
|
+
import { isBackendRequestTimeoutError } from '../backend/runtime-values';
|
|
60
58
|
|
|
61
59
|
const MAX_LIFECYCLE_GENERATION = 0x7fff_ffff_ffff_ffffn;
|
|
62
60
|
const CLIENT_SERVER_PROBE_INTERVAL_MS = 5_000;
|
|
@@ -76,8 +74,7 @@ export interface ZLinkClientServerConnectionCallbacks {
|
|
|
76
74
|
readonly onTerminated: (routingId: string | undefined, endpoint: string) => void;
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
type ClientServerDiscoveryDescriptor =
|
|
80
|
-
Parameters<ServiceDiscoveryRegistry['admitClientServer']>[0];
|
|
77
|
+
type ClientServerDiscoveryDescriptor = Parameters<ServiceDiscoveryRegistry['admitClientServer']>[0];
|
|
81
78
|
|
|
82
79
|
interface ClientServerPhysicalConnection {
|
|
83
80
|
readonly channelName: string;
|
|
@@ -122,44 +119,56 @@ export class ZLinkChannelSocketRegistry {
|
|
|
122
119
|
private readonly publishers = new Map<string, ZLinkBackendPublisherSocket>();
|
|
123
120
|
private readonly routeRouters = new Map<string, ZLinkBackendRouterSocket>();
|
|
124
121
|
private readonly routeMembers = new ZLinkRouteMemberSnapshot();
|
|
125
|
-
private readonly clientServerIdentities = new Map<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
private readonly clientServerIdentities = new Map<
|
|
123
|
+
string,
|
|
124
|
+
{
|
|
125
|
+
readonly serverRid: string;
|
|
126
|
+
readonly lifecycleGeneration: bigint;
|
|
127
|
+
}
|
|
128
|
+
>();
|
|
129
|
+
private readonly clientServerConnections = new Map<string, ClientServerPhysicalConnection>();
|
|
131
130
|
private readonly clientServerDiscovery = new ServiceDiscoveryRegistry();
|
|
132
|
-
private readonly clientServerReadyIdentities = new Map<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
private readonly clientServerReadyIdentities = new Map<
|
|
132
|
+
string,
|
|
133
|
+
{
|
|
134
|
+
readonly channelName: string;
|
|
135
|
+
readonly serverRoutingId: string;
|
|
136
|
+
readonly lifecycleGeneration: bigint;
|
|
137
|
+
}
|
|
138
|
+
>();
|
|
139
|
+
private readonly clientServerServerDescriptors = new Map<
|
|
140
|
+
string,
|
|
141
|
+
ZLinkClientServerServerDescriptor
|
|
142
|
+
>();
|
|
139
143
|
private readonly clientServerPublicWeights = new Map<string, number>();
|
|
140
144
|
private readonly routeMeshPublicWeights = new Map<string, number>();
|
|
141
145
|
private readonly clientServerAdmittedClients = new Map<string, Set<RoutingId>>();
|
|
142
|
-
private readonly clientServerServerPeers = new Map<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
private readonly clientServerServerPeers = new Map<
|
|
147
|
+
string,
|
|
148
|
+
{
|
|
149
|
+
readonly channelName: string;
|
|
150
|
+
readonly routingId: RoutingId;
|
|
151
|
+
readonly physicalConnectionId: symbol;
|
|
152
|
+
readonly normalizedEffectiveMaxMessageBytes: number;
|
|
153
|
+
nextProbeAt: number;
|
|
154
|
+
deadlineAt: number;
|
|
155
|
+
outstandingProbeId?: bigint;
|
|
156
|
+
}
|
|
157
|
+
>();
|
|
151
158
|
private readonly ownedMonitors = new Set<ZLinkBackendSocketMonitor>();
|
|
152
|
-
private readonly fanoutConnections =
|
|
153
|
-
new Map<string, FanoutPublisherConnection>();
|
|
159
|
+
private readonly fanoutConnections = new Map<string, FanoutPublisherConnection>();
|
|
154
160
|
private readonly fanoutPublisherNextBeacon = new Map<string, number>();
|
|
155
161
|
private clientServerLivenessTimer?: NodeJS.Timeout;
|
|
156
162
|
private nextClientServerProbeId = 1n;
|
|
157
|
-
private readonly clientServerMonitorHandlers =
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
private readonly
|
|
162
|
-
|
|
163
|
+
private readonly clientServerMonitorHandlers = new Map<
|
|
164
|
+
string,
|
|
165
|
+
Set<(event: ZLinkBackendSocketMonitorEvent) => void>
|
|
166
|
+
>();
|
|
167
|
+
private readonly fanoutMonitorHandlers = new Map<
|
|
168
|
+
string,
|
|
169
|
+
Set<(event: ZLinkBackendSocketMonitorEvent) => void>
|
|
170
|
+
>();
|
|
171
|
+
private readonly fanoutTopologyHandlers = new Map<string, Set<() => void>>();
|
|
163
172
|
|
|
164
173
|
constructor(
|
|
165
174
|
private readonly registration: ZLinkFrameworkRegistration,
|
|
@@ -177,18 +186,19 @@ export class ZLinkChannelSocketRegistry {
|
|
|
177
186
|
);
|
|
178
187
|
const sockets = [
|
|
179
188
|
...this.clientDealers.values(),
|
|
180
|
-
...clientServerConnections.map(value => value.dealer),
|
|
181
|
-
...[...this.fanoutConnections.values()].map(value => value.subscriber),
|
|
189
|
+
...clientServerConnections.map((value) => value.dealer),
|
|
190
|
+
...[...this.fanoutConnections.values()].map((value) => value.subscriber),
|
|
182
191
|
...this.channelRouters.values(),
|
|
183
192
|
...this.publishers.values(),
|
|
184
193
|
...this.routeRouters.values()
|
|
185
194
|
];
|
|
186
195
|
for (const socket of new Set<ReceiveFlowSocket>([
|
|
187
196
|
...this.clientDealers.values(),
|
|
188
|
-
...clientServerConnections.map(value => value.dealer),
|
|
197
|
+
...clientServerConnections.map((value) => value.dealer),
|
|
189
198
|
...this.channelRouters.values(),
|
|
190
199
|
...this.routeRouters.values()
|
|
191
|
-
]))
|
|
200
|
+
]))
|
|
201
|
+
this.unregisterReceiveFlowSocket(socket);
|
|
192
202
|
this.clientDealers.clear();
|
|
193
203
|
this.clientServerConnections.clear();
|
|
194
204
|
this.clientServerReadyIdentities.clear();
|
|
@@ -224,7 +234,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
224
234
|
if (errors.length > 1) throw new AggregateError(errors, 'Channel socket cleanup failed.');
|
|
225
235
|
}
|
|
226
236
|
|
|
227
|
-
|
|
228
237
|
clientDealer(channelName: string): ZLinkBackendDealerSocket {
|
|
229
238
|
const existing = this.clientDealers.get(channelName);
|
|
230
239
|
if (existing !== undefined) {
|
|
@@ -259,15 +268,16 @@ export class ZLinkChannelSocketRegistry {
|
|
|
259
268
|
throw new ZLinkConfigurationException(`Channel server '${channelName}' is not registered.`);
|
|
260
269
|
}
|
|
261
270
|
if (channel.server.bind === undefined) {
|
|
262
|
-
throw new ZLinkConfigurationException(
|
|
271
|
+
throw new ZLinkConfigurationException(
|
|
272
|
+
`Channel server '${channelName}' does not define a bind endpoint.`
|
|
273
|
+
);
|
|
263
274
|
}
|
|
264
275
|
|
|
265
276
|
const router = this.adapter.createRouterSocket(this.context);
|
|
266
277
|
this.registerReceiveFlowSocket(router);
|
|
267
278
|
router.setChannelName(channelName);
|
|
268
279
|
const identity = this.clientServerIdentities.get(channelName) ?? {
|
|
269
|
-
serverRid: channel.server.routingId
|
|
270
|
-
?? `${channel.routingIdPrefix ?? 'cs'}-${randomUUID()}`,
|
|
280
|
+
serverRid: channel.server.routingId ?? `${channel.routingIdPrefix ?? 'cs'}-${randomUUID()}`,
|
|
271
281
|
lifecycleGeneration: newLifecycleGeneration()
|
|
272
282
|
};
|
|
273
283
|
this.clientServerIdentities.set(channelName, identity);
|
|
@@ -282,11 +292,14 @@ export class ZLinkChannelSocketRegistry {
|
|
|
282
292
|
this.ownedMonitors.add(monitor);
|
|
283
293
|
monitor.onEvent((event) => {
|
|
284
294
|
if (event.routingId === undefined) return;
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
295
|
+
if (
|
|
296
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.Disconnected &&
|
|
297
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.Closed &&
|
|
298
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.HandshakeFailedNoDetail &&
|
|
299
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.HandshakeFailedProtocol &&
|
|
300
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.HandshakeFailedAuth
|
|
301
|
+
)
|
|
302
|
+
return;
|
|
290
303
|
const routingId = String(event.routingId);
|
|
291
304
|
this.clientServerServerPeers.delete(clientServerServerPeerKey(channelName, routingId));
|
|
292
305
|
this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
|
|
@@ -411,9 +424,12 @@ export class ZLinkChannelSocketRegistry {
|
|
|
411
424
|
this.ensureClientServerLivenessTimer();
|
|
412
425
|
try {
|
|
413
426
|
monitor.onEvent((event) => {
|
|
414
|
-
if (
|
|
415
|
-
|
|
416
|
-
|
|
427
|
+
if (
|
|
428
|
+
![...connection.aliases].some(
|
|
429
|
+
(alias) => this.clientServerConnections.get(alias) === connection
|
|
430
|
+
)
|
|
431
|
+
)
|
|
432
|
+
return;
|
|
417
433
|
for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? []) {
|
|
418
434
|
handler(event);
|
|
419
435
|
}
|
|
@@ -428,15 +444,20 @@ export class ZLinkChannelSocketRegistry {
|
|
|
428
444
|
}
|
|
429
445
|
return;
|
|
430
446
|
}
|
|
431
|
-
if (
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
447
|
+
if (
|
|
448
|
+
event.nativeEvent === ZLinkSocketNativeEventType.Disconnected ||
|
|
449
|
+
event.nativeEvent === ZLinkSocketNativeEventType.Closed ||
|
|
450
|
+
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedNoDetail ||
|
|
451
|
+
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedProtocol ||
|
|
452
|
+
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedAuth
|
|
453
|
+
) {
|
|
454
|
+
if (
|
|
455
|
+
connection.terminationRequested &&
|
|
456
|
+
(event.remoteAddr !== connection.endpoint ||
|
|
457
|
+
(event.nativeEvent !== ZLinkSocketNativeEventType.Disconnected &&
|
|
458
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.Closed))
|
|
459
|
+
)
|
|
460
|
+
return;
|
|
440
461
|
connection.physicalConnectionId = Symbol(connectionId);
|
|
441
462
|
connection.admissionAttempt = undefined;
|
|
442
463
|
if (connection.readyConnectionId !== undefined) {
|
|
@@ -483,11 +504,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
483
504
|
);
|
|
484
505
|
current.readyConnectionId = undefined;
|
|
485
506
|
const replacement = current.aliases.values().next().value as string | undefined;
|
|
486
|
-
if (
|
|
487
|
-
&&
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
507
|
+
if (
|
|
508
|
+
replacement !== undefined &&
|
|
509
|
+
current.admittedDescriptor !== undefined &&
|
|
510
|
+
this.clientServerDiscovery.admitClientServer(current.admittedDescriptor, replacement)
|
|
511
|
+
) {
|
|
491
512
|
current.readyConnectionId = replacement;
|
|
492
513
|
this.clientServerReadyIdentities.set(replacement, {
|
|
493
514
|
channelName: current.admittedDescriptor.channelName,
|
|
@@ -512,13 +533,10 @@ export class ZLinkChannelSocketRegistry {
|
|
|
512
533
|
this.ownedMonitors.delete(current.monitor);
|
|
513
534
|
this.unregisterReceiveFlowSocket(current.dealer);
|
|
514
535
|
current.readablePoller.dispose();
|
|
515
|
-
const results = await Promise.allSettled([
|
|
516
|
-
current.monitor.dispose(),
|
|
517
|
-
current.dealer.dispose()
|
|
518
|
-
]);
|
|
536
|
+
const results = await Promise.allSettled([current.monitor.dispose(), current.dealer.dispose()]);
|
|
519
537
|
const errors = results
|
|
520
538
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
521
|
-
.map(result => result.reason);
|
|
539
|
+
.map((result) => result.reason);
|
|
522
540
|
if (errors.length === 1) throw errors[0];
|
|
523
541
|
if (errors.length > 1) {
|
|
524
542
|
throw new AggregateError(errors, `ClientServer connection '${connectionId}' cleanup failed.`);
|
|
@@ -539,11 +557,12 @@ export class ZLinkChannelSocketRegistry {
|
|
|
539
557
|
if (admitted) connection.admittedDescriptor = descriptor;
|
|
540
558
|
return admitted;
|
|
541
559
|
}
|
|
542
|
-
const duplicateId = [...this.clientServerReadyIdentities]
|
|
543
|
-
|
|
544
|
-
identity.channelName === descriptor.channelName
|
|
545
|
-
|
|
546
|
-
|
|
560
|
+
const duplicateId = [...this.clientServerReadyIdentities].find(
|
|
561
|
+
([, identity]) =>
|
|
562
|
+
identity.channelName === descriptor.channelName &&
|
|
563
|
+
identity.serverRoutingId === descriptor.serverRoutingId &&
|
|
564
|
+
identity.lifecycleGeneration === descriptor.lifecycleGeneration
|
|
565
|
+
)?.[0];
|
|
547
566
|
if (duplicateId !== undefined) {
|
|
548
567
|
const shared = this.clientServerConnections.get(duplicateId);
|
|
549
568
|
if (shared !== undefined && shared !== connection) {
|
|
@@ -553,8 +572,9 @@ export class ZLinkChannelSocketRegistry {
|
|
|
553
572
|
if (callbacks !== undefined) shared.callbacksByAlias.set(connectionId, callbacks);
|
|
554
573
|
connection.aliases.clear();
|
|
555
574
|
connection.callbacksByAlias.clear();
|
|
556
|
-
void this.disposeClientServerPhysical(connectionId, connection)
|
|
557
|
-
|
|
575
|
+
void this.disposeClientServerPhysical(connectionId, connection).catch((error) =>
|
|
576
|
+
this.oneWayFailureSink?.(error)
|
|
577
|
+
);
|
|
558
578
|
return true;
|
|
559
579
|
}
|
|
560
580
|
}
|
|
@@ -654,11 +674,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
654
674
|
): Promise<ZLinkBackendDealerSocket | undefined> {
|
|
655
675
|
const startedAtMs = performance.now();
|
|
656
676
|
const deadline = Math.min(
|
|
657
|
-
deadlineAtMs ??
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
677
|
+
deadlineAtMs ??
|
|
678
|
+
startedAtMs +
|
|
679
|
+
(this.registration.channels.get(channelName)?.requestTimeoutMs ??
|
|
680
|
+
this.registration.requestTimeoutMs ??
|
|
681
|
+
DEFAULT_REQUEST_TIMEOUT_MS),
|
|
662
682
|
startedAtMs + CLIENT_SERVER_READY_WAIT_CAP_MS
|
|
663
683
|
);
|
|
664
684
|
for (;;) {
|
|
@@ -668,7 +688,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
668
688
|
const remainingMs = deadline - performance.now();
|
|
669
689
|
if (remainingMs <= 0) return undefined;
|
|
670
690
|
throwIfAborted(signal);
|
|
671
|
-
await new Promise<void>(resolve => {
|
|
691
|
+
await new Promise<void>((resolve) => {
|
|
672
692
|
setTimeout(resolve, Math.min(CLIENT_SERVER_READY_POLL_INTERVAL_MS, remainingMs));
|
|
673
693
|
});
|
|
674
694
|
}
|
|
@@ -680,10 +700,12 @@ export class ZLinkChannelSocketRegistry {
|
|
|
680
700
|
if (client === undefined) continue;
|
|
681
701
|
const endpoints = channel.client?.manualConnections ?? [];
|
|
682
702
|
if (endpoints.length === 0) continue;
|
|
683
|
-
const open = (endpoint: string) =>
|
|
703
|
+
const open = (endpoint: string) =>
|
|
704
|
+
this.openManualClientServerConnection(channelName, endpoint);
|
|
684
705
|
const close = (endpoint: string) => {
|
|
685
|
-
void this.closeClientServerConnection(
|
|
686
|
-
|
|
706
|
+
void this.closeClientServerConnection(
|
|
707
|
+
manualClientServerConnectionId(channelName, endpoint)
|
|
708
|
+
).catch((error) => this.oneWayFailureSink?.(error));
|
|
687
709
|
};
|
|
688
710
|
attachEndpointConnections(client, { connect: open, disconnect: close });
|
|
689
711
|
for (const endpoint of endpoints) {
|
|
@@ -742,17 +764,30 @@ export class ZLinkChannelSocketRegistry {
|
|
|
742
764
|
): readonly Pick<ClientServerDiscoveryDescriptor, 'serverRoutingId' | 'weight' | 'state'>[] {
|
|
743
765
|
const descriptors = this.clientServerDiscovery.clientServerDescriptors(channelName);
|
|
744
766
|
const local = this.clientServerServerDescriptors.get(channelName);
|
|
745
|
-
if (
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
767
|
+
if (
|
|
768
|
+
local === undefined ||
|
|
769
|
+
descriptors.some(
|
|
770
|
+
(descriptor) =>
|
|
771
|
+
descriptor.serverRoutingId === local.serverRid &&
|
|
772
|
+
descriptor.lifecycleGeneration === local.lifecycleGeneration
|
|
773
|
+
)
|
|
774
|
+
)
|
|
775
|
+
return descriptors;
|
|
776
|
+
|
|
777
|
+
return [
|
|
778
|
+
...descriptors,
|
|
779
|
+
{
|
|
780
|
+
serverRoutingId: local.serverRid,
|
|
781
|
+
weight: local.weight,
|
|
782
|
+
state: discoveryAvailabilityForRuntimeState(local.state)
|
|
783
|
+
}
|
|
784
|
+
].sort((left, right) =>
|
|
785
|
+
left.serverRoutingId < right.serverRoutingId
|
|
786
|
+
? -1
|
|
787
|
+
: left.serverRoutingId > right.serverRoutingId
|
|
788
|
+
? 1
|
|
789
|
+
: 0
|
|
790
|
+
);
|
|
756
791
|
}
|
|
757
792
|
|
|
758
793
|
hasKnownClientServerTargets(channelName: string): boolean {
|
|
@@ -763,28 +798,25 @@ export class ZLinkChannelSocketRegistry {
|
|
|
763
798
|
return this.clientServerDiscovery.fanoutEndpoints(channelName);
|
|
764
799
|
}
|
|
765
800
|
|
|
766
|
-
admitFanoutPublisher(
|
|
767
|
-
descriptor: ZLinkFanoutPublisherDescriptor,
|
|
768
|
-
connectionId: string
|
|
769
|
-
): boolean {
|
|
801
|
+
admitFanoutPublisher(descriptor: ZLinkFanoutPublisherDescriptor, connectionId: string): boolean {
|
|
770
802
|
const connection = this.fanoutConnections.get(connectionId);
|
|
771
803
|
if (connection === undefined || !connection.ready) return false;
|
|
772
|
-
const admitted = this.clientServerDiscovery.admitFanoutPublisher(
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
804
|
+
const admitted = this.clientServerDiscovery.admitFanoutPublisher(
|
|
805
|
+
{
|
|
806
|
+
channelName: descriptor.channelName,
|
|
807
|
+
publisherRoutingId: String(descriptor.publisherRid),
|
|
808
|
+
lifecycleGeneration: descriptor.lifecycleGeneration,
|
|
809
|
+
descriptorRevision: descriptor.descriptorRevision,
|
|
810
|
+
advertisedEndpoint: descriptor.endpoint,
|
|
811
|
+
state: discoveryAvailabilityForRuntimeState(descriptor.state)
|
|
812
|
+
},
|
|
813
|
+
fanoutDiscoveryConnectionId(connectionId)
|
|
814
|
+
);
|
|
780
815
|
this.notifyFanoutTopology(descriptor.channelName);
|
|
781
816
|
return admitted;
|
|
782
817
|
}
|
|
783
818
|
|
|
784
|
-
removeFanoutPublisher(
|
|
785
|
-
descriptor: ZLinkFanoutPublisherDescriptor,
|
|
786
|
-
connectionId: string
|
|
787
|
-
): boolean {
|
|
819
|
+
removeFanoutPublisher(descriptor: ZLinkFanoutPublisherDescriptor, connectionId: string): boolean {
|
|
788
820
|
const removed = this.clientServerDiscovery.removeFanoutPublisher(
|
|
789
821
|
descriptor.channelName,
|
|
790
822
|
String(descriptor.publisherRid),
|
|
@@ -821,18 +853,24 @@ export class ZLinkChannelSocketRegistry {
|
|
|
821
853
|
let reply: Buffer;
|
|
822
854
|
try {
|
|
823
855
|
const record = decodeClientServerControl(first.data());
|
|
824
|
-
if (
|
|
825
|
-
|
|
826
|
-
|
|
856
|
+
if (
|
|
857
|
+
record.kind === 'livenessProbe' &&
|
|
858
|
+
received.parts.length === 1 &&
|
|
859
|
+
received.replyToken !== null
|
|
860
|
+
) {
|
|
827
861
|
reply = encodeClientServerLivenessAck(record.probeId);
|
|
828
|
-
} else if (
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
862
|
+
} else if (
|
|
863
|
+
record.kind === 'livenessAck' &&
|
|
864
|
+
received.parts.length === 1 &&
|
|
865
|
+
received.replyToken === null
|
|
866
|
+
) {
|
|
867
|
+
if (
|
|
868
|
+
!this.acceptClientServerServerLivenessAck(
|
|
869
|
+
channelName,
|
|
870
|
+
String(received.routingId),
|
|
871
|
+
record.probeId
|
|
872
|
+
)
|
|
873
|
+
) {
|
|
836
874
|
this.reportStaleClientServerLivenessAck(
|
|
837
875
|
channelName,
|
|
838
876
|
String(received.routingId),
|
|
@@ -840,25 +878,26 @@ export class ZLinkChannelSocketRegistry {
|
|
|
840
878
|
);
|
|
841
879
|
}
|
|
842
880
|
return true;
|
|
843
|
-
} else if (
|
|
844
|
-
|
|
845
|
-
|
|
881
|
+
} else if (
|
|
882
|
+
record.kind !== 'hello' ||
|
|
883
|
+
received.parts.length !== 1 ||
|
|
884
|
+
received.replyToken === null
|
|
885
|
+
) {
|
|
846
886
|
reply = encodeClientServerReject(1);
|
|
847
887
|
} else {
|
|
848
888
|
const descriptor = this.clientServerServerDescriptors.get(channelName);
|
|
849
|
-
if (
|
|
850
|
-
|
|
851
|
-
|
|
889
|
+
if (
|
|
890
|
+
descriptor === undefined ||
|
|
891
|
+
record.hello.channelName !== channelName ||
|
|
892
|
+
record.hello.securityIdentity !== descriptor.securityIdentity
|
|
893
|
+
) {
|
|
852
894
|
reply = encodeClientServerReject(3);
|
|
853
895
|
} else {
|
|
854
896
|
const normalizedEffectiveMaxMessageBytes = Math.min(
|
|
855
897
|
normalizedMessageLimit(router.maxMessageSize),
|
|
856
898
|
record.hello.normalizedEffectiveMaxMessageBytes
|
|
857
899
|
);
|
|
858
|
-
reply = encodeClientServerAdmit(
|
|
859
|
-
descriptor,
|
|
860
|
-
normalizedEffectiveMaxMessageBytes
|
|
861
|
-
);
|
|
900
|
+
reply = encodeClientServerAdmit(descriptor, normalizedEffectiveMaxMessageBytes);
|
|
862
901
|
this.admitClientServerServerPeer(
|
|
863
902
|
channelName,
|
|
864
903
|
String(received.routingId),
|
|
@@ -883,8 +922,9 @@ export class ZLinkChannelSocketRegistry {
|
|
|
883
922
|
tickClientServerLiveness(nowMs = performance.now()): void {
|
|
884
923
|
this.drainSocketMonitors();
|
|
885
924
|
for (const connection of new Set(this.clientServerConnections.values())) {
|
|
886
|
-
const connectionId =
|
|
887
|
-
|
|
925
|
+
const connectionId =
|
|
926
|
+
connection.readyConnectionId ??
|
|
927
|
+
(connection.aliases.values().next().value as string | undefined);
|
|
888
928
|
if (connectionId === undefined) continue;
|
|
889
929
|
this.drainClientServerControl(connectionId, connection);
|
|
890
930
|
if (connection.deadlineAt === undefined) continue;
|
|
@@ -926,9 +966,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
926
966
|
callbacks: ZLinkFanoutConnectionCallbacks
|
|
927
967
|
): ZLinkBackendSubscriberSocket {
|
|
928
968
|
if (this.fanoutConnections.has(connectionId)) {
|
|
929
|
-
throw new ZLinkConfigurationException(
|
|
930
|
-
`Fanout connection '${connectionId}' is already open.`
|
|
931
|
-
);
|
|
969
|
+
throw new ZLinkConfigurationException(`Fanout connection '${connectionId}' is already open.`);
|
|
932
970
|
}
|
|
933
971
|
if (this.monitoringAdapter === undefined) {
|
|
934
972
|
throw new ZLinkConfigurationException(
|
|
@@ -968,11 +1006,13 @@ export class ZLinkChannelSocketRegistry {
|
|
|
968
1006
|
connection.transportReady = true;
|
|
969
1007
|
return;
|
|
970
1008
|
}
|
|
971
|
-
if (
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1009
|
+
if (
|
|
1010
|
+
event.nativeEvent === ZLinkSocketNativeEventType.Disconnected ||
|
|
1011
|
+
event.nativeEvent === ZLinkSocketNativeEventType.Closed ||
|
|
1012
|
+
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedNoDetail ||
|
|
1013
|
+
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedProtocol ||
|
|
1014
|
+
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedAuth
|
|
1015
|
+
) {
|
|
976
1016
|
connection.transportReady = false;
|
|
977
1017
|
connection.ready = false;
|
|
978
1018
|
connection.deadlineAt = undefined;
|
|
@@ -989,9 +1029,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
989
1029
|
return subscriber;
|
|
990
1030
|
}
|
|
991
1031
|
|
|
992
|
-
async closeFanoutSubscriberConnection(
|
|
993
|
-
connectionId: string
|
|
994
|
-
): Promise<void> {
|
|
1032
|
+
async closeFanoutSubscriberConnection(connectionId: string): Promise<void> {
|
|
995
1033
|
const connection = this.fanoutConnections.get(connectionId);
|
|
996
1034
|
if (connection === undefined) return;
|
|
997
1035
|
this.fanoutConnections.delete(connectionId);
|
|
@@ -1006,15 +1044,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1006
1044
|
connection.subscriber.dispose()
|
|
1007
1045
|
]);
|
|
1008
1046
|
const errors = results
|
|
1009
|
-
.filter((result): result is PromiseRejectedResult =>
|
|
1010
|
-
|
|
1011
|
-
.map(result => result.reason);
|
|
1047
|
+
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
1048
|
+
.map((result) => result.reason);
|
|
1012
1049
|
if (errors.length === 1) throw errors[0];
|
|
1013
1050
|
if (errors.length > 1) {
|
|
1014
|
-
throw new AggregateError(
|
|
1015
|
-
errors,
|
|
1016
|
-
`Fanout connection '${connectionId}' cleanup failed.`
|
|
1017
|
-
);
|
|
1051
|
+
throw new AggregateError(errors, `Fanout connection '${connectionId}' cleanup failed.`);
|
|
1018
1052
|
}
|
|
1019
1053
|
}
|
|
1020
1054
|
|
|
@@ -1027,12 +1061,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1027
1061
|
source: ZLinkBackendSubscriberSocket,
|
|
1028
1062
|
nowMs = performance.now()
|
|
1029
1063
|
): boolean {
|
|
1030
|
-
return this.handleFanoutInboundResult(
|
|
1031
|
-
connectionId,
|
|
1032
|
-
topicMessage,
|
|
1033
|
-
source,
|
|
1034
|
-
nowMs
|
|
1035
|
-
).consumed;
|
|
1064
|
+
return this.handleFanoutInboundResult(connectionId, topicMessage, source, nowMs).consumed;
|
|
1036
1065
|
}
|
|
1037
1066
|
|
|
1038
1067
|
handleFanoutInboundResult(
|
|
@@ -1051,10 +1080,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1051
1080
|
if (connection === undefined || connection.subscriber !== source) {
|
|
1052
1081
|
return { consumed: true };
|
|
1053
1082
|
}
|
|
1054
|
-
const classification = inspectFanoutInbound(
|
|
1055
|
-
topicMessage.topic,
|
|
1056
|
-
topicMessage.parts
|
|
1057
|
-
);
|
|
1083
|
+
const classification = inspectFanoutInbound(topicMessage.topic, topicMessage.parts);
|
|
1058
1084
|
if (classification.kind === 'protocolError') {
|
|
1059
1085
|
connection.ready = false;
|
|
1060
1086
|
connection.deadlineAt = undefined;
|
|
@@ -1081,12 +1107,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1081
1107
|
`Fanout subscriber '${channelName}' is not registered.`
|
|
1082
1108
|
);
|
|
1083
1109
|
}
|
|
1084
|
-
let handler:
|
|
1085
|
-
((event: ZLinkBackendSocketMonitorEvent) => void) | undefined;
|
|
1110
|
+
let handler: ((event: ZLinkBackendSocketMonitorEvent) => void) | undefined;
|
|
1086
1111
|
let disposed = false;
|
|
1087
1112
|
return {
|
|
1088
1113
|
nativeInstance: {},
|
|
1089
|
-
onEvent: next => {
|
|
1114
|
+
onEvent: (next) => {
|
|
1090
1115
|
if (disposed) return;
|
|
1091
1116
|
if (handler !== undefined) {
|
|
1092
1117
|
this.fanoutMonitorHandlers.get(channelName)?.delete(handler);
|
|
@@ -1121,7 +1146,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1121
1146
|
let handler: (() => void) | undefined;
|
|
1122
1147
|
let disposed = false;
|
|
1123
1148
|
return {
|
|
1124
|
-
onChange: next => {
|
|
1149
|
+
onChange: (next) => {
|
|
1125
1150
|
if (disposed) return;
|
|
1126
1151
|
if (handler !== undefined) {
|
|
1127
1152
|
this.fanoutTopologyHandlers.get(channelName)?.delete(handler);
|
|
@@ -1159,10 +1184,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1159
1184
|
for (const [channelName, publisher] of this.publishers) {
|
|
1160
1185
|
const next = this.fanoutPublisherNextBeacon.get(channelName) ?? nowMs;
|
|
1161
1186
|
if (nowMs < next) continue;
|
|
1162
|
-
this.fanoutPublisherNextBeacon.set(
|
|
1163
|
-
channelName,
|
|
1164
|
-
nowMs + CLIENT_SERVER_PROBE_INTERVAL_MS
|
|
1165
|
-
);
|
|
1187
|
+
this.fanoutPublisherNextBeacon.set(channelName, nowMs + CLIENT_SERVER_PROBE_INTERVAL_MS);
|
|
1166
1188
|
const payload = RuntimeMessage.from(FANOUT_LIVENESS_PAYLOAD);
|
|
1167
1189
|
try {
|
|
1168
1190
|
publisher.publish(FANOUT_LIVENESS_TOPIC, payload);
|
|
@@ -1173,14 +1195,14 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1173
1195
|
}
|
|
1174
1196
|
}
|
|
1175
1197
|
for (const [connectionId, connection] of [...this.fanoutConnections]) {
|
|
1176
|
-
if (connection.deadlineAt === undefined
|
|
1177
|
-
|| nowMs < connection.deadlineAt) continue;
|
|
1198
|
+
if (connection.deadlineAt === undefined || nowMs < connection.deadlineAt) continue;
|
|
1178
1199
|
connection.ready = false;
|
|
1179
1200
|
connection.deadlineAt = undefined;
|
|
1180
1201
|
connection.callbacks.onTerminated('deadline');
|
|
1181
1202
|
if (this.fanoutConnections.get(connectionId) === connection) {
|
|
1182
|
-
void this.closeFanoutSubscriberConnection(connectionId)
|
|
1183
|
-
|
|
1203
|
+
void this.closeFanoutSubscriberConnection(connectionId).catch((error) =>
|
|
1204
|
+
this.oneWayFailureSink?.(error)
|
|
1205
|
+
);
|
|
1184
1206
|
}
|
|
1185
1207
|
}
|
|
1186
1208
|
}
|
|
@@ -1201,8 +1223,9 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1201
1223
|
if (this.clientServerConnections.has(connectionId)) return;
|
|
1202
1224
|
this.openClientServerConnection(channelName, connectionId, endpoint, {
|
|
1203
1225
|
onTransportReady: () => {
|
|
1204
|
-
void this.admitConfiguredClientServerConnection(channelName, connectionId)
|
|
1205
|
-
|
|
1226
|
+
void this.admitConfiguredClientServerConnection(channelName, connectionId).catch((error) =>
|
|
1227
|
+
this.oneWayFailureSink?.(error)
|
|
1228
|
+
);
|
|
1206
1229
|
},
|
|
1207
1230
|
onTerminated: () => this.removeReadyConnection(connectionId)
|
|
1208
1231
|
});
|
|
@@ -1226,27 +1249,29 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1226
1249
|
'default',
|
|
1227
1250
|
15_000
|
|
1228
1251
|
);
|
|
1229
|
-
if (
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1252
|
+
if (
|
|
1253
|
+
this.clientServerConnections.get(connectionId) !== connection ||
|
|
1254
|
+
connection.physicalConnectionId !== physicalConnectionId ||
|
|
1255
|
+
connection.admissionAttempt !== admissionAttempt
|
|
1256
|
+
)
|
|
1257
|
+
return;
|
|
1258
|
+
if (admission.channelName !== channelName || admission.securityIdentity !== 'default') {
|
|
1234
1259
|
throw new ZLinkConfigurationException(
|
|
1235
1260
|
`ClientServer '${channelName}' admission does not match its configured identity.`
|
|
1236
1261
|
);
|
|
1237
1262
|
}
|
|
1238
|
-
if (
|
|
1239
|
-
admissionToDiscoveryDescriptor(admission),
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
throw new ZLinkConfigurationException(
|
|
1243
|
-
`ClientServer '${channelName}' admission was stale.`
|
|
1244
|
-
);
|
|
1263
|
+
if (
|
|
1264
|
+
!this.admitClientServerConnection(admissionToDiscoveryDescriptor(admission), connectionId)
|
|
1265
|
+
) {
|
|
1266
|
+
throw new ZLinkConfigurationException(`ClientServer '${channelName}' admission was stale.`);
|
|
1245
1267
|
}
|
|
1246
1268
|
} catch (error) {
|
|
1247
|
-
if (
|
|
1248
|
-
|
|
1249
|
-
|
|
1269
|
+
if (
|
|
1270
|
+
this.clientServerConnections.get(connectionId) !== connection ||
|
|
1271
|
+
connection.physicalConnectionId !== physicalConnectionId ||
|
|
1272
|
+
connection.admissionAttempt !== admissionAttempt
|
|
1273
|
+
)
|
|
1274
|
+
return;
|
|
1250
1275
|
this.removeReadyConnection(connectionId);
|
|
1251
1276
|
if (isBackendRequestTimeoutError(error)) {
|
|
1252
1277
|
retryAdmission = true;
|
|
@@ -1254,13 +1279,16 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1254
1279
|
}
|
|
1255
1280
|
throw error;
|
|
1256
1281
|
} finally {
|
|
1257
|
-
if (
|
|
1258
|
-
|
|
1259
|
-
|
|
1282
|
+
if (
|
|
1283
|
+
this.clientServerConnections.get(connectionId) === connection &&
|
|
1284
|
+
connection.physicalConnectionId === physicalConnectionId &&
|
|
1285
|
+
connection.admissionAttempt === admissionAttempt
|
|
1286
|
+
) {
|
|
1260
1287
|
connection.admissionAttempt = undefined;
|
|
1261
1288
|
if (retryAdmission) {
|
|
1262
|
-
void this.admitConfiguredClientServerConnection(channelName, connectionId)
|
|
1263
|
-
|
|
1289
|
+
void this.admitConfiguredClientServerConnection(channelName, connectionId).catch(
|
|
1290
|
+
(error) => this.oneWayFailureSink?.(error)
|
|
1291
|
+
);
|
|
1264
1292
|
}
|
|
1265
1293
|
}
|
|
1266
1294
|
}
|
|
@@ -1279,8 +1307,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1279
1307
|
return;
|
|
1280
1308
|
}
|
|
1281
1309
|
try {
|
|
1282
|
-
if (received.parts.length !== 1
|
|
1283
|
-
|| !isClientServerControlFrame(received.parts[0]!.data())) {
|
|
1310
|
+
if (received.parts.length !== 1 || !isClientServerControlFrame(received.parts[0]!.data())) {
|
|
1284
1311
|
throw new ZLinkConfigurationException(
|
|
1285
1312
|
`ClientServer '${connection.channelName}' received an unsolicited application frame.`
|
|
1286
1313
|
);
|
|
@@ -1288,7 +1315,8 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1288
1315
|
const record = decodeClientServerControl(received.parts[0]!.data());
|
|
1289
1316
|
if (record.kind === 'livenessProbe') {
|
|
1290
1317
|
const ack = RuntimeMessage.from(encodeClientServerLivenessAck(record.probeId));
|
|
1291
|
-
void connection.dealer
|
|
1318
|
+
void connection.dealer
|
|
1319
|
+
.send(ack)
|
|
1292
1320
|
.catch((error) => {
|
|
1293
1321
|
this.removeReadyConnection(connectionId);
|
|
1294
1322
|
this.oneWayFailureSink?.(error);
|
|
@@ -1334,19 +1362,24 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1334
1362
|
admission: ZLinkClientServerAdmission
|
|
1335
1363
|
): void {
|
|
1336
1364
|
const currentConnection = this.clientServerConnections.get(connectionId);
|
|
1337
|
-
if (
|
|
1338
|
-
|
|
1365
|
+
if (
|
|
1366
|
+
currentConnection === undefined ||
|
|
1367
|
+
currentConnection.physicalConnectionId !== connection.physicalConnectionId
|
|
1368
|
+
)
|
|
1369
|
+
return;
|
|
1339
1370
|
const identity = this.clientServerReadyIdentities.get(connectionId);
|
|
1340
1371
|
if (identity === undefined) return;
|
|
1341
|
-
const current = this.clientServerDiscovery
|
|
1342
|
-
.
|
|
1343
|
-
|
|
1372
|
+
const current = this.clientServerDiscovery
|
|
1373
|
+
.clientServerDescriptors(connection.channelName)
|
|
1374
|
+
.find((value) => value.serverRoutingId === identity.serverRoutingId);
|
|
1344
1375
|
if (current === undefined) return;
|
|
1345
|
-
if (
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1376
|
+
if (
|
|
1377
|
+
admission.channelName !== current.channelName ||
|
|
1378
|
+
admission.serverRid !== current.serverRoutingId ||
|
|
1379
|
+
admission.lifecycleGeneration !== current.lifecycleGeneration ||
|
|
1380
|
+
admission.securityIdentity !== current.securityIdentity ||
|
|
1381
|
+
admission.advertisedEndpoint !== current.advertisedEndpoint
|
|
1382
|
+
) {
|
|
1350
1383
|
throw new ZLinkConfigurationException(
|
|
1351
1384
|
`ClientServer '${connection.channelName}' descriptor update changed immutable identity.`
|
|
1352
1385
|
);
|
|
@@ -1379,10 +1412,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1379
1412
|
|
|
1380
1413
|
private ensureClientServerLivenessTimer(): void {
|
|
1381
1414
|
if (this.clientServerLivenessTimer !== undefined) return;
|
|
1382
|
-
this.clientServerLivenessTimer = setInterval(
|
|
1383
|
-
() => this.tickClientServerLiveness(),
|
|
1384
|
-
100
|
|
1385
|
-
);
|
|
1415
|
+
this.clientServerLivenessTimer = setInterval(() => this.tickClientServerLiveness(), 100);
|
|
1386
1416
|
this.clientServerLivenessTimer.unref();
|
|
1387
1417
|
}
|
|
1388
1418
|
|
|
@@ -1422,25 +1452,29 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1422
1452
|
probeId: bigint
|
|
1423
1453
|
): void {
|
|
1424
1454
|
const message = RuntimeMessage.from(encodeClientServerLivenessProbe(probeId));
|
|
1425
|
-
void connection.dealer
|
|
1455
|
+
void connection.dealer
|
|
1456
|
+
.request(message, CLIENT_SERVER_PEER_DEADLINE_MS)
|
|
1426
1457
|
.then((parts) => {
|
|
1427
1458
|
try {
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1459
|
+
const current = this.clientServerConnections.get(connectionId);
|
|
1460
|
+
if (
|
|
1461
|
+
current === undefined ||
|
|
1462
|
+
current.physicalConnectionId !== connection.physicalConnectionId ||
|
|
1463
|
+
parts.length !== 1
|
|
1464
|
+
)
|
|
1465
|
+
return;
|
|
1466
|
+
const record = decodeClientServerControl(parts[0]!.data());
|
|
1467
|
+
if (record.kind !== 'livenessAck') return;
|
|
1468
|
+
if (current.outstandingProbeId !== probeId || record.probeId !== probeId) {
|
|
1469
|
+
this.reportStaleClientServerLivenessAck(
|
|
1470
|
+
connection.channelName,
|
|
1471
|
+
connectionId,
|
|
1472
|
+
record.probeId
|
|
1473
|
+
);
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
current.outstandingProbeId = undefined;
|
|
1477
|
+
current.deadlineAt = performance.now() + CLIENT_SERVER_PEER_DEADLINE_MS;
|
|
1444
1478
|
} finally {
|
|
1445
1479
|
closeMessages(parts);
|
|
1446
1480
|
}
|
|
@@ -1487,7 +1521,8 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1487
1521
|
const router = this.channelRouters.get(peer.channelName);
|
|
1488
1522
|
if (router === undefined) return;
|
|
1489
1523
|
const message = RuntimeMessage.from(encodeClientServerLivenessProbe(probeId));
|
|
1490
|
-
void router
|
|
1524
|
+
void router
|
|
1525
|
+
.send(peer.routingId, message)
|
|
1491
1526
|
.catch((error) => this.oneWayFailureSink?.(error))
|
|
1492
1527
|
.finally(() => message.close());
|
|
1493
1528
|
}
|
|
@@ -1511,11 +1546,13 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1511
1546
|
peer: string,
|
|
1512
1547
|
probeId: bigint
|
|
1513
1548
|
): void {
|
|
1514
|
-
this.oneWayFailureSink?.(
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1549
|
+
this.oneWayFailureSink?.(
|
|
1550
|
+
createInternalFrameworkException(
|
|
1551
|
+
ZLinkFrameworkInternalErrorKind.RequestProtocolError,
|
|
1552
|
+
`ClientServer '${channelName}' ignored stale or duplicate liveness ACK '${probeId}' from '${peer}'.`,
|
|
1553
|
+
false
|
|
1554
|
+
)
|
|
1555
|
+
);
|
|
1519
1556
|
}
|
|
1520
1557
|
|
|
1521
1558
|
private pushClientServerDescriptorUpdate(
|
|
@@ -1533,11 +1570,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1533
1570
|
clients.delete(routingId);
|
|
1534
1571
|
continue;
|
|
1535
1572
|
}
|
|
1536
|
-
const message = RuntimeMessage.from(
|
|
1537
|
-
descriptor,
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1573
|
+
const message = RuntimeMessage.from(
|
|
1574
|
+
encodeClientServerUpdate(descriptor, peer.normalizedEffectiveMaxMessageBytes)
|
|
1575
|
+
);
|
|
1576
|
+
void router
|
|
1577
|
+
.send(routingId, message)
|
|
1541
1578
|
.catch((error) => {
|
|
1542
1579
|
clients.delete(routingId);
|
|
1543
1580
|
this.oneWayFailureSink?.(error);
|
|
@@ -1560,10 +1597,14 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1560
1597
|
|
|
1561
1598
|
const channel = this.registration.channels.get(channelName);
|
|
1562
1599
|
if (channel?.publisher === undefined) {
|
|
1563
|
-
throw new ZLinkConfigurationException(
|
|
1600
|
+
throw new ZLinkConfigurationException(
|
|
1601
|
+
`Channel publisher '${channelName}' is not registered.`
|
|
1602
|
+
);
|
|
1564
1603
|
}
|
|
1565
1604
|
if (channel.publisher.bind === undefined) {
|
|
1566
|
-
throw new ZLinkConfigurationException(
|
|
1605
|
+
throw new ZLinkConfigurationException(
|
|
1606
|
+
`Channel publisher '${channelName}' does not define a bind endpoint.`
|
|
1607
|
+
);
|
|
1567
1608
|
}
|
|
1568
1609
|
|
|
1569
1610
|
const publisher = this.adapter.createPublisherSocket(this.context);
|
|
@@ -1583,7 +1624,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1583
1624
|
const channel = this.registration.channels.get(channelName);
|
|
1584
1625
|
const publisher = this.publishers.get(channelName);
|
|
1585
1626
|
const boundEndpoint = publisher?.lastEndpoint;
|
|
1586
|
-
if (
|
|
1627
|
+
if (
|
|
1628
|
+
channel?.publisher === undefined ||
|
|
1629
|
+
boundEndpoint === undefined ||
|
|
1630
|
+
boundEndpoint.length === 0
|
|
1631
|
+
) {
|
|
1587
1632
|
return undefined;
|
|
1588
1633
|
}
|
|
1589
1634
|
return advertisedEndpoint(boundEndpoint, channel.publisher.advertiseHost);
|
|
@@ -1597,7 +1642,9 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1597
1642
|
|
|
1598
1643
|
const routeChannel = this.registration.routeChannelOptions.get(routerChannelId);
|
|
1599
1644
|
if (routeChannel === undefined) {
|
|
1600
|
-
throw new ZLinkConfigurationException(
|
|
1645
|
+
throw new ZLinkConfigurationException(
|
|
1646
|
+
`Route channel '${routerChannelId}' is not registered.`
|
|
1647
|
+
);
|
|
1601
1648
|
}
|
|
1602
1649
|
const router = this.adapter.createRouterSocket(this.context);
|
|
1603
1650
|
this.registerReceiveFlowSocket(router);
|
|
@@ -1609,8 +1656,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1609
1656
|
router.setProbe(true);
|
|
1610
1657
|
}
|
|
1611
1658
|
router.setRoutingId(
|
|
1612
|
-
routeChannel.routingId
|
|
1613
|
-
?? `${routeChannel.routingIdPrefix ?? routerChannelId}-${randomUUID()}`
|
|
1659
|
+
routeChannel.routingId ?? `${routeChannel.routingIdPrefix ?? routerChannelId}-${randomUUID()}`
|
|
1614
1660
|
);
|
|
1615
1661
|
const publicWeight = routeChannel.weight ?? 100;
|
|
1616
1662
|
this.routeMeshPublicWeights.set(routerChannelId, publicWeight);
|
|
@@ -1649,7 +1695,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1649
1695
|
private registerReceiveFlowSocket(socket: ReceiveFlowSocket): void {
|
|
1650
1696
|
this.applicationJobQueue?.registerReceiveFlowTarget(
|
|
1651
1697
|
socket,
|
|
1652
|
-
state => socket.setReceiveFlowState(state === 'paused' ? 1 : 0),
|
|
1698
|
+
(state) => socket.setReceiveFlowState(state === 'paused' ? 1 : 0),
|
|
1653
1699
|
this.oneWayFailureSink
|
|
1654
1700
|
);
|
|
1655
1701
|
}
|
|
@@ -1658,7 +1704,10 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1658
1704
|
this.applicationJobQueue?.unregisterReceiveFlowTarget(socket);
|
|
1659
1705
|
}
|
|
1660
1706
|
|
|
1661
|
-
routeMemberStatus(
|
|
1707
|
+
routeMemberStatus(
|
|
1708
|
+
routerChannelId: string,
|
|
1709
|
+
targetNodeRid: string
|
|
1710
|
+
): 'unknown' | 'missing' | 'connected' | 'disconnected' {
|
|
1662
1711
|
return this.routeMembers.status(routerChannelId, targetNodeRid);
|
|
1663
1712
|
}
|
|
1664
1713
|
|
|
@@ -1672,7 +1721,10 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1672
1721
|
const monitor = this.monitoringAdapter.openSocketMonitor(socket);
|
|
1673
1722
|
this.ownedMonitors.add(monitor);
|
|
1674
1723
|
monitor.onEvent((event) => {
|
|
1675
|
-
if (
|
|
1724
|
+
if (
|
|
1725
|
+
event.nativeEvent === ZLinkSocketNativeEventType.Disconnected &&
|
|
1726
|
+
event.remoteAddr.length > 0
|
|
1727
|
+
) {
|
|
1676
1728
|
handler(event.remoteAddr);
|
|
1677
1729
|
}
|
|
1678
1730
|
});
|
|
@@ -1686,14 +1738,18 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1686
1738
|
this.ownedMonitors.add(monitor);
|
|
1687
1739
|
monitor.onEvent((event) => {
|
|
1688
1740
|
const routingId = event.routingId === undefined ? undefined : String(event.routingId);
|
|
1689
|
-
if (
|
|
1741
|
+
if (
|
|
1742
|
+
event.nativeEvent === ZLinkSocketNativeEventType.ConnectionReady &&
|
|
1743
|
+
routingId !== undefined
|
|
1744
|
+
) {
|
|
1690
1745
|
this.routeMembers.observeReady(routerChannelId, routingId, event.remoteAddr);
|
|
1691
1746
|
return;
|
|
1692
1747
|
}
|
|
1693
1748
|
if (
|
|
1694
|
-
event.nativeEvent !== ZLinkSocketNativeEventType.Disconnected
|
|
1695
|
-
|
|
1696
|
-
)
|
|
1749
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.Disconnected &&
|
|
1750
|
+
event.nativeEvent !== ZLinkSocketNativeEventType.Closed
|
|
1751
|
+
)
|
|
1752
|
+
return;
|
|
1697
1753
|
this.routeMembers.observeTermination(routerChannelId, routingId, event.remoteAddr);
|
|
1698
1754
|
});
|
|
1699
1755
|
}
|
|
@@ -1717,11 +1773,13 @@ async function requestClientServerAdmission(
|
|
|
1717
1773
|
securityIdentity: string,
|
|
1718
1774
|
timeoutMs: number
|
|
1719
1775
|
): Promise<ZLinkClientServerAdmission> {
|
|
1720
|
-
const message = RuntimeMessage.from(
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1776
|
+
const message = RuntimeMessage.from(
|
|
1777
|
+
encodeClientServerHello({
|
|
1778
|
+
channelName,
|
|
1779
|
+
securityIdentity,
|
|
1780
|
+
normalizedEffectiveMaxMessageBytes: normalizedMessageLimit(dealer.maxMessageSize)
|
|
1781
|
+
})
|
|
1782
|
+
);
|
|
1725
1783
|
try {
|
|
1726
1784
|
const parts = await dealer.request(message, timeoutMs);
|
|
1727
1785
|
try {
|
|
@@ -1768,15 +1826,17 @@ function sameClientServerDiscoveryDescriptor(
|
|
|
1768
1826
|
left: ClientServerDiscoveryDescriptor,
|
|
1769
1827
|
right: ClientServerDiscoveryDescriptor
|
|
1770
1828
|
): boolean {
|
|
1771
|
-
return
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1829
|
+
return (
|
|
1830
|
+
left.channelName === right.channelName &&
|
|
1831
|
+
left.serverRoutingId === right.serverRoutingId &&
|
|
1832
|
+
left.lifecycleGeneration === right.lifecycleGeneration &&
|
|
1833
|
+
left.descriptorRevision === right.descriptorRevision &&
|
|
1834
|
+
left.weight === right.weight &&
|
|
1835
|
+
left.state === right.state &&
|
|
1836
|
+
left.securityIdentity === right.securityIdentity &&
|
|
1837
|
+
left.effectiveMaxMessageBytes === right.effectiveMaxMessageBytes &&
|
|
1838
|
+
left.advertisedEndpoint === right.advertisedEndpoint
|
|
1839
|
+
);
|
|
1780
1840
|
}
|
|
1781
1841
|
|
|
1782
1842
|
function closeMessages(parts: readonly Message[]): void {
|
|
@@ -1832,9 +1892,7 @@ function advertisedEndpoint(boundEndpoint: string, advertiseHost: string | undef
|
|
|
1832
1892
|
}
|
|
1833
1893
|
|
|
1834
1894
|
function normalizedMessageLimit(value: number): number {
|
|
1835
|
-
return Number.isSafeInteger(value) && value > 0
|
|
1836
|
-
? Math.min(value, 0xffff_ffff)
|
|
1837
|
-
: 0x7fff_ffff;
|
|
1895
|
+
return Number.isSafeInteger(value) && value > 0 ? Math.min(value, 0xffff_ffff) : 0x7fff_ffff;
|
|
1838
1896
|
}
|
|
1839
1897
|
|
|
1840
1898
|
function requirePublicWeight(weight: number): void {
|