@zlink-systems/framework 0.26.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/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/Spots/Contracts.d.ts +1 -1
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +15 -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 +1 -2
- package/dist/runtime/activation-admission.js +2 -6
- 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 +13 -11
- package/dist/runtime/actors/actor-handoff.d.ts +4 -4
- package/dist/runtime/actors/actor-handoff.js +8 -8
- 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 +83 -105
- 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 +1 -1
- package/dist/runtime/actors/actor-remote-joiner.js +5 -9
- 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-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
- package/dist/runtime/actors/deferred-join-completion.js +1 -0
- package/dist/runtime/actors/index.d.ts +9 -7
- package/dist/runtime/actors/index.js +87 -69
- 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 +2 -0
- package/dist/runtime/admission.js +7 -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 +6 -23
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
- 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-support.d.ts +1 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -6
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.js +40 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +3 -2
- package/dist/runtime/backend/raw-binding-port.d.ts +1 -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 -8
- package/dist/runtime/channels/channel-clients.js +68 -52
- 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 -10
- 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.js +5 -2
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
- package/dist/runtime/channels/channel-socket-registry.js +248 -174
- package/dist/runtime/channels/channel-transports.d.ts +11 -17
- 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 +130 -72
- 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 +12 -9
- package/dist/runtime/execution/index.js +58 -14
- package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
- package/dist/runtime/execution/serial-execution-queue.js +54 -15
- 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/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 +8 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +62 -83
- 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.js +22 -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 +0 -6
- 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-object-owner.js +3 -2
- 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 -12
- 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 +26 -25
- package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
- package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
- package/dist/runtime/foundation/service-topology-registry.js +17 -32
- 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 +16 -18
- package/dist/runtime/host/actor-transfer-runtime.js +143 -176
- 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 +14 -13
- package/dist/runtime/host/index.js +190 -157
- 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 +7 -20
- package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
- package/dist/runtime/host/route-mesh-runtime.js +171 -252
- 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 +21 -30
- package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
- 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 -10
- package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
- 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 +72 -22
- 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 +4 -9
- package/dist/runtime/locations/lifecycle.js +2 -31
- 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 +37 -28
- 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 +6 -0
- package/dist/runtime/locations/spot-location-claims.js +42 -1
- 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 +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
- package/dist/runtime/spots/index.d.ts +14 -20
- package/dist/runtime/spots/index.js +302 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
- package/dist/runtime/spots/spot-activation-registry.js +14 -50
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +2 -2
- package/dist/runtime/spots/spot-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-activation.js +49 -32
- 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 +4 -52
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
- package/dist/runtime/spots/spot-actor-membership.js +22 -45
- 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 +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +9 -20
- 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 +5 -4
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
- package/dist/runtime/spots/spot-outbound.d.ts +4 -3
- package/dist/runtime/spots/spot-outbound.js +9 -8
- 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 -3
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
- 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 +2 -16
- package/dist/runtime/spots/spot-serial-executor.js +2 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
- package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
- 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 +11 -1
- package/dist/runtime/streams/index.d.ts +14 -15
- package/dist/runtime/streams/index.js +20 -21
- 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/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/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/Spots/Contracts.ts +1 -1
- package/src/internal.ts +14 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +2 -8
- 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 +39 -33
- package/src/runtime/actors/actor-handoff.ts +24 -22
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +172 -174
- 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 +9 -11
- 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-state.ts +85 -247
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +10 -6
- package/src/runtime/actors/index.ts +100 -79
- 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 +8 -1
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +13 -29
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-support.ts +23 -6
- package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +41 -20
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +3 -2
- package/src/runtime/backend/raw-binding-port.ts +1 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +132 -85
- 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 -23
- 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 +6 -2
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +301 -192
- package/src/runtime/channels/channel-transports.ts +161 -112
- 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 +172 -91
- 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 +60 -20
- package/src/runtime/execution/serial-execution-queue.ts +131 -18
- 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/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +110 -111
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +31 -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 +0 -10
- 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-object-owner.ts +5 -2
- 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 -17
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
- package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
- package/src/runtime/foundation/service-topology-registry.ts +23 -32
- 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 +180 -260
- 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 +327 -296
- 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 +8 -41
- package/src/runtime/host/route-mesh-runtime.ts +228 -271
- 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 +699 -561
- 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 +73 -22
- package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
- 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 +100 -25
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +13 -43
- 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 +75 -49
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +58 -1
- 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 +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
- package/src/runtime/spots/index.ts +433 -229
- package/src/runtime/spots/spot-activation-registry.ts +30 -69
- package/src/runtime/spots/spot-activation-state.ts +2 -2
- package/src/runtime/spots/spot-activation.ts +67 -37
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
- package/src/runtime/spots/spot-actor-membership.ts +40 -72
- 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 -30
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +21 -17
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
- package/src/runtime/spots/spot-outbound.ts +45 -23
- 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 -26
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +5 -27
- package/src/runtime/spots/spot-serial-executor.ts +2 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
- package/src/runtime/streams/bound-session-service.ts +21 -1
- package/src/runtime/streams/index.ts +76 -64
- 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/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/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/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -1,43 +1,58 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RuntimeDisposal } from '../disposal';
|
|
2
|
+
import { UINT64_MAX } from '@zlink-systems/stream-wire';
|
|
3
|
+
import { randomBytes, randomUUID } from 'node:crypto';
|
|
2
4
|
import {
|
|
3
5
|
ZLinkFrameworkRuntimeState,
|
|
4
6
|
type RoutingId,
|
|
5
7
|
type ZLinkClientServerServerDescriptor,
|
|
6
8
|
type ZLinkFanoutPublisherDescriptor
|
|
7
9
|
} from '../../contracts';
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
+
import { ZLINK_MAX_ROUTING_ID_BYTES } from '../../contracts/Common/CoreTypes';
|
|
11
|
+
import type { Message } from '../../contracts/Common/Message';
|
|
10
12
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} 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';
|
|
15
20
|
import type {
|
|
16
21
|
ZLinkBackendContext,
|
|
17
22
|
ZLinkBackendDealerSocket,
|
|
18
23
|
ZLinkBackendPublisherSocket,
|
|
19
|
-
ZLinkBackendRouterSocket,
|
|
20
24
|
ZLinkBackendReadablePoller,
|
|
25
|
+
ZLinkBackendRouterSocket,
|
|
21
26
|
ZLinkBackendSocketMonitor,
|
|
22
27
|
ZLinkBackendSocketMonitorEvent,
|
|
23
28
|
ZLinkBackendSubscriberSocket,
|
|
24
29
|
ZLinkChannelBackendAdapter,
|
|
25
30
|
ZLinkMonitoringBackendAdapter
|
|
26
31
|
} from '../backend/contracts';
|
|
27
|
-
import { throwIfAborted } from '../abort';
|
|
28
|
-
import { attachEndpointConnections } from '../../contracts/Configuration/RuntimeEndpointConnections';
|
|
29
|
-
import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
|
|
30
|
-
import {
|
|
31
|
-
ZLinkFrameworkInternalErrorKind,
|
|
32
|
-
createInternalFrameworkException
|
|
33
|
-
} from '../framework-errors-internal';
|
|
34
|
-
import { randomBytes, randomUUID } from 'node:crypto';
|
|
35
32
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
36
|
-
import
|
|
37
|
-
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';
|
|
38
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';
|
|
39
47
|
import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
|
|
40
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,
|
|
41
56
|
decodeClientServerControl,
|
|
42
57
|
encodeClientServerAdmit,
|
|
43
58
|
encodeClientServerHello,
|
|
@@ -46,6 +61,7 @@ import {
|
|
|
46
61
|
encodeClientServerReject,
|
|
47
62
|
encodeClientServerUpdate,
|
|
48
63
|
isClientServerControlFrame,
|
|
64
|
+
normalizeClientServerMessageLimit,
|
|
49
65
|
type ZLinkClientServerAdmission
|
|
50
66
|
} from './client-server-service-wire';
|
|
51
67
|
import {
|
|
@@ -53,16 +69,13 @@ import {
|
|
|
53
69
|
FANOUT_LIVENESS_TOPIC,
|
|
54
70
|
inspectFanoutInbound
|
|
55
71
|
} from './fanout-service-wire';
|
|
56
|
-
import
|
|
57
|
-
import type { ApplicationJobQueue } from '../host/application-job-queue';
|
|
58
|
-
import { isBackendRequestTimeoutError } from '../backend/runtime-values';
|
|
72
|
+
import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
|
|
59
73
|
|
|
60
74
|
const MAX_LIFECYCLE_GENERATION = 0x7fff_ffff_ffff_ffffn;
|
|
61
|
-
const CLIENT_SERVER_PROBE_INTERVAL_MS =
|
|
62
|
-
const CLIENT_SERVER_PEER_DEADLINE_MS =
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
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;
|
|
66
79
|
|
|
67
80
|
export interface ZLinkClientServerServerSocketIdentity {
|
|
68
81
|
readonly serverRid: string;
|
|
@@ -81,8 +94,8 @@ interface ClientServerPhysicalConnection {
|
|
|
81
94
|
readonly channelName: string;
|
|
82
95
|
readonly endpoint: string;
|
|
83
96
|
readonly dealer: ZLinkBackendDealerSocket;
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
readablePoller?: ZLinkBackendReadablePoller;
|
|
98
|
+
monitor?: ZLinkBackendSocketMonitor;
|
|
86
99
|
readonly aliases: Set<string>;
|
|
87
100
|
readonly callbacksByAlias: Map<string, ZLinkClientServerConnectionCallbacks>;
|
|
88
101
|
physicalConnectionId: symbol;
|
|
@@ -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,
|
|
@@ -184,10 +203,20 @@ export class ZLinkChannelSocketRegistry {
|
|
|
184
203
|
this.listenerRecords = listenerRecords ?? new ZLinkListenerRecords();
|
|
185
204
|
}
|
|
186
205
|
|
|
187
|
-
|
|
206
|
+
dispose(): Promise<void> {
|
|
207
|
+
return this.disposal.run(() => this.disposeCore());
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private async disposeCore(): Promise<void> {
|
|
211
|
+
this.clientServerDiscovery.dispose(
|
|
212
|
+
createInternalFrameworkException(
|
|
213
|
+
ZLinkFrameworkInternalErrorKind.RuntimeShutdown,
|
|
214
|
+
'Channel sockets are shutting down.'
|
|
215
|
+
)
|
|
216
|
+
);
|
|
188
217
|
const clientServerConnections = [...new Set(this.clientServerConnections.values())];
|
|
189
|
-
const clientServerPollers = clientServerConnections.
|
|
190
|
-
|
|
218
|
+
const clientServerPollers = clientServerConnections.flatMap((connection) =>
|
|
219
|
+
connection.readablePoller === undefined ? [] : [connection.readablePoller]
|
|
191
220
|
);
|
|
192
221
|
const sockets = [
|
|
193
222
|
...this.clientDealers.values(),
|
|
@@ -204,8 +233,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
204
233
|
...this.routeRouters.values()
|
|
205
234
|
]))
|
|
206
235
|
this.unregisterReceiveFlowSocket(socket);
|
|
207
|
-
this.clientDealers.clear();
|
|
208
|
-
this.clientServerConnections.clear();
|
|
209
236
|
this.clientServerReadyIdentities.clear();
|
|
210
237
|
this.clientServerServerDescriptors.clear();
|
|
211
238
|
this.clientServerPublicWeights.clear();
|
|
@@ -215,23 +242,37 @@ export class ZLinkChannelSocketRegistry {
|
|
|
215
242
|
this.clientServerMonitorHandlers.clear();
|
|
216
243
|
this.fanoutMonitorHandlers.clear();
|
|
217
244
|
this.fanoutTopologyHandlers.clear();
|
|
218
|
-
this.fanoutConnections.clear();
|
|
219
245
|
this.fanoutPublisherNextBeacon.clear();
|
|
220
246
|
if (this.clientServerLivenessTimer !== undefined) {
|
|
221
247
|
clearInterval(this.clientServerLivenessTimer);
|
|
222
248
|
this.clientServerLivenessTimer = undefined;
|
|
223
249
|
}
|
|
224
|
-
this.channelRouters.clear();
|
|
225
|
-
this.publishers.clear();
|
|
226
|
-
this.routeRouters.clear();
|
|
227
250
|
this.routeMembers.clear();
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
+
);
|
|
235
276
|
const errors = cleanup
|
|
236
277
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
237
278
|
.map((result) => result.reason);
|
|
@@ -252,13 +293,16 @@ export class ZLinkChannelSocketRegistry {
|
|
|
252
293
|
}
|
|
253
294
|
|
|
254
295
|
const dealer = this.adapter.createDealerSocket(this.context);
|
|
296
|
+
this.clientDealers.set(channelName, dealer);
|
|
255
297
|
this.registerReceiveFlowSocket(dealer);
|
|
256
298
|
dealer.setChannelName(channelName);
|
|
257
299
|
if (channel?.routingId !== undefined && channel.routingId.length > 0) {
|
|
258
300
|
dealer.setRoutingId(deriveRoutingId(channel.routingId, 'dealer'));
|
|
259
301
|
}
|
|
260
|
-
applySocketConfig(dealer,
|
|
261
|
-
|
|
302
|
+
applySocketConfig(dealer, {
|
|
303
|
+
...client,
|
|
304
|
+
sendTimeoutMs: configuredSendTimeoutMs(client.sendTimeoutMs)
|
|
305
|
+
});
|
|
262
306
|
return dealer;
|
|
263
307
|
}
|
|
264
308
|
|
|
@@ -279,6 +323,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
279
323
|
}
|
|
280
324
|
|
|
281
325
|
const router = this.adapter.createRouterSocket(this.context);
|
|
326
|
+
this.channelRouters.set(channelName, router);
|
|
282
327
|
this.registerReceiveFlowSocket(router);
|
|
283
328
|
router.setChannelName(channelName);
|
|
284
329
|
const identity = this.clientServerIdentities.get(channelName) ?? {
|
|
@@ -287,14 +332,14 @@ export class ZLinkChannelSocketRegistry {
|
|
|
287
332
|
};
|
|
288
333
|
this.clientServerIdentities.set(channelName, identity);
|
|
289
334
|
router.setRoutingId(identity.serverRid);
|
|
290
|
-
const publicWeight = channel.server.weight ??
|
|
335
|
+
const publicWeight = channel.server.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
291
336
|
this.clientServerPublicWeights.set(channelName, publicWeight);
|
|
292
337
|
router.peerWeight = rawAvailabilityWeight(publicWeight);
|
|
293
338
|
applySocketConfig(router, channel.server);
|
|
294
339
|
router.bind(channel.server.bind);
|
|
295
340
|
if (this.monitoringAdapter !== undefined) {
|
|
296
341
|
const monitor = this.monitoringAdapter.openSocketMonitor(router);
|
|
297
|
-
this.
|
|
342
|
+
this.ownedResources.add(monitor);
|
|
298
343
|
monitor.onEvent((event) => {
|
|
299
344
|
if (event.routingId === undefined) return;
|
|
300
345
|
if (
|
|
@@ -310,7 +355,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
310
355
|
this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
|
|
311
356
|
});
|
|
312
357
|
}
|
|
313
|
-
this.channelRouters.set(channelName, router);
|
|
314
358
|
const endpoint = advertisedEndpoint(
|
|
315
359
|
router.lastEndpoint ?? channel.server.bind,
|
|
316
360
|
channel.server.advertiseHost
|
|
@@ -358,7 +402,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
358
402
|
|
|
359
403
|
clientServerServerWeight(channelName: string): number {
|
|
360
404
|
this.channelRouter(channelName);
|
|
361
|
-
return this.clientServerPublicWeights.get(channelName) ??
|
|
405
|
+
return this.clientServerPublicWeights.get(channelName) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
362
406
|
}
|
|
363
407
|
|
|
364
408
|
setClientServerServerWeight(channelName: string, weight: number): void {
|
|
@@ -390,46 +434,38 @@ export class ZLinkChannelSocketRegistry {
|
|
|
390
434
|
throw new ZLinkConfigurationException(`Channel client '${channelName}' is not registered.`);
|
|
391
435
|
}
|
|
392
436
|
const dealer = this.adapter.createDealerSocket(this.context);
|
|
393
|
-
this.registerReceiveFlowSocket(dealer);
|
|
394
|
-
dealer.setChannelName(channelName);
|
|
395
|
-
dealer.setRoutingId(`cs-client-${randomUUID()}`);
|
|
396
|
-
applySocketConfig(dealer, client);
|
|
397
|
-
const cleanupDealer = (): void => {
|
|
398
|
-
this.unregisterReceiveFlowSocket(dealer);
|
|
399
|
-
void Promise.allSettled([dealer.dispose()]);
|
|
400
|
-
};
|
|
401
|
-
let readablePoller: ZLinkBackendReadablePoller;
|
|
402
|
-
try {
|
|
403
|
-
readablePoller = this.adapter.createReadablePoller(dealer);
|
|
404
|
-
} catch (error) {
|
|
405
|
-
cleanupDealer();
|
|
406
|
-
throw error;
|
|
407
|
-
}
|
|
408
|
-
let monitor: ZLinkBackendSocketMonitor;
|
|
409
|
-
try {
|
|
410
|
-
monitor = this.monitoringAdapter.openSocketMonitor(dealer);
|
|
411
|
-
} catch (error) {
|
|
412
|
-
try {
|
|
413
|
-
readablePoller.dispose();
|
|
414
|
-
} finally {
|
|
415
|
-
cleanupDealer();
|
|
416
|
-
}
|
|
417
|
-
throw error;
|
|
418
|
-
}
|
|
419
|
-
this.ownedMonitors.add(monitor);
|
|
420
437
|
const connection: ClientServerPhysicalConnection = {
|
|
421
438
|
channelName,
|
|
422
439
|
endpoint,
|
|
423
440
|
dealer,
|
|
424
|
-
readablePoller,
|
|
425
|
-
monitor,
|
|
426
441
|
aliases: new Set([connectionId]),
|
|
427
442
|
callbacksByAlias: new Map([[connectionId, callbacks]]),
|
|
428
443
|
physicalConnectionId: Symbol(connectionId)
|
|
429
444
|
};
|
|
430
|
-
this.
|
|
431
|
-
|
|
445
|
+
this.ownedResources.add(dealer);
|
|
446
|
+
const created: (
|
|
447
|
+
| ZLinkBackendSocketMonitor
|
|
448
|
+
| ZLinkBackendReadablePoller
|
|
449
|
+
| ZLinkBackendDealerSocket
|
|
450
|
+
| ZLinkBackendSubscriberSocket
|
|
451
|
+
)[] = [dealer];
|
|
432
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();
|
|
433
469
|
monitor.onEvent((event) => {
|
|
434
470
|
if (
|
|
435
471
|
![...connection.aliases].some(
|
|
@@ -464,24 +500,26 @@ export class ZLinkChannelSocketRegistry {
|
|
|
464
500
|
}
|
|
465
501
|
});
|
|
466
502
|
dealer.connect(endpoint);
|
|
503
|
+
return dealer;
|
|
467
504
|
} catch (error) {
|
|
468
505
|
this.clientServerConnections.delete(connectionId);
|
|
469
|
-
this.
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
+
});
|
|
476
516
|
throw error;
|
|
477
517
|
}
|
|
478
|
-
return dealer;
|
|
479
518
|
}
|
|
480
519
|
|
|
481
520
|
async closeClientServerConnection(connectionId: string): Promise<void> {
|
|
482
521
|
const current = this.clientServerConnections.get(connectionId);
|
|
483
522
|
if (current === undefined) return;
|
|
484
|
-
this.clientServerConnections.delete(connectionId);
|
|
485
523
|
current.aliases.delete(connectionId);
|
|
486
524
|
current.callbacksByAlias.delete(connectionId);
|
|
487
525
|
const ready = this.clientServerReadyIdentities.get(connectionId);
|
|
@@ -507,8 +545,13 @@ export class ZLinkChannelSocketRegistry {
|
|
|
507
545
|
});
|
|
508
546
|
}
|
|
509
547
|
}
|
|
510
|
-
|
|
548
|
+
this.notifyClientServerTopology(current.channelName);
|
|
549
|
+
if (current.aliases.size > 0) {
|
|
550
|
+
this.clientServerConnections.delete(connectionId);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
511
553
|
await this.disposeClientServerPhysical(connectionId, current);
|
|
554
|
+
this.clientServerConnections.delete(connectionId);
|
|
512
555
|
}
|
|
513
556
|
|
|
514
557
|
private async disposeClientServerPhysical(
|
|
@@ -518,12 +561,21 @@ export class ZLinkChannelSocketRegistry {
|
|
|
518
561
|
try {
|
|
519
562
|
current.dealer.disconnect(current.endpoint);
|
|
520
563
|
} catch {
|
|
521
|
-
//
|
|
564
|
+
// The socket close below releases an endpoint that is already disconnected.
|
|
522
565
|
}
|
|
523
|
-
this.ownedMonitors.delete(current.monitor);
|
|
524
566
|
this.unregisterReceiveFlowSocket(current.dealer);
|
|
525
|
-
current.readablePoller
|
|
526
|
-
|
|
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
|
+
]);
|
|
527
579
|
const errors = results
|
|
528
580
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
529
581
|
.map((result) => result.reason);
|
|
@@ -531,6 +583,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
531
583
|
if (errors.length > 1) {
|
|
532
584
|
throw new AggregateError(errors, `ClientServer connection '${connectionId}' cleanup failed.`);
|
|
533
585
|
}
|
|
586
|
+
if (current.monitor !== undefined) this.ownedResources.delete(current.monitor);
|
|
534
587
|
}
|
|
535
588
|
|
|
536
589
|
admitClientServerConnection(
|
|
@@ -545,6 +598,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
545
598
|
connection.readyConnectionId
|
|
546
599
|
);
|
|
547
600
|
if (admitted) connection.admittedDescriptor = descriptor;
|
|
601
|
+
this.notifyClientServerTopology(descriptor.channelName);
|
|
548
602
|
return admitted;
|
|
549
603
|
}
|
|
550
604
|
const duplicateId = [...this.clientServerReadyIdentities].find(
|
|
@@ -582,6 +636,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
582
636
|
connection.readyConnectionId = connectionId;
|
|
583
637
|
connection.admittedDescriptor = descriptor;
|
|
584
638
|
}
|
|
639
|
+
this.notifyClientServerTopology(descriptor.channelName);
|
|
585
640
|
return admitted;
|
|
586
641
|
}
|
|
587
642
|
|
|
@@ -605,6 +660,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
605
660
|
connection.outstandingProbeId = undefined;
|
|
606
661
|
}
|
|
607
662
|
}
|
|
663
|
+
this.notifyClientServerTopology(channelName);
|
|
608
664
|
return removed;
|
|
609
665
|
}
|
|
610
666
|
|
|
@@ -636,52 +692,60 @@ export class ZLinkChannelSocketRegistry {
|
|
|
636
692
|
return undefined;
|
|
637
693
|
}
|
|
638
694
|
|
|
639
|
-
/**
|
|
640
|
-
* Resolves a ClientServer send target, waiting when the ready candidate set is still empty, as
|
|
641
|
-
* `framework/doc/framework/common/spec/server/02-channel-transport/02-channel-messaging.ko.md` §3.2 requires: the call waits
|
|
642
|
-
* at call time for a bounded period and then fails with no-target. The bound is the shorter of
|
|
643
|
-
* the call's remaining deadline and five seconds, mirroring the .NET reference
|
|
644
|
-
* `ZLinkClientServerClientRuntime.WaitForReadyAsync`. The wait lives here because this registry
|
|
645
|
-
* owns ClientServer connections, admission and weighted selection. Sends have no per-call
|
|
646
|
-
* timeout, so they use the Channel's request timeout.
|
|
647
|
-
*
|
|
648
|
-
* The wait only observes admission that is already in flight: it never opens or reconnects a
|
|
649
|
-
* connection, so it cannot trigger the admission it waits for, and Framework startup keeps not
|
|
650
|
-
* waiting for local ClientServer admission. It applies whenever nothing is selectable, including
|
|
651
|
-
* candidate sets excluded by weight 0 or drain, because `selectClientServerDealer` filters the
|
|
652
|
-
* same way the reference `SelectReady()` does.
|
|
653
|
-
*
|
|
654
|
-
* Every attempt yields to the event loop between polls. ClientServer admission completes on the
|
|
655
|
-
* monitor drains that the backend poll timer pumps, so a synchronous wait would starve the
|
|
656
|
-
* admission it is waiting for and burn the whole bound before failing anyway. That is this
|
|
657
|
-
* execution model's form of the hazard the JVM mirror avoids by not holding the admission
|
|
658
|
-
* monitor across its sleep.
|
|
659
|
-
*/
|
|
695
|
+
/** Observes discovery changes until the client DEALER admission deadline. */
|
|
660
696
|
async awaitClientDealerForOutbound(
|
|
661
697
|
channelName: string,
|
|
662
|
-
signal?: AbortSignal
|
|
663
|
-
deadlineAtMs?: number
|
|
698
|
+
signal?: AbortSignal
|
|
664
699
|
): Promise<ZLinkBackendDealerSocket | undefined> {
|
|
665
|
-
|
|
666
|
-
const
|
|
667
|
-
deadlineAtMs ??
|
|
668
|
-
startedAtMs +
|
|
669
|
-
(this.registration.channels.get(channelName)?.requestTimeoutMs ??
|
|
670
|
-
this.registration.requestTimeoutMs ??
|
|
671
|
-
DEFAULT_REQUEST_TIMEOUT_MS),
|
|
672
|
-
startedAtMs + CLIENT_SERVER_READY_WAIT_CAP_MS
|
|
673
|
-
);
|
|
674
|
-
for (;;) {
|
|
675
|
-
this.drainSocketMonitors();
|
|
700
|
+
throwIfAborted(signal);
|
|
701
|
+
const select = (): ZLinkBackendDealerSocket | undefined => {
|
|
676
702
|
const dealer = this.clientDealerForOutbound(channelName);
|
|
677
703
|
if (dealer !== undefined) return dealer;
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
}
|
|
684
|
-
|
|
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
|
+
});
|
|
685
749
|
}
|
|
686
750
|
|
|
687
751
|
startManualClientServerConnections(): void {
|
|
@@ -716,26 +780,41 @@ export class ZLinkChannelSocketRegistry {
|
|
|
716
780
|
}
|
|
717
781
|
}
|
|
718
782
|
|
|
719
|
-
clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor {
|
|
720
|
-
|
|
721
|
-
|
|
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
|
+
);
|
|
722
791
|
}
|
|
723
792
|
let disposed = false;
|
|
724
|
-
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
|
+
};
|
|
725
807
|
return {
|
|
726
808
|
nativeInstance: {},
|
|
727
809
|
onEvent: (next) => {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
this.clientServerMonitorHandlers.set(channelName, handlers);
|
|
737
|
-
}
|
|
738
|
-
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
|
+
});
|
|
739
818
|
},
|
|
740
819
|
drain: () => 0,
|
|
741
820
|
dispose: async () => {
|
|
@@ -822,6 +901,11 @@ export class ZLinkChannelSocketRegistry {
|
|
|
822
901
|
this.clientServerServerDescriptors.set(channelName, descriptor);
|
|
823
902
|
this.pushClientServerDescriptorUpdate(channelName, descriptor);
|
|
824
903
|
}
|
|
904
|
+
this.notifyClientServerTopology(channelName);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
private notifyClientServerTopology(channelName: string): void {
|
|
908
|
+
for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? []) handler();
|
|
825
909
|
}
|
|
826
910
|
|
|
827
911
|
tryHandleClientServerControl(
|
|
@@ -869,7 +953,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
869
953
|
received.parts.length !== 1 ||
|
|
870
954
|
received.replyToken === null
|
|
871
955
|
) {
|
|
872
|
-
reply = encodeClientServerReject(
|
|
956
|
+
reply = encodeClientServerReject(ClientServerRejectReason.ProtocolVersionUnsupported);
|
|
873
957
|
} else {
|
|
874
958
|
const descriptor = this.clientServerServerDescriptors.get(channelName);
|
|
875
959
|
if (
|
|
@@ -877,10 +961,10 @@ export class ZLinkChannelSocketRegistry {
|
|
|
877
961
|
record.hello.channelName !== channelName ||
|
|
878
962
|
record.hello.securityIdentity !== descriptor.securityIdentity
|
|
879
963
|
) {
|
|
880
|
-
reply = encodeClientServerReject(
|
|
964
|
+
reply = encodeClientServerReject(ClientServerRejectReason.AdmissionMismatch);
|
|
881
965
|
} else {
|
|
882
966
|
const normalizedEffectiveMaxMessageBytes = Math.min(
|
|
883
|
-
|
|
967
|
+
normalizeClientServerMessageLimit(router.maxMessageSize),
|
|
884
968
|
record.hello.normalizedEffectiveMaxMessageBytes
|
|
885
969
|
);
|
|
886
970
|
reply = encodeClientServerAdmit(descriptor, normalizedEffectiveMaxMessageBytes);
|
|
@@ -966,23 +1050,31 @@ export class ZLinkChannelSocketRegistry {
|
|
|
966
1050
|
);
|
|
967
1051
|
}
|
|
968
1052
|
const subscriber = this.adapter.createSubscriberSocket(this.context);
|
|
969
|
-
subscriber.setChannelName(channelName);
|
|
970
|
-
setFanoutSubscriptions(subscriber, channel.subscriptions);
|
|
971
|
-
const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
|
|
972
1053
|
const connection: FanoutPublisherConnection = {
|
|
973
1054
|
channelName,
|
|
974
1055
|
endpoint,
|
|
975
1056
|
subscriber,
|
|
976
|
-
monitor,
|
|
977
1057
|
callbacks,
|
|
978
1058
|
physicalConnectionId: Symbol(connectionId),
|
|
979
1059
|
transportReady: false,
|
|
980
1060
|
ready: false
|
|
981
1061
|
};
|
|
982
|
-
this.
|
|
983
|
-
|
|
984
|
-
|
|
1062
|
+
this.ownedResources.add(subscriber);
|
|
1063
|
+
const created: (
|
|
1064
|
+
| ZLinkBackendSocketMonitor
|
|
1065
|
+
| ZLinkBackendReadablePoller
|
|
1066
|
+
| ZLinkBackendDealerSocket
|
|
1067
|
+
| ZLinkBackendSubscriberSocket
|
|
1068
|
+
)[] = [subscriber];
|
|
985
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();
|
|
986
1078
|
monitor.onEvent((event) => {
|
|
987
1079
|
if (this.fanoutConnections.get(connectionId) !== connection) return;
|
|
988
1080
|
for (const handler of this.fanoutMonitorHandlers.get(channelName) ?? []) {
|
|
@@ -1006,28 +1098,36 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1006
1098
|
}
|
|
1007
1099
|
});
|
|
1008
1100
|
subscriber.connect(endpoint);
|
|
1101
|
+
return subscriber;
|
|
1009
1102
|
} catch (error) {
|
|
1010
1103
|
this.fanoutConnections.delete(connectionId);
|
|
1011
|
-
|
|
1012
|
-
|
|
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
|
+
});
|
|
1013
1113
|
throw error;
|
|
1014
1114
|
}
|
|
1015
|
-
return subscriber;
|
|
1016
1115
|
}
|
|
1017
1116
|
|
|
1018
1117
|
async closeFanoutSubscriberConnection(connectionId: string): Promise<void> {
|
|
1019
1118
|
const connection = this.fanoutConnections.get(connectionId);
|
|
1020
1119
|
if (connection === undefined) return;
|
|
1021
|
-
this.fanoutConnections.delete(connectionId);
|
|
1022
1120
|
try {
|
|
1023
1121
|
connection.subscriber.disconnect(connection.endpoint);
|
|
1024
1122
|
} catch {
|
|
1025
|
-
//
|
|
1123
|
+
// The socket close below releases an endpoint that is already disconnected.
|
|
1026
1124
|
}
|
|
1027
|
-
this.ownedMonitors.delete(connection.monitor);
|
|
1028
1125
|
const results = await Promise.allSettled([
|
|
1029
|
-
connection.monitor
|
|
1030
|
-
|
|
1126
|
+
connection.monitor?.dispose(),
|
|
1127
|
+
(async () => {
|
|
1128
|
+
await connection.subscriber.dispose();
|
|
1129
|
+
this.ownedResources.delete(connection.subscriber);
|
|
1130
|
+
})()
|
|
1031
1131
|
]);
|
|
1032
1132
|
const errors = results
|
|
1033
1133
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
@@ -1036,6 +1136,8 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1036
1136
|
if (errors.length > 1) {
|
|
1037
1137
|
throw new AggregateError(errors, `Fanout connection '${connectionId}' cleanup failed.`);
|
|
1038
1138
|
}
|
|
1139
|
+
this.fanoutConnections.delete(connectionId);
|
|
1140
|
+
if (connection.monitor !== undefined) this.ownedResources.delete(connection.monitor);
|
|
1039
1141
|
}
|
|
1040
1142
|
|
|
1041
1143
|
handleFanoutInbound(
|
|
@@ -1156,7 +1258,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1156
1258
|
};
|
|
1157
1259
|
}
|
|
1158
1260
|
|
|
1159
|
-
|
|
1261
|
+
notifyFanoutTopology(channelName: string): void {
|
|
1160
1262
|
for (const handler of this.fanoutTopologyHandlers.get(channelName) ?? []) {
|
|
1161
1263
|
try {
|
|
1162
1264
|
handler();
|
|
@@ -1285,7 +1387,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1285
1387
|
connection: ClientServerPhysicalConnection
|
|
1286
1388
|
): void {
|
|
1287
1389
|
for (;;) {
|
|
1288
|
-
if (!connection.readablePoller.wait(0)) return;
|
|
1390
|
+
if (connection.readablePoller === undefined || !connection.readablePoller.wait(0)) return;
|
|
1289
1391
|
const received = connection.dealer.recv(1);
|
|
1290
1392
|
if (received === undefined) {
|
|
1291
1393
|
connection.readablePoller.markDrained();
|
|
@@ -1417,12 +1519,15 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1417
1519
|
|
|
1418
1520
|
private ensureClientServerLivenessTimer(): void {
|
|
1419
1521
|
if (this.clientServerLivenessTimer !== undefined) return;
|
|
1420
|
-
this.clientServerLivenessTimer = setInterval(
|
|
1522
|
+
this.clientServerLivenessTimer = setInterval(
|
|
1523
|
+
() => this.tickClientServerLiveness(),
|
|
1524
|
+
CLIENT_SERVER_LIVENESS_TICK_MS
|
|
1525
|
+
);
|
|
1421
1526
|
this.clientServerLivenessTimer.unref();
|
|
1422
1527
|
}
|
|
1423
1528
|
|
|
1424
1529
|
private drainSocketMonitors(): void {
|
|
1425
|
-
for (const monitor of this.
|
|
1530
|
+
for (const monitor of this.ownedResources) if ('drain' in monitor) monitor.drain();
|
|
1426
1531
|
}
|
|
1427
1532
|
|
|
1428
1533
|
private removeReadyConnection(connectionId: string): void {
|
|
@@ -1443,6 +1548,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1443
1548
|
connection.nextProbeAt = undefined;
|
|
1444
1549
|
connection.outstandingProbeId = undefined;
|
|
1445
1550
|
}
|
|
1551
|
+
this.notifyClientServerTopology(identity.channelName);
|
|
1446
1552
|
}
|
|
1447
1553
|
|
|
1448
1554
|
private requestClientServerLiveness(
|
|
@@ -1590,7 +1696,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1590
1696
|
|
|
1591
1697
|
private allocateClientServerProbeId(): bigint {
|
|
1592
1698
|
const result = this.nextClientServerProbeId;
|
|
1593
|
-
this.nextClientServerProbeId = result ===
|
|
1699
|
+
this.nextClientServerProbeId = result === UINT64_MAX ? 1n : result + 1n;
|
|
1594
1700
|
return result;
|
|
1595
1701
|
}
|
|
1596
1702
|
|
|
@@ -1613,10 +1719,10 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1613
1719
|
}
|
|
1614
1720
|
|
|
1615
1721
|
const publisher = this.adapter.createPublisherSocket(this.context);
|
|
1722
|
+
this.publishers.set(channelName, publisher);
|
|
1616
1723
|
publisher.setChannelName(channelName);
|
|
1617
1724
|
applyFanoutPublisherSocketOptions(publisher, channel);
|
|
1618
1725
|
publisher.bind(channel.publisher.bind);
|
|
1619
|
-
this.publishers.set(channelName, publisher);
|
|
1620
1726
|
const endpoint = buildAdvertisedEndpoint(
|
|
1621
1727
|
publisher.lastEndpoint ?? channel.publisher.bind,
|
|
1622
1728
|
channel.publisher.advertiseHost
|
|
@@ -1645,6 +1751,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1645
1751
|
);
|
|
1646
1752
|
}
|
|
1647
1753
|
const router = this.adapter.createRouterSocket(this.context);
|
|
1754
|
+
this.routeRouters.set(routerChannelId, router);
|
|
1648
1755
|
this.registerReceiveFlowSocket(router);
|
|
1649
1756
|
router.setChannelName(routerChannelId);
|
|
1650
1757
|
if (
|
|
@@ -1656,7 +1763,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1656
1763
|
router.setRoutingId(
|
|
1657
1764
|
routeChannel.routingId ?? `${routeChannel.routingIdPrefix ?? routerChannelId}-${randomUUID()}`
|
|
1658
1765
|
);
|
|
1659
|
-
const publicWeight = routeChannel.weight ??
|
|
1766
|
+
const publicWeight = routeChannel.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
1660
1767
|
this.routeMeshPublicWeights.set(routerChannelId, publicWeight);
|
|
1661
1768
|
router.peerWeight = rawAvailabilityWeight(publicWeight);
|
|
1662
1769
|
applySocketConfig(router, routeChannel);
|
|
@@ -1670,7 +1777,6 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1670
1777
|
if (routeChannel.bind !== undefined && routeChannel.bind.trim().length > 0) {
|
|
1671
1778
|
router.bind(routeChannel.bind);
|
|
1672
1779
|
}
|
|
1673
|
-
this.routeRouters.set(routerChannelId, router);
|
|
1674
1780
|
return router;
|
|
1675
1781
|
}
|
|
1676
1782
|
|
|
@@ -1680,7 +1786,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1680
1786
|
|
|
1681
1787
|
routeMeshWeight(routerChannelId: string): number {
|
|
1682
1788
|
this.routeRouter(routerChannelId);
|
|
1683
|
-
return this.routeMeshPublicWeights.get(routerChannelId) ??
|
|
1789
|
+
return this.routeMeshPublicWeights.get(routerChannelId) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
|
|
1684
1790
|
}
|
|
1685
1791
|
|
|
1686
1792
|
setRouteMeshWeight(routerChannelId: string, weight: number): void {
|
|
@@ -1717,7 +1823,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1717
1823
|
return;
|
|
1718
1824
|
}
|
|
1719
1825
|
const monitor = this.monitoringAdapter.openSocketMonitor(socket);
|
|
1720
|
-
this.
|
|
1826
|
+
this.ownedResources.add(monitor);
|
|
1721
1827
|
monitor.onEvent((event) => {
|
|
1722
1828
|
if (
|
|
1723
1829
|
event.nativeEvent === ZLinkSocketNativeEventType.Disconnected &&
|
|
@@ -1733,7 +1839,7 @@ export class ZLinkChannelSocketRegistry {
|
|
|
1733
1839
|
return;
|
|
1734
1840
|
}
|
|
1735
1841
|
const monitor = this.monitoringAdapter.openSocketMonitor(router);
|
|
1736
|
-
this.
|
|
1842
|
+
this.ownedResources.add(monitor);
|
|
1737
1843
|
monitor.onEvent((event) => {
|
|
1738
1844
|
const routingId = event.routingId === undefined ? undefined : String(event.routingId);
|
|
1739
1845
|
if (
|
|
@@ -1775,7 +1881,7 @@ async function requestClientServerAdmission(
|
|
|
1775
1881
|
encodeClientServerHello({
|
|
1776
1882
|
channelName,
|
|
1777
1883
|
securityIdentity,
|
|
1778
|
-
normalizedEffectiveMaxMessageBytes:
|
|
1884
|
+
normalizedEffectiveMaxMessageBytes: normalizeClientServerMessageLimit(dealer.maxMessageSize)
|
|
1779
1885
|
})
|
|
1780
1886
|
);
|
|
1781
1887
|
try {
|
|
@@ -1853,9 +1959,9 @@ function setFanoutSubscriptions(
|
|
|
1853
1959
|
|
|
1854
1960
|
function deriveRoutingId(baseRoutingId: string, suffix: string): string {
|
|
1855
1961
|
const derived = `${baseRoutingId}\0${suffix}`;
|
|
1856
|
-
if (Buffer.byteLength(derived, 'utf8') >
|
|
1962
|
+
if (Buffer.byteLength(derived, 'utf8') > ZLINK_MAX_ROUTING_ID_BYTES) {
|
|
1857
1963
|
throw new ZLinkConfigurationException(
|
|
1858
|
-
`Derived routing id with suffix '${suffix}' exceeds the
|
|
1964
|
+
`Derived routing id with suffix '${suffix}' exceeds the ${ZLINK_MAX_ROUTING_ID_BYTES} byte limit.`
|
|
1859
1965
|
);
|
|
1860
1966
|
}
|
|
1861
1967
|
return derived;
|
|
@@ -1866,6 +1972,7 @@ function applyFanoutPublisherSocketOptions(
|
|
|
1866
1972
|
channel: ZLinkChannelOptions
|
|
1867
1973
|
): void {
|
|
1868
1974
|
publisher.noDrop = channel.noDrop ?? false;
|
|
1975
|
+
publisher.sendTimeoutMs = configuredSendTimeoutMs(channel.publisher?.sendTimeoutMs);
|
|
1869
1976
|
}
|
|
1870
1977
|
|
|
1871
1978
|
function fanoutDiscoveryConnectionId(connectionId: string): string {
|
|
@@ -1889,13 +1996,11 @@ function advertisedEndpoint(boundEndpoint: string, advertiseHost: string | undef
|
|
|
1889
1996
|
return result;
|
|
1890
1997
|
}
|
|
1891
1998
|
|
|
1892
|
-
function normalizedMessageLimit(value: number): number {
|
|
1893
|
-
return Number.isSafeInteger(value) && value > 0 ? Math.min(value, 0xffff_ffff) : 0x7fff_ffff;
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
1999
|
function requirePublicWeight(weight: number): void {
|
|
1897
|
-
if (!
|
|
1898
|
-
throw new ZLinkConfigurationException(
|
|
2000
|
+
if (!isValidPublicWeight(weight)) {
|
|
2001
|
+
throw new ZLinkConfigurationException(
|
|
2002
|
+
`Weight must be an integer in 0..${ZLINK_MAX_PUBLIC_WEIGHT}.`
|
|
2003
|
+
);
|
|
1899
2004
|
}
|
|
1900
2005
|
}
|
|
1901
2006
|
|
|
@@ -1931,3 +2036,7 @@ function applySocketConfig(
|
|
|
1931
2036
|
socket.maxMessageSize = config.maxMessageSize;
|
|
1932
2037
|
}
|
|
1933
2038
|
}
|
|
2039
|
+
|
|
2040
|
+
function configuredSendTimeoutMs(value: number | undefined): number {
|
|
2041
|
+
return value ?? DEFAULT_SEND_TIMEOUT_MS;
|
|
2042
|
+
}
|