@zlink-systems/framework 0.25.0 → 0.27.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/Channels/IZLinkFanoutClient.d.ts +0 -6
- package/dist/contracts/Common/CoreTypes.d.ts +6 -0
- package/dist/contracts/Common/CoreTypes.js +7 -0
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/index.js +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
- package/dist/contracts/Configuration/InternalDefaults.js +9 -1
- package/dist/contracts/Configuration/Registration.d.ts +13 -2
- package/dist/contracts/Configuration/Registration.js +58 -36
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
- package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
- package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
- package/dist/contracts/Handlers/JsonContract.js +10 -4
- package/dist/contracts/Locations/Authority.d.ts +1 -1
- package/dist/contracts/Locations/Authority.js +3 -2
- package/dist/contracts/Locations/Options.js +1 -1
- package/dist/contracts/Locations/Stores.d.ts +12 -0
- package/dist/contracts/Locations/Stores.js +9 -0
- package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
- package/dist/contracts/Spots/Contracts.d.ts +1 -1
- package/dist/internal.d.ts +5 -0
- package/dist/internal.js +16 -1
- package/dist/nest-integration.d.ts +4 -2
- package/dist/nest-integration.js +14 -4
- package/dist/runtime/abort.d.ts +1 -0
- package/dist/runtime/abort.js +8 -5
- package/dist/runtime/activation-admission.d.ts +28 -0
- package/dist/runtime/activation-admission.js +57 -0
- package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
- package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
- package/dist/runtime/actors/actor-client.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +42 -143
- package/dist/runtime/actors/actor-context.d.ts +3 -5
- package/dist/runtime/actors/actor-context.js +19 -17
- package/dist/runtime/actors/actor-handoff.d.ts +13 -7
- package/dist/runtime/actors/actor-handoff.js +36 -25
- package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
- package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
- package/dist/runtime/actors/actor-local-native-join.js +85 -123
- package/dist/runtime/actors/actor-native-lookup.js +2 -8
- package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
- package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
- package/dist/runtime/actors/actor-remote-joiner.d.ts +3 -3
- package/dist/runtime/actors/actor-remote-joiner.js +11 -17
- package/dist/runtime/actors/actor-remote-wire.js +5 -3
- package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
- package/dist/runtime/actors/actor-request-deadline.js +31 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
- package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +19 -0
- package/dist/runtime/actors/deferred-join-completion.js +21 -0
- package/dist/runtime/actors/index.d.ts +10 -8
- package/dist/runtime/actors/index.js +101 -73
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
- package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
- package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
- package/dist/runtime/admission.d.ts +7 -1
- package/dist/runtime/admission.js +11 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
- package/dist/runtime/backend/contracts/index.d.ts +8 -33
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +3 -26
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
- package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +7 -4
- package/dist/runtime/backend/node/node-backend-adapter-support.js +28 -34
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +11 -6
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +51 -19
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +21 -19
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +171 -111
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
- package/dist/runtime/backend/raw-binding-port.d.ts +13 -1
- package/dist/runtime/backend/runtime-values.d.ts +4 -1
- package/dist/runtime/backend/runtime-values.js +2 -0
- package/dist/runtime/channels/channel-clients.d.ts +20 -9
- package/dist/runtime/channels/channel-clients.js +68 -60
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.js +47 -29
- package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
- package/dist/runtime/channels/channel-outbound-operations.js +9 -18
- package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
- package/dist/runtime/channels/channel-receive-loops.js +27 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
- package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
- package/dist/runtime/channels/channel-runtime-manager.js +4 -12
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +30 -32
- package/dist/runtime/channels/channel-socket-registry.js +296 -235
- package/dist/runtime/channels/channel-transports.d.ts +11 -20
- package/dist/runtime/channels/channel-transports.js +68 -47
- package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/client-server-location-runtime.js +10 -11
- package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
- package/dist/runtime/channels/client-server-service-wire.js +32 -11
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
- package/dist/runtime/channels/fanout-location-runtime.js +133 -81
- package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
- package/dist/runtime/channels/spot-direct-envelope.js +4 -3
- package/dist/runtime/channels/spot-node-route-transport.js +3 -2
- package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
- package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
- package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
- package/dist/runtime/diagnostics/flow-context.js +16 -2
- package/dist/runtime/diagnostics/index.d.ts +4 -2
- package/dist/runtime/diagnostics/index.js +14 -4
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
- package/dist/runtime/diagnostics/message-flow.js +10 -19
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
- package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
- package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
- package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
- package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
- package/dist/runtime/disposal.d.ts +5 -0
- package/dist/runtime/disposal.js +22 -0
- package/dist/runtime/execution/index.d.ts +22 -9
- package/dist/runtime/execution/index.js +107 -37
- package/dist/runtime/execution/serial-execution-queue.d.ts +12 -7
- package/dist/runtime/execution/serial-execution-queue.js +99 -26
- package/dist/runtime/execution/state-lane.d.ts +8 -1
- package/dist/runtime/execution/state-lane.js +118 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
- package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
- package/dist/runtime/foundation/event-loop-resources.js +6 -119
- package/dist/runtime/foundation/listener-records.d.ts +11 -0
- package/dist/runtime/foundation/listener-records.js +20 -0
- package/dist/runtime/foundation/operation-identity.d.ts +2 -0
- package/dist/runtime/foundation/operation-identity.js +9 -5
- package/dist/runtime/foundation/operation-registry.d.ts +5 -7
- package/dist/runtime/foundation/operation-registry.js +34 -44
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +18 -26
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +122 -469
- package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
- package/dist/runtime/foundation/runtime-state-projections.js +8 -0
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +30 -12
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +22 -3
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
- package/dist/runtime/foundation/service-liveness-registry.js +2 -1
- package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
- package/dist/runtime/foundation/service-maintenance-runtime.js +23 -8
- package/dist/runtime/foundation/service-metadata-codec.js +3 -3
- package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
- package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
- package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +19 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
- package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -19
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +10 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +28 -24
- package/dist/runtime/foundation/service-stateful-runtime.js +297 -244
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +12 -7
- package/dist/runtime/foundation/service-stateful-wire-codec.js +240 -143
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -3
- package/dist/runtime/foundation/service-topology-registry.js +22 -61
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
- package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
- package/dist/runtime/foundation/service-wire-codec.js +10 -8
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
- package/dist/runtime/framework-errors-internal.d.ts +2 -1
- package/dist/runtime/framework-errors-internal.js +343 -122
- package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
- package/dist/runtime/handlers/handler-instance-scope.js +61 -74
- package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
- package/dist/runtime/host/actor-packet-relay.js +48 -91
- package/dist/runtime/host/actor-placement-coordinator.js +7 -5
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
- package/dist/runtime/host/actor-transfer-runtime.d.ts +28 -28
- package/dist/runtime/host/actor-transfer-runtime.js +210 -256
- package/dist/runtime/host/application-job-queue.js +16 -33
- package/dist/runtime/host/bound-session-relay.js +1 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
- package/dist/runtime/host/index.d.ts +19 -14
- package/dist/runtime/host/index.js +234 -175
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
- package/dist/runtime/host/instance-activation-authority.js +17 -45
- package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
- package/dist/runtime/host/location-runtime-owner.js +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
- package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
- package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
- package/dist/runtime/host/remote-bound-session-relay.js +11 -23
- package/dist/runtime/host/route-mesh-runtime.d.ts +14 -10
- package/dist/runtime/host/route-mesh-runtime.js +178 -257
- package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
- package/dist/runtime/host/runtime-shutdown.js +18 -21
- package/dist/runtime/host/service-relocation-control.js +6 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +71 -38
- package/dist/runtime/host/service-relocation-host-runtime.js +816 -651
- package/dist/runtime/host/spot-address-transport.d.ts +2 -3
- package/dist/runtime/host/spot-address-transport.js +34 -136
- package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
- package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -7
- package/dist/runtime/host/spot-runtime-options-factory.js +53 -21
- package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +14 -6
- package/dist/runtime/host/user-spot-creation-coordinator.js +96 -95
- package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
- package/dist/runtime/locations/authority-key-codec.js +4 -3
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
- package/dist/runtime/locations/creation-operation-id.js +6 -4
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
- package/dist/runtime/locations/in-memory-authority-store.js +31 -15
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +17 -14
- package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-provider-location-store.js +79 -27
- package/dist/runtime/locations/key-codec.js +3 -2
- package/dist/runtime/locations/lease-tracker.d.ts +3 -5
- package/dist/runtime/locations/lease-tracker.js +7 -11
- package/dist/runtime/locations/lifecycle.d.ts +5 -10
- package/dist/runtime/locations/lifecycle.js +4 -33
- package/dist/runtime/locations/location-store-failure.d.ts +2 -0
- package/dist/runtime/locations/location-store-failure.js +7 -0
- package/dist/runtime/locations/location-store-pages.d.ts +3 -0
- package/dist/runtime/locations/location-store-pages.js +13 -0
- package/dist/runtime/locations/location-store-repository.d.ts +5 -7
- package/dist/runtime/locations/location-store-repository.js +303 -332
- package/dist/runtime/locations/relocation-blob.js +18 -5
- package/dist/runtime/locations/resolvers.d.ts +5 -5
- package/dist/runtime/locations/resolvers.js +44 -30
- package/dist/runtime/locations/runtime.d.ts +5 -4
- package/dist/runtime/locations/runtime.js +123 -92
- package/dist/runtime/locations/spot-location-claims.d.ts +8 -2
- package/dist/runtime/locations/spot-location-claims.js +40 -23
- package/dist/runtime/messaging/payload-codec.js +26 -20
- package/dist/runtime/messaging/submission-result.d.ts +3 -0
- package/dist/runtime/messaging/submission-result.js +48 -0
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +2 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +17 -8
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +6 -3
- package/dist/runtime/spots/index.d.ts +29 -29
- package/dist/runtime/spots/index.js +441 -313
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -4
- package/dist/runtime/spots/spot-activation-registry.js +27 -60
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
- package/dist/runtime/spots/spot-activation-state.js +4 -17
- package/dist/runtime/spots/spot-activation.d.ts +10 -9
- package/dist/runtime/spots/spot-activation.js +103 -81
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
- package/dist/runtime/spots/spot-actor-join-dispatch.js +5 -55
- package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
- package/dist/runtime/spots/spot-actor-membership.d.ts +7 -5
- package/dist/runtime/spots/spot-actor-membership.js +44 -53
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
- package/dist/runtime/spots/spot-context.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-entry-activation.js +9 -21
- package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
- package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
- package/dist/runtime/spots/spot-manager-public.js +6 -5
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +22 -21
- package/dist/runtime/spots/spot-node-runtime-manager.js +73 -82
- package/dist/runtime/spots/spot-outbound.d.ts +4 -3
- package/dist/runtime/spots/spot-outbound.js +10 -37
- package/dist/runtime/spots/spot-remote-codec.js +5 -3
- package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
- package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
- package/dist/runtime/spots/spot-route-replies.js +3 -1
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -2
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -7
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +1 -70
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
- package/dist/runtime/spots/spot-runtime-ports.d.ts +4 -20
- package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
- package/dist/runtime/spots/spot-serial-executor.js +9 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +29 -6
- package/dist/runtime/spots/spot-serial-turn-executor.js +89 -13
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +17 -32
- package/dist/runtime/streams/actor-session-binding-registry.js +145 -367
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +2 -6
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +12 -19
- package/dist/runtime/streams/index.d.ts +15 -14
- package/dist/runtime/streams/index.js +38 -39
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +17 -8
- package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
- package/dist/runtime/streams/protocol.d.ts +6 -33
- package/dist/runtime/streams/protocol.js +38 -110
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
- package/dist/runtime/streams/session-actor-coordinator.js +12 -4
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +5 -4
- package/dist/runtime/streams/session-context.d.ts +6 -6
- package/dist/runtime/streams/session-context.js +22 -4
- package/dist/runtime/streams/session-requests.js +2 -1
- package/dist/runtime/streams/session-serial-executor.js +2 -2
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
- package/dist/runtime/streams/stream-frame-factory.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
- package/dist/runtime/streams/stream-session-runtime.js +25 -33
- package/dist/runtime/workers/index.d.ts +2 -2
- package/dist/runtime/workers/index.js +5 -4
- package/package.json +3 -3
- package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
- package/src/contracts/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Configuration/InternalDefaults.ts +12 -0
- package/src/contracts/Configuration/Registration.ts +92 -48
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Handlers/JsonContract.ts +14 -4
- package/src/contracts/Locations/Authority.ts +7 -3
- package/src/contracts/Locations/Options.ts +1 -1
- package/src/contracts/Locations/Stores.ts +14 -0
- package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
- package/src/contracts/Spots/Contracts.ts +1 -1
- package/src/internal.ts +15 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +72 -0
- package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
- package/src/runtime/actors/actor-client.ts +77 -204
- package/src/runtime/actors/actor-context.ts +45 -39
- package/src/runtime/actors/actor-handoff.ts +55 -45
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +174 -215
- package/src/runtime/actors/actor-native-lookup.ts +2 -9
- package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
- package/src/runtime/actors/actor-remote-joiner.ts +15 -36
- package/src/runtime/actors/actor-remote-wire.ts +5 -3
- package/src/runtime/actors/actor-request-deadline.ts +49 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
- package/src/runtime/actors/actor-runtime-state.ts +85 -247
- package/src/runtime/actors/actor-source-transfer.ts +5 -18
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +44 -0
- package/src/runtime/actors/index.ts +122 -88
- package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
- package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
- package/src/runtime/admission.ts +13 -2
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +15 -42
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -28
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
- package/src/runtime/backend/node/node-backend-adapter-support.ts +32 -35
- package/src/runtime/backend/node/node-event-loop-poller.ts +16 -8
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +58 -23
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +252 -162
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -4
- package/src/runtime/backend/raw-binding-port.ts +14 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +132 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +58 -29
- package/src/runtime/channels/channel-outbound-operations.ts +10 -31
- package/src/runtime/channels/channel-receive-loops.ts +39 -7
- package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
- package/src/runtime/channels/channel-runtime-manager.ts +8 -15
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +369 -262
- package/src/runtime/channels/channel-transports.ts +161 -115
- package/src/runtime/channels/client-server-location-runtime.ts +17 -17
- package/src/runtime/channels/client-server-service-wire.ts +40 -12
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
- package/src/runtime/channels/fanout-location-runtime.ts +175 -106
- package/src/runtime/channels/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +5 -2
- package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
- package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
- package/src/runtime/diagnostics/flow-context.ts +16 -2
- package/src/runtime/diagnostics/index.ts +27 -17
- package/src/runtime/diagnostics/message-flow.ts +15 -25
- package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
- package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
- package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
- package/src/runtime/disposal.ts +19 -0
- package/src/runtime/execution/index.ts +116 -38
- package/src/runtime/execution/serial-execution-queue.ts +179 -34
- package/src/runtime/execution/state-lane.ts +142 -4
- package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
- package/src/runtime/foundation/event-loop-resources.ts +5 -122
- package/src/runtime/foundation/listener-records.ts +21 -0
- package/src/runtime/foundation/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +170 -571
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +41 -13
- package/src/runtime/foundation/service-discovery-registry.ts +32 -3
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
- package/src/runtime/foundation/service-liveness-registry.ts +2 -1
- package/src/runtime/foundation/service-maintenance-runtime.ts +30 -19
- package/src/runtime/foundation/service-metadata-codec.ts +2 -2
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
- package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
- package/src/runtime/foundation/service-relocation-object-owner.ts +23 -7
- package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
- package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -25
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +435 -327
- package/src/runtime/foundation/service-stateful-wire-codec.ts +329 -199
- package/src/runtime/foundation/service-topology-registry.ts +30 -79
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
- package/src/runtime/foundation/service-wire-codec.ts +15 -8
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
- package/src/runtime/framework-errors-internal.ts +380 -134
- package/src/runtime/handlers/handler-instance-scope.ts +68 -95
- package/src/runtime/host/actor-packet-relay.ts +57 -147
- package/src/runtime/host/actor-placement-coordinator.ts +8 -5
- package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
- package/src/runtime/host/actor-transfer-runtime.ts +266 -418
- package/src/runtime/host/application-job-queue.ts +28 -34
- package/src/runtime/host/bound-session-relay.ts +1 -2
- package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
- package/src/runtime/host/index.ts +408 -312
- package/src/runtime/host/instance-activation-authority.ts +89 -109
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
- package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
- package/src/runtime/host/remote-bound-session-relay.ts +12 -44
- package/src/runtime/host/route-mesh-runtime.ts +236 -275
- package/src/runtime/host/runtime-shutdown.ts +17 -21
- package/src/runtime/host/service-relocation-control.ts +14 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +1161 -904
- package/src/runtime/host/spot-address-transport.ts +73 -195
- package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
- package/src/runtime/host/spot-runtime-options-factory.ts +92 -30
- package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
- package/src/runtime/host/user-spot-creation-coordinator.ts +182 -163
- package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
- package/src/runtime/locations/authority-key-codec.ts +7 -3
- package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
- package/src/runtime/locations/creation-operation-id.ts +6 -3
- package/src/runtime/locations/domain-store-contract.ts +12 -3
- package/src/runtime/locations/in-memory-authority-store.ts +44 -15
- package/src/runtime/locations/in-memory-location-store.ts +50 -39
- package/src/runtime/locations/in-memory-provider-location-store.ts +110 -31
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +16 -45
- package/src/runtime/locations/location-store-failure.ts +4 -0
- package/src/runtime/locations/location-store-pages.ts +18 -0
- package/src/runtime/locations/location-store-repository.ts +450 -478
- package/src/runtime/locations/relocation-blob.ts +17 -6
- package/src/runtime/locations/resolvers.ts +90 -58
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +54 -26
- package/src/runtime/messaging/payload-codec.ts +35 -24
- package/src/runtime/messaging/submission-result.ts +57 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +27 -10
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +6 -3
- package/src/runtime/spots/index.ts +687 -437
- package/src/runtime/spots/spot-activation-registry.ts +42 -71
- package/src/runtime/spots/spot-activation-state.ts +4 -16
- package/src/runtime/spots/spot-activation.ts +167 -115
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +25 -79
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
- package/src/runtime/spots/spot-actor-membership.ts +107 -75
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
- package/src/runtime/spots/spot-context.ts +3 -3
- package/src/runtime/spots/spot-entry-activation.ts +13 -33
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +29 -21
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +145 -140
- package/src/runtime/spots/spot-outbound.ts +47 -68
- package/src/runtime/spots/spot-remote-codec.ts +7 -3
- package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
- package/src/runtime/spots/spot-route-replies.ts +6 -4
- package/src/runtime/spots/spot-routed-actor-admission.ts +13 -6
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -77
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +10 -43
- package/src/runtime/spots/spot-serial-executor.ts +10 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +120 -13
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +182 -560
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +1 -19
- package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
- package/src/runtime/streams/bound-session-service.ts +23 -37
- package/src/runtime/streams/index.ts +102 -88
- package/src/runtime/streams/managed-stream.ts +29 -10
- package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
- package/src/runtime/streams/protocol.ts +34 -88
- package/src/runtime/streams/session-actor-coordinator.ts +17 -5
- package/src/runtime/streams/session-calls.ts +6 -5
- package/src/runtime/streams/session-context.ts +54 -10
- package/src/runtime/streams/session-requests.ts +2 -1
- package/src/runtime/streams/session-serial-executor.ts +2 -2
- package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
- package/src/runtime/streams/stream-frame-factory.ts +2 -3
- package/src/runtime/streams/stream-session-runtime.ts +57 -59
- package/src/runtime/workers/index.ts +13 -12
- package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
- package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
- package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
- package/dist/runtime/actors/post-commit-actor-location.js +0 -72
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
- package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
- package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
- package/src/runtime/actors/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -1,42 +1,58 @@
|
|
|
1
|
+
import { RuntimeDisposal } from '../disposal';
|
|
2
|
+
import { UINT64_MAX } from '@zlink-systems/stream-wire';
|
|
3
|
+
import { randomBytes, randomUUID } from 'node:crypto';
|
|
1
4
|
import {
|
|
2
5
|
ZLinkFrameworkRuntimeState,
|
|
3
6
|
type RoutingId,
|
|
4
7
|
type ZLinkClientServerServerDescriptor,
|
|
5
8
|
type ZLinkFanoutPublisherDescriptor
|
|
6
9
|
} from '../../contracts';
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
10
|
+
import { ZLINK_MAX_ROUTING_ID_BYTES } from '../../contracts/Common/CoreTypes';
|
|
11
|
+
import type { Message } from '../../contracts/Common/Message';
|
|
9
12
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from '
|
|
13
|
+
isValidPublicWeight,
|
|
14
|
+
ZLINK_DEFAULT_PUBLIC_WEIGHT,
|
|
15
|
+
ZLINK_MAX_PUBLIC_WEIGHT
|
|
16
|
+
} from '../../contracts/Configuration/RegistrationBuilderPolicy';
|
|
17
|
+
import type { ZLinkChannelOptions } from '../../contracts/Configuration/RegistrationTypes';
|
|
18
|
+
import { attachEndpointConnections } from '../../contracts/Configuration/RuntimeEndpointConnections';
|
|
19
|
+
import { createAbortError, throwIfAborted } from '../abort';
|
|
14
20
|
import type {
|
|
15
21
|
ZLinkBackendContext,
|
|
16
22
|
ZLinkBackendDealerSocket,
|
|
17
23
|
ZLinkBackendPublisherSocket,
|
|
18
|
-
ZLinkBackendRouterSocket,
|
|
19
24
|
ZLinkBackendReadablePoller,
|
|
25
|
+
ZLinkBackendRouterSocket,
|
|
20
26
|
ZLinkBackendSocketMonitor,
|
|
21
27
|
ZLinkBackendSocketMonitorEvent,
|
|
22
28
|
ZLinkBackendSubscriberSocket,
|
|
23
29
|
ZLinkChannelBackendAdapter,
|
|
24
30
|
ZLinkMonitoringBackendAdapter
|
|
25
31
|
} from '../backend/contracts';
|
|
26
|
-
import { throwIfAborted } from '../abort';
|
|
27
|
-
import { attachEndpointConnections } from '../../contracts/Configuration/RuntimeEndpointConnections';
|
|
28
|
-
import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
|
|
29
|
-
import {
|
|
30
|
-
ZLinkFrameworkInternalErrorKind,
|
|
31
|
-
createInternalFrameworkException
|
|
32
|
-
} from '../framework-errors-internal';
|
|
33
|
-
import { randomBytes, randomUUID } from 'node:crypto';
|
|
34
32
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
35
|
-
import
|
|
36
|
-
import {
|
|
33
|
+
import { isBackendRequestTimeoutError } from '../backend/runtime-values';
|
|
34
|
+
import {
|
|
35
|
+
buildAdvertisedEndpoint,
|
|
36
|
+
ZLinkConfigurationException,
|
|
37
|
+
type ZLinkFrameworkRegistration
|
|
38
|
+
} from '../configuration';
|
|
39
|
+
import { ZLinkSocketNativeEventType } from '../diagnostics/internal-event-contracts';
|
|
40
|
+
import { ZLinkListenerRecords } from '../foundation/listener-records';
|
|
37
41
|
import { discoveryAvailabilityForRuntimeState } from '../foundation/runtime-state-projections';
|
|
42
|
+
import { ServiceDiscoveryRegistry } from '../foundation/service-discovery-registry';
|
|
43
|
+
import {
|
|
44
|
+
DEFAULT_SERVICE_PEER_TIMEOUT_MS,
|
|
45
|
+
DEFAULT_SERVICE_PROBE_INTERVAL_MS
|
|
46
|
+
} from '../foundation/service-liveness-registry';
|
|
38
47
|
import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
|
|
39
48
|
import {
|
|
49
|
+
createInternalFrameworkException,
|
|
50
|
+
ZLinkFrameworkInternalErrorKind
|
|
51
|
+
} from '../framework-errors-internal';
|
|
52
|
+
import type { ApplicationJobQueue } from '../host/application-job-queue';
|
|
53
|
+
import type { ZLinkChannelEnvelopeHeader } from './channel-envelope';
|
|
54
|
+
import {
|
|
55
|
+
ClientServerRejectReason,
|
|
40
56
|
decodeClientServerControl,
|
|
41
57
|
encodeClientServerAdmit,
|
|
42
58
|
encodeClientServerHello,
|
|
@@ -45,6 +61,7 @@ import {
|
|
|
45
61
|
encodeClientServerReject,
|
|
46
62
|
encodeClientServerUpdate,
|
|
47
63
|
isClientServerControlFrame,
|
|
64
|
+
normalizeClientServerMessageLimit,
|
|
48
65
|
type ZLinkClientServerAdmission
|
|
49
66
|
} from './client-server-service-wire';
|
|
50
67
|
import {
|
|
@@ -52,16 +69,13 @@ import {
|
|
|
52
69
|
FANOUT_LIVENESS_TOPIC,
|
|
53
70
|
inspectFanoutInbound
|
|
54
71
|
} from './fanout-service-wire';
|
|
55
|
-
import
|
|
56
|
-
import type { ApplicationJobQueue } from '../host/application-job-queue';
|
|
57
|
-
import { isBackendRequestTimeoutError } from '../backend/runtime-values';
|
|
72
|
+
import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
|
|
58
73
|
|
|
59
74
|
const MAX_LIFECYCLE_GENERATION = 0x7fff_ffff_ffff_ffffn;
|
|
60
|
-
const CLIENT_SERVER_PROBE_INTERVAL_MS =
|
|
61
|
-
const CLIENT_SERVER_PEER_DEADLINE_MS =
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
75
|
+
const CLIENT_SERVER_PROBE_INTERVAL_MS = DEFAULT_SERVICE_PROBE_INTERVAL_MS;
|
|
76
|
+
const CLIENT_SERVER_PEER_DEADLINE_MS = DEFAULT_SERVICE_PEER_TIMEOUT_MS;
|
|
77
|
+
const CLIENT_SERVER_LIVENESS_TICK_MS = 100;
|
|
78
|
+
const DEFAULT_SEND_TIMEOUT_MS = 1_000;
|
|
65
79
|
|
|
66
80
|
export interface ZLinkClientServerServerSocketIdentity {
|
|
67
81
|
readonly serverRid: string;
|
|
@@ -80,12 +94,11 @@ interface ClientServerPhysicalConnection {
|
|
|
80
94
|
readonly channelName: string;
|
|
81
95
|
readonly endpoint: string;
|
|
82
96
|
readonly dealer: ZLinkBackendDealerSocket;
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
readablePoller?: ZLinkBackendReadablePoller;
|
|
98
|
+
monitor?: ZLinkBackendSocketMonitor;
|
|
85
99
|
readonly aliases: Set<string>;
|
|
86
100
|
readonly callbacksByAlias: Map<string, ZLinkClientServerConnectionCallbacks>;
|
|
87
101
|
physicalConnectionId: symbol;
|
|
88
|
-
terminationRequested: boolean;
|
|
89
102
|
readyConnectionId?: string;
|
|
90
103
|
admittedDescriptor?: ClientServerDiscoveryDescriptor;
|
|
91
104
|
nextProbeAt?: number;
|
|
@@ -103,7 +116,7 @@ interface FanoutPublisherConnection {
|
|
|
103
116
|
readonly channelName: string;
|
|
104
117
|
readonly endpoint: string;
|
|
105
118
|
readonly subscriber: ZLinkBackendSubscriberSocket;
|
|
106
|
-
|
|
119
|
+
monitor?: ZLinkBackendSocketMonitor;
|
|
107
120
|
readonly callbacks: ZLinkFanoutConnectionCallbacks;
|
|
108
121
|
readonly physicalConnectionId: symbol;
|
|
109
122
|
transportReady: boolean;
|
|
@@ -155,14 +168,20 @@ export class ZLinkChannelSocketRegistry {
|
|
|
155
168
|
outstandingProbeId?: bigint;
|
|
156
169
|
}
|
|
157
170
|
>();
|
|
158
|
-
private readonly
|
|
171
|
+
private readonly disposal = new RuntimeDisposal();
|
|
172
|
+
private readonly ownedResources = new Set<
|
|
173
|
+
| ZLinkBackendSocketMonitor
|
|
174
|
+
| ZLinkBackendReadablePoller
|
|
175
|
+
| ZLinkBackendDealerSocket
|
|
176
|
+
| ZLinkBackendSubscriberSocket
|
|
177
|
+
>();
|
|
159
178
|
private readonly fanoutConnections = new Map<string, FanoutPublisherConnection>();
|
|
160
179
|
private readonly fanoutPublisherNextBeacon = new Map<string, number>();
|
|
161
180
|
private clientServerLivenessTimer?: NodeJS.Timeout;
|
|
162
181
|
private nextClientServerProbeId = 1n;
|
|
163
182
|
private readonly clientServerMonitorHandlers = new Map<
|
|
164
183
|
string,
|
|
165
|
-
Set<(event
|
|
184
|
+
Set<(event?: ZLinkBackendSocketMonitorEvent) => void>
|
|
166
185
|
>();
|
|
167
186
|
private readonly fanoutMonitorHandlers = new Map<
|
|
168
187
|
string,
|
|
@@ -170,19 +189,34 @@ export class ZLinkChannelSocketRegistry {
|
|
|
170
189
|
>();
|
|
171
190
|
private readonly fanoutTopologyHandlers = new Map<string, Set<() => void>>();
|
|
172
191
|
|
|
192
|
+
private readonly listenerRecords: ZLinkListenerRecords;
|
|
193
|
+
|
|
173
194
|
constructor(
|
|
174
195
|
private readonly registration: ZLinkFrameworkRegistration,
|
|
175
196
|
private readonly adapter: ZLinkChannelBackendAdapter,
|
|
176
197
|
private readonly context: ZLinkBackendContext,
|
|
177
198
|
private readonly monitoringAdapter?: ZLinkMonitoringBackendAdapter,
|
|
178
199
|
private readonly oneWayFailureSink?: (error: unknown) => void,
|
|
179
|
-
private readonly applicationJobQueue?: ApplicationJobQueue
|
|
180
|
-
|
|
200
|
+
private readonly applicationJobQueue?: ApplicationJobQueue,
|
|
201
|
+
listenerRecords?: ZLinkListenerRecords
|
|
202
|
+
) {
|
|
203
|
+
this.listenerRecords = listenerRecords ?? new ZLinkListenerRecords();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
dispose(): Promise<void> {
|
|
207
|
+
return this.disposal.run(() => this.disposeCore());
|
|
208
|
+
}
|
|
181
209
|
|
|
182
|
-
async
|
|
210
|
+
private async disposeCore(): Promise<void> {
|
|
211
|
+
this.clientServerDiscovery.dispose(
|
|
212
|
+
createInternalFrameworkException(
|
|
213
|
+
ZLinkFrameworkInternalErrorKind.RuntimeShutdown,
|
|
214
|
+
'Channel sockets are shutting down.'
|
|
215
|
+
)
|
|
216
|
+
);
|
|
183
217
|
const clientServerConnections = [...new Set(this.clientServerConnections.values())];
|
|
184
|
-
const clientServerPollers = clientServerConnections.
|
|
185
|
-
|
|
218
|
+
const clientServerPollers = clientServerConnections.flatMap((connection) =>
|
|
219
|
+
connection.readablePoller === undefined ? [] : [connection.readablePoller]
|
|
186
220
|
);
|
|
187
221
|
const sockets = [
|
|
188
222
|
...this.clientDealers.values(),
|
|
@@ -199,8 +233,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
199
233
|
...this.routeRouters.values()
|
|
200
234
|
]))
|
|
201
235
|
this.unregisterReceiveFlowSocket(socket);
|
|
202
|
-
this.clientDealers.clear();
|
|
203
|
-
this.clientServerConnections.clear();
|
|
204
236
|
this.clientServerReadyIdentities.clear();
|
|
205
237
|
this.clientServerServerDescriptors.clear();
|
|
206
238
|
this.clientServerPublicWeights.clear();
|
|
@@ -210,23 +242,37 @@ export class ZLinkChannelSocketRegistry {
|
|
|
210
242
|
this.clientServerMonitorHandlers.clear();
|
|
211
243
|
this.fanoutMonitorHandlers.clear();
|
|
212
244
|
this.fanoutTopologyHandlers.clear();
|
|
213
|
-
this.fanoutConnections.clear();
|
|
214
245
|
this.fanoutPublisherNextBeacon.clear();
|
|
215
246
|
if (this.clientServerLivenessTimer !== undefined) {
|
|
216
247
|
clearInterval(this.clientServerLivenessTimer);
|
|
217
248
|
this.clientServerLivenessTimer = undefined;
|
|
218
249
|
}
|
|
219
|
-
this.channelRouters.clear();
|
|
220
|
-
this.publishers.clear();
|
|
221
|
-
this.routeRouters.clear();
|
|
222
250
|
this.routeMembers.clear();
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
251
|
+
const cleanup = await Promise.allSettled(
|
|
252
|
+
[...new Set([...clientServerPollers, ...this.ownedResources, ...sockets])].map(
|
|
253
|
+
async (resource) => {
|
|
254
|
+
await resource.dispose();
|
|
255
|
+
this.ownedResources.delete(resource as ZLinkBackendSocketMonitor);
|
|
256
|
+
for (const owners of [
|
|
257
|
+
this.clientDealers,
|
|
258
|
+
this.channelRouters,
|
|
259
|
+
this.publishers,
|
|
260
|
+
this.routeRouters
|
|
261
|
+
]) {
|
|
262
|
+
for (const [name, owned] of owners) if (owned === resource) owners.delete(name);
|
|
263
|
+
}
|
|
264
|
+
for (const [name, owned] of this.clientServerConnections) {
|
|
265
|
+
if (owned.dealer === resource) this.clientServerConnections.delete(name);
|
|
266
|
+
if (owned.readablePoller === resource) owned.readablePoller = undefined;
|
|
267
|
+
if (owned.monitor === resource) owned.monitor = undefined;
|
|
268
|
+
}
|
|
269
|
+
for (const [name, owned] of this.fanoutConnections) {
|
|
270
|
+
if (owned.subscriber === resource) this.fanoutConnections.delete(name);
|
|
271
|
+
if (owned.monitor === resource) owned.monitor = undefined;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
)
|
|
275
|
+
);
|
|
230
276
|
const errors = cleanup
|
|
231
277
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
232
278
|
.map((result) => result.reason);
|
|
@@ -247,13 +293,16 @@ export class ZLinkChannelSocketRegistry {
|
|
|
247
293
|
}
|
|
248
294
|
|
|
249
295
|
const dealer = this.adapter.createDealerSocket(this.context);
|
|
296
|
+
this.clientDealers.set(channelName, dealer);
|
|
250
297
|
this.registerReceiveFlowSocket(dealer);
|
|
251
298
|
dealer.setChannelName(channelName);
|
|
252
299
|
if (channel?.routingId !== undefined && channel.routingId.length > 0) {
|
|
253
300
|
dealer.setRoutingId(deriveRoutingId(channel.routingId, 'dealer'));
|
|
254
301
|
}
|
|
255
|
-
applySocketConfig(dealer,
|
|
256
|
-
|
|
302
|
+
applySocketConfig(dealer, {
|
|
303
|
+
...client,
|
|
304
|
+
sendTimeoutMs: configuredSendTimeoutMs(client.sendTimeoutMs)
|
|
305
|
+
});
|
|
257
306
|
return dealer;
|
|
258
307
|
}
|
|
259
308
|
|
|
@@ -274,6 +323,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
274
323
|
}
|
|
275
324
|
|
|
276
325
|
const router = this.adapter.createRouterSocket(this.context);
|
|
326
|
+
this.channelRouters.set(channelName, router);
|
|
277
327
|
this.registerReceiveFlowSocket(router);
|
|
278
328
|
router.setChannelName(channelName);
|
|
279
329
|
const identity = this.clientServerIdentities.get(channelName) ?? {
|
|
@@ -282,14 +332,14 @@ export class ZLinkChannelSocketRegistry {
|
|
|
282
332
|
};
|
|
283
333
|
this.clientServerIdentities.set(channelName, identity);
|
|
284
334
|
router.setRoutingId(identity.serverRid);
|
|
285
|
-
const publicWeight = channel.server.weight ??
|
|
335
|
+
const publicWeight = channel.server.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
286
336
|
this.clientServerPublicWeights.set(channelName, publicWeight);
|
|
287
337
|
router.peerWeight = rawAvailabilityWeight(publicWeight);
|
|
288
338
|
applySocketConfig(router, channel.server);
|
|
289
339
|
router.bind(channel.server.bind);
|
|
290
340
|
if (this.monitoringAdapter !== undefined) {
|
|
291
341
|
const monitor = this.monitoringAdapter.openSocketMonitor(router);
|
|
292
|
-
this.
|
|
342
|
+
this.ownedResources.add(monitor);
|
|
293
343
|
monitor.onEvent((event) => {
|
|
294
344
|
if (event.routingId === undefined) return;
|
|
295
345
|
if (
|
|
@@ -305,15 +355,18 @@ export class ZLinkChannelSocketRegistry {
|
|
|
305
355
|
this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
|
|
306
356
|
});
|
|
307
357
|
}
|
|
308
|
-
|
|
358
|
+
const endpoint = advertisedEndpoint(
|
|
359
|
+
router.lastEndpoint ?? channel.server.bind,
|
|
360
|
+
channel.server.advertiseHost
|
|
361
|
+
);
|
|
362
|
+
this.recordListener('clientServer', channelName, endpoint);
|
|
309
363
|
if (!this.clientServerServerDescriptors.has(channelName)) {
|
|
310
|
-
const boundEndpoint = router.lastEndpoint ?? channel.server.bind;
|
|
311
364
|
this.clientServerServerDescriptors.set(channelName, {
|
|
312
365
|
channelName,
|
|
313
366
|
serverRid: identity.serverRid,
|
|
314
367
|
lifecycleGeneration: identity.lifecycleGeneration,
|
|
315
368
|
descriptorRevision: 1n,
|
|
316
|
-
endpoint
|
|
369
|
+
endpoint,
|
|
317
370
|
weight: publicWeight,
|
|
318
371
|
state: ZLinkFrameworkRuntimeState.Serving,
|
|
319
372
|
securityIdentity: 'default',
|
|
@@ -326,22 +379,21 @@ export class ZLinkChannelSocketRegistry {
|
|
|
326
379
|
}
|
|
327
380
|
|
|
328
381
|
clientServerServerIdentity(channelName: string): ZLinkClientServerServerSocketIdentity {
|
|
329
|
-
|
|
382
|
+
this.channelRouter(channelName);
|
|
330
383
|
const identity = this.clientServerIdentities.get(channelName);
|
|
331
|
-
const
|
|
332
|
-
if (identity === undefined ||
|
|
384
|
+
const endpoint = this.listenerRecords.endpoint('clientServer', channelName);
|
|
385
|
+
if (identity === undefined || endpoint === undefined) {
|
|
333
386
|
throw new ZLinkConfigurationException(`Channel server '${channelName}' is not registered.`);
|
|
334
387
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
};
|
|
388
|
+
return { ...identity, endpoint };
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
fanoutPublisherEndpoint(channelName: string): string | undefined {
|
|
392
|
+
return this.listenerRecords.endpoint('fanout', channelName);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private recordListener(kind: 'clientServer' | 'fanout', name: string, endpoint: string): void {
|
|
396
|
+
this.listenerRecords.record(kind, name, endpoint);
|
|
345
397
|
}
|
|
346
398
|
|
|
347
399
|
clientServerServerSocket(channelName: string): ZLinkBackendRouterSocket {
|
|
@@ -350,7 +402,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
350
402
|
|
|
351
403
|
clientServerServerWeight(channelName: string): number {
|
|
352
404
|
this.channelRouter(channelName);
|
|
353
|
-
return this.clientServerPublicWeights.get(channelName) ??
|
|
405
|
+
return this.clientServerPublicWeights.get(channelName) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
354
406
|
}
|
|
355
407
|
|
|
356
408
|
setClientServerServerWeight(channelName: string, weight: number): void {
|
|
@@ -382,47 +434,38 @@ export class ZLinkChannelSocketRegistry {
|
|
|
382
434
|
throw new ZLinkConfigurationException(`Channel client '${channelName}' is not registered.`);
|
|
383
435
|
}
|
|
384
436
|
const dealer = this.adapter.createDealerSocket(this.context);
|
|
385
|
-
this.registerReceiveFlowSocket(dealer);
|
|
386
|
-
dealer.setChannelName(channelName);
|
|
387
|
-
dealer.setRoutingId(`cs-client-${randomUUID()}`);
|
|
388
|
-
applySocketConfig(dealer, client);
|
|
389
|
-
const cleanupDealer = (): void => {
|
|
390
|
-
this.unregisterReceiveFlowSocket(dealer);
|
|
391
|
-
void Promise.allSettled([dealer.dispose()]);
|
|
392
|
-
};
|
|
393
|
-
let readablePoller: ZLinkBackendReadablePoller;
|
|
394
|
-
try {
|
|
395
|
-
readablePoller = this.adapter.createReadablePoller(dealer);
|
|
396
|
-
} catch (error) {
|
|
397
|
-
cleanupDealer();
|
|
398
|
-
throw error;
|
|
399
|
-
}
|
|
400
|
-
let monitor: ZLinkBackendSocketMonitor;
|
|
401
|
-
try {
|
|
402
|
-
monitor = this.monitoringAdapter.openSocketMonitor(dealer);
|
|
403
|
-
} catch (error) {
|
|
404
|
-
try {
|
|
405
|
-
readablePoller.dispose();
|
|
406
|
-
} finally {
|
|
407
|
-
cleanupDealer();
|
|
408
|
-
}
|
|
409
|
-
throw error;
|
|
410
|
-
}
|
|
411
|
-
this.ownedMonitors.add(monitor);
|
|
412
437
|
const connection: ClientServerPhysicalConnection = {
|
|
413
438
|
channelName,
|
|
414
439
|
endpoint,
|
|
415
440
|
dealer,
|
|
416
|
-
readablePoller,
|
|
417
|
-
monitor,
|
|
418
441
|
aliases: new Set([connectionId]),
|
|
419
442
|
callbacksByAlias: new Map([[connectionId, callbacks]]),
|
|
420
|
-
physicalConnectionId: Symbol(connectionId)
|
|
421
|
-
terminationRequested: false
|
|
443
|
+
physicalConnectionId: Symbol(connectionId)
|
|
422
444
|
};
|
|
423
|
-
this.
|
|
424
|
-
|
|
445
|
+
this.ownedResources.add(dealer);
|
|
446
|
+
const created: (
|
|
447
|
+
| ZLinkBackendSocketMonitor
|
|
448
|
+
| ZLinkBackendReadablePoller
|
|
449
|
+
| ZLinkBackendDealerSocket
|
|
450
|
+
| ZLinkBackendSubscriberSocket
|
|
451
|
+
)[] = [dealer];
|
|
425
452
|
try {
|
|
453
|
+
this.clientServerConnections.set(connectionId, connection);
|
|
454
|
+
this.registerReceiveFlowSocket(dealer);
|
|
455
|
+
dealer.setChannelName(channelName);
|
|
456
|
+
dealer.setRoutingId(`cs-client-${randomUUID()}`);
|
|
457
|
+
applySocketConfig(dealer, {
|
|
458
|
+
...client,
|
|
459
|
+
sendTimeoutMs: configuredSendTimeoutMs(client.sendTimeoutMs)
|
|
460
|
+
});
|
|
461
|
+
connection.readablePoller = this.adapter.createReadablePoller(dealer);
|
|
462
|
+
created.push(connection.readablePoller);
|
|
463
|
+
this.ownedResources.add(connection.readablePoller);
|
|
464
|
+
const monitor = this.monitoringAdapter.openSocketMonitor(dealer);
|
|
465
|
+
connection.monitor = monitor;
|
|
466
|
+
created.push(monitor);
|
|
467
|
+
this.ownedResources.add(monitor);
|
|
468
|
+
this.ensureClientServerLivenessTimer();
|
|
426
469
|
monitor.onEvent((event) => {
|
|
427
470
|
if (
|
|
428
471
|
![...connection.aliases].some(
|
|
@@ -436,7 +479,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
436
479
|
const routingId = event.routingId === undefined ? undefined : String(event.routingId);
|
|
437
480
|
if (event.nativeEvent === ZLinkSocketNativeEventType.ConnectionReady) {
|
|
438
481
|
// This single-endpoint DEALER also receives its disconnected ready-count snapshot.
|
|
439
|
-
if (event.value === 0n
|
|
482
|
+
if (event.value === 0n) return;
|
|
440
483
|
connection.physicalConnectionId = Symbol(connectionId);
|
|
441
484
|
connection.admissionAttempt = undefined;
|
|
442
485
|
for (const currentCallbacks of [...connection.callbacksByAlias.values()]) {
|
|
@@ -451,47 +494,32 @@ export class ZLinkChannelSocketRegistry {
|
|
|
451
494
|
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedProtocol ||
|
|
452
495
|
event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedAuth
|
|
453
496
|
) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
(event.nativeEvent !== ZLinkSocketNativeEventType.Disconnected &&
|
|
458
|
-
event.nativeEvent !== ZLinkSocketNativeEventType.Closed))
|
|
459
|
-
)
|
|
460
|
-
return;
|
|
461
|
-
connection.physicalConnectionId = Symbol(connectionId);
|
|
462
|
-
connection.admissionAttempt = undefined;
|
|
463
|
-
if (connection.readyConnectionId !== undefined) {
|
|
464
|
-
this.removeReadyConnection(connection.readyConnectionId);
|
|
465
|
-
}
|
|
466
|
-
for (const currentCallbacks of [...connection.callbacksByAlias.values()]) {
|
|
467
|
-
currentCallbacks.onTerminated(routingId, event.remoteAddr);
|
|
468
|
-
}
|
|
469
|
-
if (connection.terminationRequested) {
|
|
470
|
-
connection.terminationRequested = false;
|
|
471
|
-
// Explicit disconnect removes intent; restore it once after this endpoint closes.
|
|
472
|
-
connection.dealer.connect(connection.endpoint);
|
|
473
|
-
}
|
|
497
|
+
// Core owns the endpoint reconnect (transport liveness §6); the
|
|
498
|
+
// connect intent stays and the next READY starts a new admission.
|
|
499
|
+
this.endClientServerAdmission(connectionId, connection, routingId, event.remoteAddr);
|
|
474
500
|
}
|
|
475
501
|
});
|
|
476
502
|
dealer.connect(endpoint);
|
|
503
|
+
return dealer;
|
|
477
504
|
} catch (error) {
|
|
478
505
|
this.clientServerConnections.delete(connectionId);
|
|
479
|
-
this.
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
506
|
+
this.unregisterReceiveFlowSocket(dealer);
|
|
507
|
+
void Promise.allSettled(
|
|
508
|
+
created.map(async (resource) => {
|
|
509
|
+
await resource.dispose();
|
|
510
|
+
this.ownedResources.delete(resource);
|
|
511
|
+
})
|
|
512
|
+
).then((results) => {
|
|
513
|
+
for (const result of results)
|
|
514
|
+
if (result.status === 'rejected') this.oneWayFailureSink?.(result.reason);
|
|
515
|
+
});
|
|
486
516
|
throw error;
|
|
487
517
|
}
|
|
488
|
-
return dealer;
|
|
489
518
|
}
|
|
490
519
|
|
|
491
520
|
async closeClientServerConnection(connectionId: string): Promise<void> {
|
|
492
521
|
const current = this.clientServerConnections.get(connectionId);
|
|
493
522
|
if (current === undefined) return;
|
|
494
|
-
this.clientServerConnections.delete(connectionId);
|
|
495
523
|
current.aliases.delete(connectionId);
|
|
496
524
|
current.callbacksByAlias.delete(connectionId);
|
|
497
525
|
const ready = this.clientServerReadyIdentities.get(connectionId);
|
|
@@ -517,8 +545,13 @@ export class ZLinkChannelSocketRegistry {
|
|
|
517
545
|
});
|
|
518
546
|
}
|
|
519
547
|
}
|
|
520
|
-
|
|
548
|
+
this.notifyClientServerTopology(current.channelName);
|
|
549
|
+
if (current.aliases.size > 0) {
|
|
550
|
+
this.clientServerConnections.delete(connectionId);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
521
553
|
await this.disposeClientServerPhysical(connectionId, current);
|
|
554
|
+
this.clientServerConnections.delete(connectionId);
|
|
522
555
|
}
|
|
523
556
|
|
|
524
557
|
private async disposeClientServerPhysical(
|
|
@@ -528,12 +561,21 @@ export class ZLinkChannelSocketRegistry {
|
|
|
528
561
|
try {
|
|
529
562
|
current.dealer.disconnect(current.endpoint);
|
|
530
563
|
} catch {
|
|
531
|
-
//
|
|
564
|
+
// The socket close below releases an endpoint that is already disconnected.
|
|
532
565
|
}
|
|
533
|
-
this.ownedMonitors.delete(current.monitor);
|
|
534
566
|
this.unregisterReceiveFlowSocket(current.dealer);
|
|
535
|
-
current.readablePoller
|
|
536
|
-
|
|
567
|
+
if (current.readablePoller !== undefined) {
|
|
568
|
+
current.readablePoller.dispose();
|
|
569
|
+
this.ownedResources.delete(current.readablePoller);
|
|
570
|
+
current.readablePoller = undefined;
|
|
571
|
+
}
|
|
572
|
+
const results = await Promise.allSettled([
|
|
573
|
+
current.monitor?.dispose(),
|
|
574
|
+
(async () => {
|
|
575
|
+
await current.dealer.dispose();
|
|
576
|
+
this.ownedResources.delete(current.dealer);
|
|
577
|
+
})()
|
|
578
|
+
]);
|
|
537
579
|
const errors = results
|
|
538
580
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
539
581
|
.map((result) => result.reason);
|
|
@@ -541,6 +583,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
541
583
|
if (errors.length > 1) {
|
|
542
584
|
throw new AggregateError(errors, `ClientServer connection '${connectionId}' cleanup failed.`);
|
|
543
585
|
}
|
|
586
|
+
if (current.monitor !== undefined) this.ownedResources.delete(current.monitor);
|
|
544
587
|
}
|
|
545
588
|
|
|
546
589
|
admitClientServerConnection(
|
|
@@ -555,6 +598,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
555
598
|
connection.readyConnectionId
|
|
556
599
|
);
|
|
557
600
|
if (admitted) connection.admittedDescriptor = descriptor;
|
|
601
|
+
this.notifyClientServerTopology(descriptor.channelName);
|
|
558
602
|
return admitted;
|
|
559
603
|
}
|
|
560
604
|
const duplicateId = [...this.clientServerReadyIdentities].find(
|
|
@@ -592,6 +636,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
592
636
|
connection.readyConnectionId = connectionId;
|
|
593
637
|
connection.admittedDescriptor = descriptor;
|
|
594
638
|
}
|
|
639
|
+
this.notifyClientServerTopology(descriptor.channelName);
|
|
595
640
|
return admitted;
|
|
596
641
|
}
|
|
597
642
|
|
|
@@ -615,6 +660,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
615
660
|
connection.outstandingProbeId = undefined;
|
|
616
661
|
}
|
|
617
662
|
}
|
|
663
|
+
this.notifyClientServerTopology(channelName);
|
|
618
664
|
return removed;
|
|
619
665
|
}
|
|
620
666
|
|
|
@@ -646,52 +692,60 @@ export class ZLinkChannelSocketRegistry {
|
|
|
646
692
|
return undefined;
|
|
647
693
|
}
|
|
648
694
|
|
|
649
|
-
/**
|
|
650
|
-
* Resolves a ClientServer send target, waiting when the ready candidate set is still empty, as
|
|
651
|
-
* `framework/doc/framework/common/spec/server/02-channel-transport/02-channel-messaging.ko.md` §3.2 requires: the call waits
|
|
652
|
-
* at call time for a bounded period and then fails with no-target. The bound is the shorter of
|
|
653
|
-
* the call's remaining deadline and five seconds, mirroring the .NET reference
|
|
654
|
-
* `ZLinkClientServerClientRuntime.WaitForReadyAsync`. The wait lives here because this registry
|
|
655
|
-
* owns ClientServer connections, admission and weighted selection. Sends have no per-call
|
|
656
|
-
* timeout, so they use the Channel's request timeout.
|
|
657
|
-
*
|
|
658
|
-
* The wait only observes admission that is already in flight: it never opens or reconnects a
|
|
659
|
-
* connection, so it cannot trigger the admission it waits for, and Framework startup keeps not
|
|
660
|
-
* waiting for local ClientServer admission. It applies whenever nothing is selectable, including
|
|
661
|
-
* candidate sets excluded by weight 0 or drain, because `selectClientServerDealer` filters the
|
|
662
|
-
* same way the reference `SelectReady()` does.
|
|
663
|
-
*
|
|
664
|
-
* Every attempt yields to the event loop between polls. ClientServer admission completes on the
|
|
665
|
-
* monitor drains that the backend poll timer pumps, so a synchronous wait would starve the
|
|
666
|
-
* admission it is waiting for and burn the whole bound before failing anyway. That is this
|
|
667
|
-
* execution model's form of the hazard the JVM mirror avoids by not holding the admission
|
|
668
|
-
* monitor across its sleep.
|
|
669
|
-
*/
|
|
695
|
+
/** Observes discovery changes until the client DEALER admission deadline. */
|
|
670
696
|
async awaitClientDealerForOutbound(
|
|
671
697
|
channelName: string,
|
|
672
|
-
signal?: AbortSignal
|
|
673
|
-
deadlineAtMs?: number
|
|
698
|
+
signal?: AbortSignal
|
|
674
699
|
): Promise<ZLinkBackendDealerSocket | undefined> {
|
|
675
|
-
|
|
676
|
-
const
|
|
677
|
-
deadlineAtMs ??
|
|
678
|
-
startedAtMs +
|
|
679
|
-
(this.registration.channels.get(channelName)?.requestTimeoutMs ??
|
|
680
|
-
this.registration.requestTimeoutMs ??
|
|
681
|
-
DEFAULT_REQUEST_TIMEOUT_MS),
|
|
682
|
-
startedAtMs + CLIENT_SERVER_READY_WAIT_CAP_MS
|
|
683
|
-
);
|
|
684
|
-
for (;;) {
|
|
685
|
-
this.drainSocketMonitors();
|
|
700
|
+
throwIfAborted(signal);
|
|
701
|
+
const select = (): ZLinkBackendDealerSocket | undefined => {
|
|
686
702
|
const dealer = this.clientDealerForOutbound(channelName);
|
|
687
703
|
if (dealer !== undefined) return dealer;
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}
|
|
694
|
-
|
|
704
|
+
if (this.clientServerDiscovery.hasReadyClientServer(channelName)) {
|
|
705
|
+
throw createInternalFrameworkException(
|
|
706
|
+
ZLinkFrameworkInternalErrorKind.RouteNotConnected,
|
|
707
|
+
`Channel '${channelName}' has no eligible ClientServer member.`
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
return undefined;
|
|
711
|
+
};
|
|
712
|
+
const dealer = select();
|
|
713
|
+
if (dealer !== undefined) return dealer;
|
|
714
|
+
const sendTimeoutMs = configuredSendTimeoutMs(
|
|
715
|
+
this.registration.channels.get(channelName)?.client?.sendTimeoutMs
|
|
716
|
+
);
|
|
717
|
+
return new Promise((resolve, reject) => {
|
|
718
|
+
const cleanup = (): void => {
|
|
719
|
+
clearTimeout(deadline);
|
|
720
|
+
unsubscribe();
|
|
721
|
+
signal?.removeEventListener('abort', abort);
|
|
722
|
+
};
|
|
723
|
+
const abort = (): void => {
|
|
724
|
+
cleanup();
|
|
725
|
+
reject(createAbortError());
|
|
726
|
+
};
|
|
727
|
+
const changed = (error?: Error): void => {
|
|
728
|
+
try {
|
|
729
|
+
if (error !== undefined) throw error;
|
|
730
|
+
const selected = select();
|
|
731
|
+
if (selected === undefined) return;
|
|
732
|
+
cleanup();
|
|
733
|
+
resolve(selected);
|
|
734
|
+
} catch (error) {
|
|
735
|
+
cleanup();
|
|
736
|
+
reject(error);
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
const unsubscribe = this.clientServerDiscovery.onClientServerChanged(changed);
|
|
740
|
+
const deadline = setTimeout(() => {
|
|
741
|
+
cleanup();
|
|
742
|
+
resolve(undefined);
|
|
743
|
+
}, sendTimeoutMs);
|
|
744
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
745
|
+
// Registration and selection share one event-loop turn; recheck after subscribing.
|
|
746
|
+
changed();
|
|
747
|
+
if (signal?.aborted === true) abort();
|
|
748
|
+
});
|
|
695
749
|
}
|
|
696
750
|
|
|
697
751
|
startManualClientServerConnections(): void {
|
|
@@ -726,26 +780,41 @@ export class ZLinkChannelSocketRegistry {
|
|
|
726
780
|
}
|
|
727
781
|
}
|
|
728
782
|
|
|
729
|
-
clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor {
|
|
730
|
-
|
|
731
|
-
|
|
783
|
+
clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor & {
|
|
784
|
+
onChange(handler: () => void): void;
|
|
785
|
+
} {
|
|
786
|
+
const channel = this.registration.channels.get(channelName);
|
|
787
|
+
if (channel?.client === undefined && channel?.server === undefined) {
|
|
788
|
+
throw new ZLinkConfigurationException(
|
|
789
|
+
`ClientServer channel '${channelName}' is not registered.`
|
|
790
|
+
);
|
|
732
791
|
}
|
|
733
792
|
let disposed = false;
|
|
734
|
-
let handler: ((event
|
|
793
|
+
let handler: ((event?: ZLinkBackendSocketMonitorEvent) => void) | undefined;
|
|
794
|
+
const register = (next: (event?: ZLinkBackendSocketMonitorEvent) => void): void => {
|
|
795
|
+
if (disposed) return;
|
|
796
|
+
if (handler !== undefined) {
|
|
797
|
+
this.clientServerMonitorHandlers.get(channelName)?.delete(handler);
|
|
798
|
+
}
|
|
799
|
+
handler = next;
|
|
800
|
+
let handlers = this.clientServerMonitorHandlers.get(channelName);
|
|
801
|
+
if (handlers === undefined) {
|
|
802
|
+
handlers = new Set();
|
|
803
|
+
this.clientServerMonitorHandlers.set(channelName, handlers);
|
|
804
|
+
}
|
|
805
|
+
handlers.add(next);
|
|
806
|
+
};
|
|
735
807
|
return {
|
|
736
808
|
nativeInstance: {},
|
|
737
809
|
onEvent: (next) => {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
this.clientServerMonitorHandlers.set(channelName, handlers);
|
|
747
|
-
}
|
|
748
|
-
handlers.add(next);
|
|
810
|
+
register((event) => {
|
|
811
|
+
if (event !== undefined) next(event);
|
|
812
|
+
});
|
|
813
|
+
},
|
|
814
|
+
onChange: (next) => {
|
|
815
|
+
register((event) => {
|
|
816
|
+
if (event === undefined) next();
|
|
817
|
+
});
|
|
749
818
|
},
|
|
750
819
|
drain: () => 0,
|
|
751
820
|
dispose: async () => {
|
|
@@ -790,10 +859,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
790
859
|
);
|
|
791
860
|
}
|
|
792
861
|
|
|
793
|
-
hasKnownClientServerTargets(channelName: string): boolean {
|
|
794
|
-
return this.clientServerDiscovery.clientServerDescriptors(channelName).length > 0;
|
|
795
|
-
}
|
|
796
|
-
|
|
797
862
|
fanoutActiveTargets(channelName: string) {
|
|
798
863
|
return this.clientServerDiscovery.fanoutEndpoints(channelName);
|
|
799
864
|
}
|
|
@@ -836,6 +901,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
836
901
|
this.clientServerServerDescriptors.set(channelName, descriptor);
|
|
837
902
|
this.pushClientServerDescriptorUpdate(channelName, descriptor);
|
|
838
903
|
}
|
|
904
|
+
this.notifyClientServerTopology(channelName);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
private notifyClientServerTopology(channelName: string): void {
|
|
908
|
+
for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? []) handler();
|
|
839
909
|
}
|
|
840
910
|
|
|
841
911
|
tryHandleClientServerControl(
|
|
@@ -883,7 +953,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
883
953
|
received.parts.length !== 1 ||
|
|
884
954
|
received.replyToken === null
|
|
885
955
|
) {
|
|
886
|
-
reply = encodeClientServerReject(
|
|
956
|
+
reply = encodeClientServerReject(ClientServerRejectReason.ProtocolVersionUnsupported);
|
|
887
957
|
} else {
|
|
888
958
|
const descriptor = this.clientServerServerDescriptors.get(channelName);
|
|
889
959
|
if (
|
|
@@ -891,10 +961,10 @@ export class ZLinkChannelSocketRegistry {
|
|
|
891
961
|
record.hello.channelName !== channelName ||
|
|
892
962
|
record.hello.securityIdentity !== descriptor.securityIdentity
|
|
893
963
|
) {
|
|
894
|
-
reply = encodeClientServerReject(
|
|
964
|
+
reply = encodeClientServerReject(ClientServerRejectReason.AdmissionMismatch);
|
|
895
965
|
} else {
|
|
896
966
|
const normalizedEffectiveMaxMessageBytes = Math.min(
|
|
897
|
-
|
|
967
|
+
normalizeClientServerMessageLimit(router.maxMessageSize),
|
|
898
968
|
record.hello.normalizedEffectiveMaxMessageBytes
|
|
899
969
|
);
|
|
900
970
|
reply = encodeClientServerAdmit(descriptor, normalizedEffectiveMaxMessageBytes);
|
|
@@ -929,7 +999,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
929
999
|
this.drainClientServerControl(connectionId, connection);
|
|
930
1000
|
if (connection.deadlineAt === undefined) continue;
|
|
931
1001
|
if (nowMs >= connection.deadlineAt) {
|
|
932
|
-
this.
|
|
1002
|
+
this.restartClientServerAdmission(connectionId, connection);
|
|
933
1003
|
continue;
|
|
934
1004
|
}
|
|
935
1005
|
if (connection.nextProbeAt === undefined || nowMs < connection.nextProbeAt) continue;
|
|
@@ -980,23 +1050,31 @@ export class ZLinkChannelSocketRegistry {
|
|
|
980
1050
|
);
|
|
981
1051
|
}
|
|
982
1052
|
const subscriber = this.adapter.createSubscriberSocket(this.context);
|
|
983
|
-
subscriber.setChannelName(channelName);
|
|
984
|
-
setFanoutSubscriptions(subscriber, channel.subscriptions);
|
|
985
|
-
const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
|
|
986
1053
|
const connection: FanoutPublisherConnection = {
|
|
987
1054
|
channelName,
|
|
988
1055
|
endpoint,
|
|
989
1056
|
subscriber,
|
|
990
|
-
monitor,
|
|
991
1057
|
callbacks,
|
|
992
1058
|
physicalConnectionId: Symbol(connectionId),
|
|
993
1059
|
transportReady: false,
|
|
994
1060
|
ready: false
|
|
995
1061
|
};
|
|
996
|
-
this.
|
|
997
|
-
|
|
998
|
-
|
|
1062
|
+
this.ownedResources.add(subscriber);
|
|
1063
|
+
const created: (
|
|
1064
|
+
| ZLinkBackendSocketMonitor
|
|
1065
|
+
| ZLinkBackendReadablePoller
|
|
1066
|
+
| ZLinkBackendDealerSocket
|
|
1067
|
+
| ZLinkBackendSubscriberSocket
|
|
1068
|
+
)[] = [subscriber];
|
|
999
1069
|
try {
|
|
1070
|
+
this.fanoutConnections.set(connectionId, connection);
|
|
1071
|
+
subscriber.setChannelName(channelName);
|
|
1072
|
+
setFanoutSubscriptions(subscriber, channel.subscriptions);
|
|
1073
|
+
const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
|
|
1074
|
+
connection.monitor = monitor;
|
|
1075
|
+
created.push(monitor);
|
|
1076
|
+
this.ownedResources.add(monitor);
|
|
1077
|
+
this.ensureClientServerLivenessTimer();
|
|
1000
1078
|
monitor.onEvent((event) => {
|
|
1001
1079
|
if (this.fanoutConnections.get(connectionId) !== connection) return;
|
|
1002
1080
|
for (const handler of this.fanoutMonitorHandlers.get(channelName) ?? []) {
|
|
@@ -1020,28 +1098,36 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1020
1098
|
}
|
|
1021
1099
|
});
|
|
1022
1100
|
subscriber.connect(endpoint);
|
|
1101
|
+
return subscriber;
|
|
1023
1102
|
} catch (error) {
|
|
1024
1103
|
this.fanoutConnections.delete(connectionId);
|
|
1025
|
-
|
|
1026
|
-
|
|
1104
|
+
void Promise.allSettled(
|
|
1105
|
+
created.map(async (resource) => {
|
|
1106
|
+
await resource.dispose();
|
|
1107
|
+
this.ownedResources.delete(resource);
|
|
1108
|
+
})
|
|
1109
|
+
).then((results) => {
|
|
1110
|
+
for (const result of results)
|
|
1111
|
+
if (result.status === 'rejected') this.oneWayFailureSink?.(result.reason);
|
|
1112
|
+
});
|
|
1027
1113
|
throw error;
|
|
1028
1114
|
}
|
|
1029
|
-
return subscriber;
|
|
1030
1115
|
}
|
|
1031
1116
|
|
|
1032
1117
|
async closeFanoutSubscriberConnection(connectionId: string): Promise<void> {
|
|
1033
1118
|
const connection = this.fanoutConnections.get(connectionId);
|
|
1034
1119
|
if (connection === undefined) return;
|
|
1035
|
-
this.fanoutConnections.delete(connectionId);
|
|
1036
1120
|
try {
|
|
1037
1121
|
connection.subscriber.disconnect(connection.endpoint);
|
|
1038
1122
|
} catch {
|
|
1039
|
-
//
|
|
1123
|
+
// The socket close below releases an endpoint that is already disconnected.
|
|
1040
1124
|
}
|
|
1041
|
-
this.ownedMonitors.delete(connection.monitor);
|
|
1042
1125
|
const results = await Promise.allSettled([
|
|
1043
|
-
connection.monitor
|
|
1044
|
-
|
|
1126
|
+
connection.monitor?.dispose(),
|
|
1127
|
+
(async () => {
|
|
1128
|
+
await connection.subscriber.dispose();
|
|
1129
|
+
this.ownedResources.delete(connection.subscriber);
|
|
1130
|
+
})()
|
|
1045
1131
|
]);
|
|
1046
1132
|
const errors = results
|
|
1047
1133
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
@@ -1050,6 +1136,8 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1050
1136
|
if (errors.length > 1) {
|
|
1051
1137
|
throw new AggregateError(errors, `Fanout connection '${connectionId}' cleanup failed.`);
|
|
1052
1138
|
}
|
|
1139
|
+
this.fanoutConnections.delete(connectionId);
|
|
1140
|
+
if (connection.monitor !== undefined) this.ownedResources.delete(connection.monitor);
|
|
1053
1141
|
}
|
|
1054
1142
|
|
|
1055
1143
|
handleFanoutInbound(
|
|
@@ -1170,7 +1258,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1170
1258
|
};
|
|
1171
1259
|
}
|
|
1172
1260
|
|
|
1173
|
-
|
|
1261
|
+
notifyFanoutTopology(channelName: string): void {
|
|
1174
1262
|
for (const handler of this.fanoutTopologyHandlers.get(channelName) ?? []) {
|
|
1175
1263
|
try {
|
|
1176
1264
|
handler();
|
|
@@ -1298,9 +1386,8 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1298
1386
|
connectionId: string,
|
|
1299
1387
|
connection: ClientServerPhysicalConnection
|
|
1300
1388
|
): void {
|
|
1301
|
-
if (connection.terminationRequested) return;
|
|
1302
1389
|
for (;;) {
|
|
1303
|
-
if (!connection.readablePoller.wait(0)) return;
|
|
1390
|
+
if (connection.readablePoller === undefined || !connection.readablePoller.wait(0)) return;
|
|
1304
1391
|
const received = connection.dealer.recv(1);
|
|
1305
1392
|
if (received === undefined) {
|
|
1306
1393
|
connection.readablePoller.markDrained();
|
|
@@ -1331,7 +1418,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1331
1418
|
}
|
|
1332
1419
|
this.applyClientServerDescriptorUpdate(connectionId, connection, record.admission);
|
|
1333
1420
|
} catch (error) {
|
|
1334
|
-
this.
|
|
1421
|
+
this.restartClientServerAdmission(connectionId, connection);
|
|
1335
1422
|
this.oneWayFailureSink?.(error);
|
|
1336
1423
|
return;
|
|
1337
1424
|
} finally {
|
|
@@ -1340,19 +1427,39 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1340
1427
|
}
|
|
1341
1428
|
}
|
|
1342
1429
|
|
|
1343
|
-
|
|
1430
|
+
/**
|
|
1431
|
+
* Ends the current logical admission of this connection: later replies of
|
|
1432
|
+
* the fenced attempt no longer apply and its ready target is withdrawn.
|
|
1433
|
+
*/
|
|
1434
|
+
private endClientServerAdmission(
|
|
1344
1435
|
connectionId: string,
|
|
1345
|
-
connection: ClientServerPhysicalConnection
|
|
1436
|
+
connection: ClientServerPhysicalConnection,
|
|
1437
|
+
routingId: string | undefined,
|
|
1438
|
+
endpoint: string
|
|
1346
1439
|
): void {
|
|
1347
|
-
if (connection.terminationRequested) return;
|
|
1348
|
-
connection.terminationRequested = true;
|
|
1349
1440
|
connection.physicalConnectionId = Symbol(connectionId);
|
|
1350
1441
|
connection.admissionAttempt = undefined;
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1442
|
+
if (connection.readyConnectionId !== undefined) {
|
|
1443
|
+
this.removeReadyConnection(connection.readyConnectionId);
|
|
1444
|
+
}
|
|
1445
|
+
for (const callbacks of [...connection.callbacksByAlias.values()]) {
|
|
1446
|
+
callbacks.onTerminated(routingId, endpoint);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
/**
|
|
1451
|
+
* A peer deadline or an invalid pushed control ends only the current logical
|
|
1452
|
+
* admission. The connect intent stays with Core, which owns the endpoint
|
|
1453
|
+
* reconnect (transport liveness §6); the service handshake starts again on
|
|
1454
|
+
* the existing admission path.
|
|
1455
|
+
*/
|
|
1456
|
+
private restartClientServerAdmission(
|
|
1457
|
+
connectionId: string,
|
|
1458
|
+
connection: ClientServerPhysicalConnection
|
|
1459
|
+
): void {
|
|
1460
|
+
this.endClientServerAdmission(connectionId, connection, undefined, connection.endpoint);
|
|
1461
|
+
for (const callbacks of [...connection.callbacksByAlias.values()]) {
|
|
1462
|
+
callbacks.onTransportReady('', connection.endpoint);
|
|
1356
1463
|
}
|
|
1357
1464
|
}
|
|
1358
1465
|
|
|
@@ -1412,12 +1519,15 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1412
1519
|
|
|
1413
1520
|
private ensureClientServerLivenessTimer(): void {
|
|
1414
1521
|
if (this.clientServerLivenessTimer !== undefined) return;
|
|
1415
|
-
this.clientServerLivenessTimer = setInterval(
|
|
1522
|
+
this.clientServerLivenessTimer = setInterval(
|
|
1523
|
+
() => this.tickClientServerLiveness(),
|
|
1524
|
+
CLIENT_SERVER_LIVENESS_TICK_MS
|
|
1525
|
+
);
|
|
1416
1526
|
this.clientServerLivenessTimer.unref();
|
|
1417
1527
|
}
|
|
1418
1528
|
|
|
1419
1529
|
private drainSocketMonitors(): void {
|
|
1420
|
-
for (const monitor of this.
|
|
1530
|
+
for (const monitor of this.ownedResources) if ('drain' in monitor) monitor.drain();
|
|
1421
1531
|
}
|
|
1422
1532
|
|
|
1423
1533
|
private removeReadyConnection(connectionId: string): void {
|
|
@@ -1438,6 +1548,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1438
1548
|
connection.nextProbeAt = undefined;
|
|
1439
1549
|
connection.outstandingProbeId = undefined;
|
|
1440
1550
|
}
|
|
1551
|
+
this.notifyClientServerTopology(identity.channelName);
|
|
1441
1552
|
}
|
|
1442
1553
|
|
|
1443
1554
|
private requestClientServerLiveness(
|
|
@@ -1585,7 +1696,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1585
1696
|
|
|
1586
1697
|
private allocateClientServerProbeId(): bigint {
|
|
1587
1698
|
const result = this.nextClientServerProbeId;
|
|
1588
|
-
this.nextClientServerProbeId = result ===
|
|
1699
|
+
this.nextClientServerProbeId = result === UINT64_MAX ? 1n : result + 1n;
|
|
1589
1700
|
return result;
|
|
1590
1701
|
}
|
|
1591
1702
|
|
|
@@ -1608,10 +1719,17 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1608
1719
|
}
|
|
1609
1720
|
|
|
1610
1721
|
const publisher = this.adapter.createPublisherSocket(this.context);
|
|
1722
|
+
this.publishers.set(channelName, publisher);
|
|
1611
1723
|
publisher.setChannelName(channelName);
|
|
1612
1724
|
applyFanoutPublisherSocketOptions(publisher, channel);
|
|
1613
1725
|
publisher.bind(channel.publisher.bind);
|
|
1614
|
-
|
|
1726
|
+
const endpoint = buildAdvertisedEndpoint(
|
|
1727
|
+
publisher.lastEndpoint ?? channel.publisher.bind,
|
|
1728
|
+
channel.publisher.advertiseHost
|
|
1729
|
+
);
|
|
1730
|
+
if (endpoint !== undefined && endpoint.length > 0) {
|
|
1731
|
+
this.recordListener('fanout', channelName, endpoint);
|
|
1732
|
+
}
|
|
1615
1733
|
this.fanoutPublisherNextBeacon.set(
|
|
1616
1734
|
channelName,
|
|
1617
1735
|
performance.now() + CLIENT_SERVER_PROBE_INTERVAL_MS
|
|
@@ -1620,20 +1738,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1620
1738
|
return publisher;
|
|
1621
1739
|
}
|
|
1622
1740
|
|
|
1623
|
-
fanoutPublisherEndpoint(channelName: string): string | undefined {
|
|
1624
|
-
const channel = this.registration.channels.get(channelName);
|
|
1625
|
-
const publisher = this.publishers.get(channelName);
|
|
1626
|
-
const boundEndpoint = publisher?.lastEndpoint;
|
|
1627
|
-
if (
|
|
1628
|
-
channel?.publisher === undefined ||
|
|
1629
|
-
boundEndpoint === undefined ||
|
|
1630
|
-
boundEndpoint.length === 0
|
|
1631
|
-
) {
|
|
1632
|
-
return undefined;
|
|
1633
|
-
}
|
|
1634
|
-
return advertisedEndpoint(boundEndpoint, channel.publisher.advertiseHost);
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
1741
|
routeRouter(routerChannelId: string): ZLinkBackendRouterSocket {
|
|
1638
1742
|
const existing = this.routeRouters.get(routerChannelId);
|
|
1639
1743
|
if (existing !== undefined) {
|
|
@@ -1647,6 +1751,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1647
1751
|
);
|
|
1648
1752
|
}
|
|
1649
1753
|
const router = this.adapter.createRouterSocket(this.context);
|
|
1754
|
+
this.routeRouters.set(routerChannelId, router);
|
|
1650
1755
|
this.registerReceiveFlowSocket(router);
|
|
1651
1756
|
router.setChannelName(routerChannelId);
|
|
1652
1757
|
if (
|
|
@@ -1658,7 +1763,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1658
1763
|
router.setRoutingId(
|
|
1659
1764
|
routeChannel.routingId ?? `${routeChannel.routingIdPrefix ?? routerChannelId}-${randomUUID()}`
|
|
1660
1765
|
);
|
|
1661
|
-
const publicWeight = routeChannel.weight ??
|
|
1766
|
+
const publicWeight = routeChannel.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
1662
1767
|
this.routeMeshPublicWeights.set(routerChannelId, publicWeight);
|
|
1663
1768
|
router.peerWeight = rawAvailabilityWeight(publicWeight);
|
|
1664
1769
|
applySocketConfig(router, routeChannel);
|
|
@@ -1672,7 +1777,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1672
1777
|
if (routeChannel.bind !== undefined && routeChannel.bind.trim().length > 0) {
|
|
1673
1778
|
router.bind(routeChannel.bind);
|
|
1674
1779
|
}
|
|
1675
|
-
this.routeRouters.set(routerChannelId, router);
|
|
1676
1780
|
return router;
|
|
1677
1781
|
}
|
|
1678
1782
|
|
|
@@ -1682,7 +1786,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1682
1786
|
|
|
1683
1787
|
routeMeshWeight(routerChannelId: string): number {
|
|
1684
1788
|
this.routeRouter(routerChannelId);
|
|
1685
|
-
return this.routeMeshPublicWeights.get(routerChannelId) ??
|
|
1789
|
+
return this.routeMeshPublicWeights.get(routerChannelId) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
1686
1790
|
}
|
|
1687
1791
|
|
|
1688
1792
|
setRouteMeshWeight(routerChannelId: string, weight: number): void {
|
|
@@ -1719,7 +1823,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1719
1823
|
return;
|
|
1720
1824
|
}
|
|
1721
1825
|
const monitor = this.monitoringAdapter.openSocketMonitor(socket);
|
|
1722
|
-
this.
|
|
1826
|
+
this.ownedResources.add(monitor);
|
|
1723
1827
|
monitor.onEvent((event) => {
|
|
1724
1828
|
if (
|
|
1725
1829
|
event.nativeEvent === ZLinkSocketNativeEventType.Disconnected &&
|
|
@@ -1735,7 +1839,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1735
1839
|
return;
|
|
1736
1840
|
}
|
|
1737
1841
|
const monitor = this.monitoringAdapter.openSocketMonitor(router);
|
|
1738
|
-
this.
|
|
1842
|
+
this.ownedResources.add(monitor);
|
|
1739
1843
|
monitor.onEvent((event) => {
|
|
1740
1844
|
const routingId = event.routingId === undefined ? undefined : String(event.routingId);
|
|
1741
1845
|
if (
|
|
@@ -1777,7 +1881,7 @@ async function requestClientServerAdmission(
|
|
|
1777
1881
|
encodeClientServerHello({
|
|
1778
1882
|
channelName,
|
|
1779
1883
|
securityIdentity,
|
|
1780
|
-
normalizedEffectiveMaxMessageBytes:
|
|
1884
|
+
normalizedEffectiveMaxMessageBytes: normalizeClientServerMessageLimit(dealer.maxMessageSize)
|
|
1781
1885
|
})
|
|
1782
1886
|
);
|
|
1783
1887
|
try {
|
|
@@ -1855,9 +1959,9 @@ function setFanoutSubscriptions(
|
|
|
1855
1959
|
|
|
1856
1960
|
function deriveRoutingId(baseRoutingId: string, suffix: string): string {
|
|
1857
1961
|
const derived = `${baseRoutingId}\0${suffix}`;
|
|
1858
|
-
if (Buffer.byteLength(derived, 'utf8') >
|
|
1962
|
+
if (Buffer.byteLength(derived, 'utf8') > ZLINK_MAX_ROUTING_ID_BYTES) {
|
|
1859
1963
|
throw new ZLinkConfigurationException(
|
|
1860
|
-
`Derived routing id with suffix '${suffix}' exceeds the
|
|
1964
|
+
`Derived routing id with suffix '${suffix}' exceeds the ${ZLINK_MAX_ROUTING_ID_BYTES} byte limit.`
|
|
1861
1965
|
);
|
|
1862
1966
|
}
|
|
1863
1967
|
return derived;
|
|
@@ -1868,6 +1972,7 @@ function applyFanoutPublisherSocketOptions(
|
|
|
1868
1972
|
channel: ZLinkChannelOptions
|
|
1869
1973
|
): void {
|
|
1870
1974
|
publisher.noDrop = channel.noDrop ?? false;
|
|
1975
|
+
publisher.sendTimeoutMs = configuredSendTimeoutMs(channel.publisher?.sendTimeoutMs);
|
|
1871
1976
|
}
|
|
1872
1977
|
|
|
1873
1978
|
function fanoutDiscoveryConnectionId(connectionId: string): string {
|
|
@@ -1891,13 +1996,11 @@ function advertisedEndpoint(boundEndpoint: string, advertiseHost: string | undef
|
|
|
1891
1996
|
return result;
|
|
1892
1997
|
}
|
|
1893
1998
|
|
|
1894
|
-
function normalizedMessageLimit(value: number): number {
|
|
1895
|
-
return Number.isSafeInteger(value) && value > 0 ? Math.min(value, 0xffff_ffff) : 0x7fff_ffff;
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
1999
|
function requirePublicWeight(weight: number): void {
|
|
1899
|
-
if (!
|
|
1900
|
-
throw new ZLinkConfigurationException(
|
|
2000
|
+
if (!isValidPublicWeight(weight)) {
|
|
2001
|
+
throw new ZLinkConfigurationException(
|
|
2002
|
+
`Weight must be an integer in 0..${ZLINK_MAX_PUBLIC_WEIGHT}.`
|
|
2003
|
+
);
|
|
1901
2004
|
}
|
|
1902
2005
|
}
|
|
1903
2006
|
|
|
@@ -1933,3 +2036,7 @@ function applySocketConfig(
|
|
|
1933
2036
|
socket.maxMessageSize = config.maxMessageSize;
|
|
1934
2037
|
}
|
|
1935
2038
|
}
|
|
2039
|
+
|
|
2040
|
+
function configuredSendTimeoutMs(value: number | undefined): number {
|
|
2041
|
+
return value ?? DEFAULT_SEND_TIMEOUT_MS;
|
|
2042
|
+
}
|