@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,30 +1,36 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { constants as osConstants } from 'node:os';
|
|
2
|
+
import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
|
|
3
|
+
import type {
|
|
4
|
+
ApplicationJobPermitPort,
|
|
5
|
+
ApplicationJobQueuePort
|
|
6
|
+
} from '../application-jobs/contracts';
|
|
2
7
|
import type {
|
|
3
8
|
ZLinkRawBindingPort,
|
|
4
9
|
ZLinkRawHostPort,
|
|
5
|
-
ZLinkRawMonitorRecord,
|
|
6
|
-
ZLinkRawMonitorPort,
|
|
7
10
|
ZLinkRawReceivedRecord,
|
|
8
11
|
ZLinkRawRouterPort
|
|
9
12
|
} from '../backend/raw-binding-port';
|
|
10
13
|
import { RequestResult, SubmitResult } from '../backend/runtime-values';
|
|
11
|
-
import
|
|
12
|
-
ApplicationJobPermitPort,
|
|
13
|
-
ApplicationJobQueuePort
|
|
14
|
-
} from '../application-jobs/contracts';
|
|
15
|
-
import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
|
|
14
|
+
import { enumWireRejectReason } from '../protocol/service_wire_codec.generated';
|
|
16
15
|
import { OperationRegistry, type PendingOperation } from './operation-registry';
|
|
17
16
|
import { ServiceLivenessRegistry, type ServiceLivenessTick } from './service-liveness-registry';
|
|
18
17
|
import { ServiceMailbox, type ServiceMailboxRecord } from './service-mailbox';
|
|
19
18
|
import {
|
|
20
|
-
ServiceTopologyRegistry,
|
|
21
19
|
sameServiceNodeDescriptor,
|
|
20
|
+
ServiceTopologyRegistry,
|
|
22
21
|
validateDescriptor,
|
|
23
22
|
type AdmittedServicePeer,
|
|
24
23
|
type PeerAdmissionResult,
|
|
25
|
-
type
|
|
26
|
-
type
|
|
24
|
+
type ServiceNodeDescriptor,
|
|
25
|
+
type ServicePeerAdmissionExpectation
|
|
27
26
|
} from './service-topology-registry';
|
|
27
|
+
import { createServiceWireCodec } from './service-wire-codec';
|
|
28
|
+
import {
|
|
29
|
+
SERVICE_WIRE_MAGIC,
|
|
30
|
+
SERVICE_WIRE_MAJOR,
|
|
31
|
+
ServiceWireCommand,
|
|
32
|
+
ServiceWireFrameworkErrorCode
|
|
33
|
+
} from './service-wire-constants.generated';
|
|
28
34
|
import {
|
|
29
35
|
decodeApplicationPayloadView,
|
|
30
36
|
decodeChannelRequestHeader,
|
|
@@ -43,14 +49,11 @@ import {
|
|
|
43
49
|
encodeReplyHeader,
|
|
44
50
|
encodeRouteMeshAdmission,
|
|
45
51
|
M6aServiceWireCommand,
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
ServiceWireProtocolError,
|
|
53
|
+
type ServiceApplicationPayload
|
|
48
54
|
} from './service-wire-m6a-codec';
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ServiceWireCommand,
|
|
52
|
-
ServiceWireFrameworkErrorCode
|
|
53
|
-
} from './service-wire-constants.generated';
|
|
55
|
+
|
|
56
|
+
const nativeErrnoValues = osConstants.errno;
|
|
54
57
|
|
|
55
58
|
export type RawServicePumpResult =
|
|
56
59
|
'noData' | 'infrastructure' | 'application' | 'dropped' | 'protocolError';
|
|
@@ -96,6 +99,7 @@ export type RawServiceIngressHandler = (
|
|
|
96
99
|
) => RawServicePumpResult | undefined | Promise<RawServicePumpResult | undefined>;
|
|
97
100
|
|
|
98
101
|
export interface RawServiceMeshRuntimeOptions {
|
|
102
|
+
readonly onPendingOperationsChanged?: () => void;
|
|
99
103
|
readonly descriptor: ServiceNodeDescriptor;
|
|
100
104
|
readonly resolveAdvertisedEndpoint?: (boundEndpoint: string) => string;
|
|
101
105
|
readonly probeIntervalMs?: number;
|
|
@@ -119,31 +123,20 @@ export interface RawServiceMeshRuntimeOptions {
|
|
|
119
123
|
}) => void;
|
|
120
124
|
}
|
|
121
125
|
|
|
122
|
-
const MONITOR_DISCONNECTED = 0x0200;
|
|
123
|
-
const MONITOR_CONNECTION_READY = 0x1000;
|
|
124
|
-
const MONITOR_CONNECTION_READY_EDGE = 1;
|
|
125
126
|
// Framework error code 13 (RequestTargetNotFound) is encoded as 14 on a
|
|
126
127
|
// RequestResult.NotFound reply. Boundary transport results keep failureCode 0.
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
readonly direction: PhysicalConnectionDirection;
|
|
133
|
-
readonly discriminator: string;
|
|
134
|
-
readonly localAddress: string;
|
|
135
|
-
readonly remoteAddress: string;
|
|
136
|
-
}
|
|
128
|
+
const RAW_MESH_RECEIVE_RECORD_BUDGET = 64;
|
|
129
|
+
const RAW_MESH_RECEIVE_BYTE_BUDGET = 4 * 1024 * 1024;
|
|
130
|
+
export const RAW_MESH_RECEIVE_TIME_BUDGET_MS = 2;
|
|
131
|
+
|
|
132
|
+
const REQUEST_TARGET_NOT_FOUND_FAILURE_CODE = ServiceWireFrameworkErrorCode.requestTargetNotFound;
|
|
137
133
|
|
|
138
134
|
const livenessCodec = createServiceWireCodec({
|
|
139
|
-
magic:
|
|
140
|
-
major:
|
|
135
|
+
magic: SERVICE_WIRE_MAGIC,
|
|
136
|
+
major: SERVICE_WIRE_MAJOR,
|
|
141
137
|
commands: M6aServiceWireCommand
|
|
142
138
|
});
|
|
143
139
|
|
|
144
|
-
const MAX_PENDING_MONITOR_EVENTS = 8192;
|
|
145
|
-
const MAX_UNRESOLVED_CONNECTION_CANDIDATES = 4096;
|
|
146
|
-
|
|
147
140
|
/**
|
|
148
141
|
* RouteMesh M6A runtime built only on the public raw binding package.
|
|
149
142
|
* It owns protocol, admission, mailbox, request and liveness state.
|
|
@@ -153,7 +146,7 @@ export class RawServiceMeshRuntime {
|
|
|
153
146
|
readonly mailbox: ServiceMailbox;
|
|
154
147
|
readonly liveness: ServiceLivenessRegistry;
|
|
155
148
|
|
|
156
|
-
private readonly operations
|
|
149
|
+
private readonly operations: OperationRegistry<RawServiceRequestResult>;
|
|
157
150
|
private readonly expectedPeers = new Map<
|
|
158
151
|
string,
|
|
159
152
|
{
|
|
@@ -162,24 +155,16 @@ export class RawServiceMeshRuntime {
|
|
|
162
155
|
readonly endpoint?: string;
|
|
163
156
|
readonly securityIdentity?: string;
|
|
164
157
|
readonly lifecycleGeneration?: bigint;
|
|
158
|
+
helloSubmittedGeneration?: bigint;
|
|
165
159
|
}
|
|
166
160
|
>();
|
|
167
161
|
private readonly endpointOnlyPeers = new Set<string>();
|
|
168
162
|
private readonly peerConnectionIntentRemoved = new Set<(nodeRoutingId: string) => void>();
|
|
169
|
-
private readonly connectionCandidates = new Map<
|
|
170
|
-
string,
|
|
171
|
-
Map<string, PhysicalConnectionCandidate>
|
|
172
|
-
>();
|
|
173
|
-
private readonly unresolvedConnectionCandidates: PhysicalConnectionCandidate[] = [];
|
|
174
|
-
private readonly connectionIds = new Map<string, string>();
|
|
175
163
|
/**
|
|
176
|
-
* The
|
|
177
|
-
*
|
|
178
|
-
* longer usable by the application route.
|
|
164
|
+
* The last observed Core selected route of each RID (Core ROUTER §10.1):
|
|
165
|
+
* RID -> route generation. Only `observeSelectedRoutes` replaces it.
|
|
179
166
|
*/
|
|
180
|
-
private
|
|
181
|
-
private monitorEvents: ZLinkRawMonitorRecord[] = [];
|
|
182
|
-
private monitorDrainBuffer: ZLinkRawMonitorRecord[] = [];
|
|
167
|
+
private selectedRoutes = new Map<string, bigint>();
|
|
183
168
|
private readonly bindingPort: ZLinkRawBindingPort;
|
|
184
169
|
private readonly applicationJobQueue: ApplicationJobQueuePort;
|
|
185
170
|
private readonly peerAdmissionSealed?: () => boolean;
|
|
@@ -192,12 +177,12 @@ export class RawServiceMeshRuntime {
|
|
|
192
177
|
private descriptor: ServiceNodeDescriptor;
|
|
193
178
|
private host?: ZLinkRawHostPort;
|
|
194
179
|
private router?: ZLinkRawRouterPort;
|
|
195
|
-
private monitor?: ZLinkRawMonitorPort;
|
|
196
180
|
private nextCorrelation = 1n;
|
|
197
181
|
private serviceIngress?: RawServiceIngressHandler;
|
|
198
182
|
private closed = false;
|
|
199
183
|
|
|
200
184
|
constructor(options: RawServiceMeshRuntimeOptions) {
|
|
185
|
+
this.operations = new OperationRegistry(undefined, options.onPendingOperationsChanged);
|
|
201
186
|
this.descriptor = options.descriptor;
|
|
202
187
|
this.topology = new ServiceTopologyRegistry(options.descriptor);
|
|
203
188
|
this.mailbox = new ServiceMailbox(options.onMailboxReady);
|
|
@@ -239,8 +224,6 @@ export class RawServiceMeshRuntime {
|
|
|
239
224
|
};
|
|
240
225
|
this.topology.publishLocal(next);
|
|
241
226
|
this.descriptor = next;
|
|
242
|
-
this.monitor = router.monitor();
|
|
243
|
-
this.pullMonitorEvents();
|
|
244
227
|
this.host = host;
|
|
245
228
|
this.router = router;
|
|
246
229
|
} catch (error) {
|
|
@@ -254,13 +237,16 @@ export class RawServiceMeshRuntime {
|
|
|
254
237
|
|
|
255
238
|
connectPeer(endpoint: string, expected: ServiceNodeDescriptor): void {
|
|
256
239
|
this.requireStarted().connectToRoutingId(expected.nodeRoutingId, endpoint);
|
|
257
|
-
this.expectedPeers.set(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
240
|
+
this.expectedPeers.set(
|
|
241
|
+
expected.nodeRoutingId,
|
|
242
|
+
Object.assign(this.expectedPeers.get(expected.nodeRoutingId) ?? {}, {
|
|
243
|
+
meshName: expected.meshName,
|
|
244
|
+
nodeRoutingId: expected.nodeRoutingId,
|
|
245
|
+
endpoint,
|
|
246
|
+
securityIdentity: expected.securityIdentity,
|
|
247
|
+
lifecycleGeneration: expected.lifecycleGeneration
|
|
248
|
+
})
|
|
249
|
+
);
|
|
264
250
|
}
|
|
265
251
|
|
|
266
252
|
connectPeerByRoutingId(
|
|
@@ -270,13 +256,16 @@ export class RawServiceMeshRuntime {
|
|
|
270
256
|
lifecycleGeneration?: bigint
|
|
271
257
|
): void {
|
|
272
258
|
this.requireStarted().connectToRoutingId(nodeRoutingId, endpoint);
|
|
273
|
-
this.expectedPeers.set(
|
|
274
|
-
meshName: this.topology.localDescriptor().meshName,
|
|
259
|
+
this.expectedPeers.set(
|
|
275
260
|
nodeRoutingId,
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
261
|
+
Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
|
|
262
|
+
meshName: this.topology.localDescriptor().meshName,
|
|
263
|
+
nodeRoutingId,
|
|
264
|
+
endpoint,
|
|
265
|
+
securityIdentity,
|
|
266
|
+
lifecycleGeneration
|
|
267
|
+
})
|
|
268
|
+
);
|
|
280
269
|
}
|
|
281
270
|
|
|
282
271
|
expectPeerByRoutingId(
|
|
@@ -285,13 +274,16 @@ export class RawServiceMeshRuntime {
|
|
|
285
274
|
securityIdentity?: string,
|
|
286
275
|
lifecycleGeneration?: bigint
|
|
287
276
|
): void {
|
|
288
|
-
this.expectedPeers.set(
|
|
289
|
-
meshName: this.topology.localDescriptor().meshName,
|
|
277
|
+
this.expectedPeers.set(
|
|
290
278
|
nodeRoutingId,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
279
|
+
Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
|
|
280
|
+
meshName: this.topology.localDescriptor().meshName,
|
|
281
|
+
nodeRoutingId,
|
|
282
|
+
endpoint,
|
|
283
|
+
securityIdentity,
|
|
284
|
+
lifecycleGeneration
|
|
285
|
+
})
|
|
286
|
+
);
|
|
295
287
|
}
|
|
296
288
|
|
|
297
289
|
connectPeerEndpoint(endpoint: string): void {
|
|
@@ -379,35 +371,42 @@ export class RawServiceMeshRuntime {
|
|
|
379
371
|
}
|
|
380
372
|
|
|
381
373
|
async announcePeer(nodeRoutingId: string): Promise<boolean> {
|
|
382
|
-
|
|
374
|
+
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
375
|
+
const generation = this.selectedRoutes.get(nodeRoutingId);
|
|
376
|
+
if (
|
|
377
|
+
expected === undefined ||
|
|
378
|
+
generation === undefined ||
|
|
379
|
+
expected.helloSubmittedGeneration === generation ||
|
|
380
|
+
this.peerAdmissionSealed?.() === true
|
|
381
|
+
)
|
|
383
382
|
return false;
|
|
384
|
-
|
|
383
|
+
const accepted = await this.send(nodeRoutingId, [
|
|
385
384
|
encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())
|
|
386
385
|
]);
|
|
386
|
+
if (
|
|
387
|
+
accepted &&
|
|
388
|
+
this.expectedPeers.get(nodeRoutingId) === expected &&
|
|
389
|
+
this.selectedRoutes.get(nodeRoutingId) === generation
|
|
390
|
+
)
|
|
391
|
+
expected.helloSubmittedGeneration = generation;
|
|
392
|
+
return accepted;
|
|
387
393
|
}
|
|
388
394
|
|
|
389
395
|
isPeerRouteReady(nodeRoutingId: string, lifecycleGeneration?: bigint): boolean {
|
|
396
|
+
// Admission is bound to the observed selected route: the route observer
|
|
397
|
+
// removes the peer when that route ends or is replaced.
|
|
390
398
|
const peer = this.topology.peer(nodeRoutingId);
|
|
391
|
-
|
|
392
|
-
const applicationRouteReady =
|
|
393
|
-
monitorConnection === undefined || monitorConnection === peer?.connectionId;
|
|
394
|
-
const ready =
|
|
399
|
+
return (
|
|
395
400
|
peer !== undefined &&
|
|
396
401
|
(lifecycleGeneration === undefined ||
|
|
397
402
|
peer.descriptor.lifecycleGeneration === lifecycleGeneration) &&
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return ready;
|
|
403
|
+
this.liveness.isReady(nodeRoutingId, peer.connectionId)
|
|
404
|
+
);
|
|
401
405
|
}
|
|
402
406
|
|
|
403
407
|
async announceExpectedPeers(): Promise<number> {
|
|
404
408
|
let accepted = 0;
|
|
405
409
|
for (const nodeRoutingId of this.expectedPeers.keys()) {
|
|
406
|
-
// Admission is a one-time fence for the current physical connection.
|
|
407
|
-
// Re-sending Hello after the peer is admitted would re-run admission on
|
|
408
|
-
// every poll and reset the liveness record before application traffic
|
|
409
|
-
// can use the route. A disconnected peer is removed by monitor handling
|
|
410
|
-
// and remains eligible for the next admission attempt.
|
|
411
410
|
if (this.topology.peer(nodeRoutingId) !== undefined) continue;
|
|
412
411
|
if (await this.announcePeer(nodeRoutingId)) accepted++;
|
|
413
412
|
}
|
|
@@ -451,7 +450,6 @@ export class RawServiceMeshRuntime {
|
|
|
451
450
|
for (const peer of this.topology.peers()) {
|
|
452
451
|
await this.send(peer.descriptor.nodeRoutingId, [update]);
|
|
453
452
|
}
|
|
454
|
-
await this.announceExpectedPeers();
|
|
455
453
|
}
|
|
456
454
|
|
|
457
455
|
replaceDiscoveredNotRequired(descriptors: readonly ServiceNodeDescriptor[]): void {
|
|
@@ -481,23 +479,6 @@ export class RawServiceMeshRuntime {
|
|
|
481
479
|
if (selection.kind !== 'selected') return selection.submitResult;
|
|
482
480
|
const selected = selection.peer;
|
|
483
481
|
const applicationFrame = this.applicationFrame(payload);
|
|
484
|
-
if (selected.descriptor.nodeRoutingId === this.descriptor.nodeRoutingId) {
|
|
485
|
-
const applicationJobOwner = await this.reserveLocalIngress();
|
|
486
|
-
try {
|
|
487
|
-
const applicationJob = await applicationJobOwner.acquire('application');
|
|
488
|
-
const accepted = this.mailbox.tryEnqueue({
|
|
489
|
-
owner: `channel:${channelName}`,
|
|
490
|
-
domain: 'application',
|
|
491
|
-
parts: [encodeChannelSendHeader(channelName), applicationFrame],
|
|
492
|
-
sourceRoutingId: this.descriptor.nodeRoutingId,
|
|
493
|
-
applicationJob
|
|
494
|
-
});
|
|
495
|
-
if (!accepted) applicationJob.close();
|
|
496
|
-
return accepted ? SubmitResult.Ok : SubmitResult.NotAdmitted;
|
|
497
|
-
} finally {
|
|
498
|
-
applicationJobOwner.close();
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
482
|
return (await this.send(selected.descriptor.nodeRoutingId, [
|
|
502
483
|
encodeChannelSendHeader(channelName),
|
|
503
484
|
applicationFrame
|
|
@@ -535,7 +516,7 @@ export class RawServiceMeshRuntime {
|
|
|
535
516
|
|
|
536
517
|
private selectChannelTarget(channelName: string): RawServiceChannelTargetSelection {
|
|
537
518
|
const selected = this.topology.selectChannel(channelName, (peer) =>
|
|
538
|
-
this.
|
|
519
|
+
this.isPeerRouteReady(peer.descriptor.nodeRoutingId)
|
|
539
520
|
);
|
|
540
521
|
if (selected !== undefined) return { kind: 'selected', peer: selected };
|
|
541
522
|
return this.topology.hasKnownChannelTarget(channelName)
|
|
@@ -554,10 +535,6 @@ export class RawServiceMeshRuntime {
|
|
|
554
535
|
};
|
|
555
536
|
}
|
|
556
537
|
|
|
557
|
-
private isLocalOrReadyPeer(nodeRoutingId: string): boolean {
|
|
558
|
-
return nodeRoutingId === this.descriptor.nodeRoutingId || this.isPeerRouteReady(nodeRoutingId);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
538
|
setServiceIngress(handler: RawServiceIngressHandler): void {
|
|
562
539
|
if (this.serviceIngress !== undefined && this.serviceIngress !== handler) {
|
|
563
540
|
throw new Error('Raw service ingress is already registered.');
|
|
@@ -629,24 +606,23 @@ export class RawServiceMeshRuntime {
|
|
|
629
606
|
nowMs = performance.now(),
|
|
630
607
|
observe?: RawServicePumpObserver
|
|
631
608
|
): Promise<RawServicePumpResult> {
|
|
632
|
-
this.pullMonitorEvents();
|
|
633
609
|
return this.receiveOne(nowMs, observe);
|
|
634
610
|
}
|
|
635
611
|
|
|
636
|
-
setReadableHandler(handler: () => void): void {
|
|
612
|
+
setReadableHandler(handler: (receiveReady: boolean, routeReady: boolean) => void): void {
|
|
637
613
|
this.requireStarted().setReadableHandler(handler);
|
|
638
614
|
}
|
|
639
615
|
|
|
640
616
|
/** Returns whether a receive budget ended before no-data; idle ticks only maintain peers. */
|
|
641
|
-
async pumpBatch(receiveReady = true): Promise<boolean> {
|
|
642
|
-
await this.
|
|
617
|
+
async pumpBatch(receiveReady = true, routeReady = false): Promise<boolean> {
|
|
618
|
+
if (routeReady) await this.observeSelectedRoutes();
|
|
643
619
|
const startedAtMs = performance.now();
|
|
644
620
|
let messages = 0;
|
|
645
621
|
let bytes = 0;
|
|
646
622
|
const observe: RawServicePumpObserver = (_source, byteCount) => {
|
|
647
623
|
bytes += byteCount;
|
|
648
624
|
};
|
|
649
|
-
while (receiveReady && messages <
|
|
625
|
+
while (receiveReady && messages < RAW_MESH_RECEIVE_RECORD_BUDGET && !this.closed) {
|
|
650
626
|
const result = await this.receiveOne(performance.now(), observe);
|
|
651
627
|
if (result === 'noData') {
|
|
652
628
|
receiveReady = false;
|
|
@@ -655,7 +631,11 @@ export class RawServiceMeshRuntime {
|
|
|
655
631
|
messages += 1;
|
|
656
632
|
// Core owns the per-peer fair-queue cursor. The Framework limit bounds
|
|
657
633
|
// the entire round, so changing peers does not renew its byte/count budget.
|
|
658
|
-
if (
|
|
634
|
+
if (
|
|
635
|
+
bytes >= RAW_MESH_RECEIVE_BYTE_BUDGET ||
|
|
636
|
+
performance.now() - startedAtMs >= RAW_MESH_RECEIVE_TIME_BUDGET_MS
|
|
637
|
+
)
|
|
638
|
+
break;
|
|
659
639
|
}
|
|
660
640
|
if (!this.closed) {
|
|
661
641
|
await this.announceExpectedPeers();
|
|
@@ -711,24 +691,6 @@ export class RawServiceMeshRuntime {
|
|
|
711
691
|
}
|
|
712
692
|
}
|
|
713
693
|
|
|
714
|
-
private pullMonitorEvents(): void {
|
|
715
|
-
this.monitor?.drain((event) => {
|
|
716
|
-
this.observeMonitorEvent(event);
|
|
717
|
-
if (this.monitorEvents.length < MAX_PENDING_MONITOR_EVENTS) {
|
|
718
|
-
this.monitorEvents.push(event);
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
const existingIndex = this.monitorEvents.findIndex((candidate) =>
|
|
722
|
-
sameMonitorConnection(candidate, event)
|
|
723
|
-
);
|
|
724
|
-
if (existingIndex >= 0) this.monitorEvents[existingIndex] = event;
|
|
725
|
-
else {
|
|
726
|
-
this.monitorEvents.shift();
|
|
727
|
-
this.monitorEvents.push(event);
|
|
728
|
-
}
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
|
|
732
694
|
private reportProtocolError(
|
|
733
695
|
received: import('../backend/node/node-raw-binding-port').ZLinkRawReceivedRecord
|
|
734
696
|
): void {
|
|
@@ -809,14 +771,17 @@ export class RawServiceMeshRuntime {
|
|
|
809
771
|
(expected.meshName !== descriptor.meshName ||
|
|
810
772
|
expected.nodeRoutingId !== descriptor.nodeRoutingId)
|
|
811
773
|
) {
|
|
812
|
-
await this.send(received.sourceRid, [
|
|
774
|
+
await this.send(received.sourceRid, [
|
|
775
|
+
encodeReject(enumWireRejectReason('identityMismatch'))
|
|
776
|
+
]);
|
|
813
777
|
return 'infrastructure';
|
|
814
778
|
}
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
779
|
+
const result = this.admitPeer(
|
|
780
|
+
descriptor,
|
|
781
|
+
routeConnectionId(received.routeGeneration),
|
|
782
|
+
nowMs,
|
|
783
|
+
expected
|
|
818
784
|
);
|
|
819
|
-
const result = this.admitPeer(descriptor, connection, nowMs, expected);
|
|
820
785
|
if (result !== 'admitted' && result !== 'notRequired') {
|
|
821
786
|
const detail =
|
|
822
787
|
result === 'invalidDescriptor'
|
|
@@ -848,25 +813,7 @@ export class RawServiceMeshRuntime {
|
|
|
848
813
|
}
|
|
849
814
|
if (header.command === M6aServiceWireCommand.reject) {
|
|
850
815
|
if (received.parts.length !== 1) return 'protocolError';
|
|
851
|
-
|
|
852
|
-
// A reject belongs to one physical candidate, but the wire record does
|
|
853
|
-
// not carry that candidate's connection id. Keep an already admitted
|
|
854
|
-
// peer: bilateral manual connect can reject the duplicate after the
|
|
855
|
-
// other candidate has become Ready.
|
|
856
|
-
if (reason === 4 && this.topology.peer(received.sourceRid) === undefined) {
|
|
857
|
-
const expected = this.expectedPeers.get(received.sourceRid);
|
|
858
|
-
const local = this.topology.localDescriptor();
|
|
859
|
-
this.topology.markNotRequired({
|
|
860
|
-
...local,
|
|
861
|
-
nodeRoutingId: received.sourceRid,
|
|
862
|
-
lifecycleGeneration: 1n,
|
|
863
|
-
descriptorRevision: 1n,
|
|
864
|
-
advertisedEndpoint: expected?.endpoint ?? local.advertisedEndpoint,
|
|
865
|
-
channels: [],
|
|
866
|
-
objectRole: 'client'
|
|
867
|
-
});
|
|
868
|
-
this.retireNotRequiredExpectedPeer(received.sourceRid);
|
|
869
|
-
}
|
|
816
|
+
decodeReject(received.parts[0]!);
|
|
870
817
|
return 'infrastructure';
|
|
871
818
|
}
|
|
872
819
|
const peer = this.topology.peer(received.sourceRid);
|
|
@@ -997,6 +944,14 @@ export class RawServiceMeshRuntime {
|
|
|
997
944
|
}
|
|
998
945
|
}
|
|
999
946
|
|
|
947
|
+
expireOperations(nowMs: number, turnDeadlineMs: number): number {
|
|
948
|
+
return this.operations.expire(nowMs, turnDeadlineMs);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
get pendingOperationCount(): number {
|
|
952
|
+
return this.operations.size;
|
|
953
|
+
}
|
|
954
|
+
|
|
1000
955
|
async tickLiveness(nowMs = performance.now()): Promise<ServiceLivenessTick> {
|
|
1001
956
|
const result = this.liveness.tick(nowMs);
|
|
1002
957
|
this.requireStarted();
|
|
@@ -1011,130 +966,50 @@ export class RawServiceMeshRuntime {
|
|
|
1011
966
|
for (const nodeRoutingId of result.timedOutNodes) {
|
|
1012
967
|
const peer = this.topology.peer(nodeRoutingId);
|
|
1013
968
|
if (peer === undefined) continue;
|
|
1014
|
-
// Liveness timeout is a semantic peer removal.
|
|
1015
|
-
// physical candidate state, and auto-connect intent must be retired by
|
|
1016
|
-
// the same owner so a failed endpoint cannot be selected again.
|
|
1017
|
-
this.removeConnectionCandidate(nodeRoutingId, peer.connectionId);
|
|
969
|
+
// Liveness timeout is a semantic peer removal of the admitted route.
|
|
1018
970
|
this.removePeer(peer);
|
|
1019
971
|
}
|
|
1020
972
|
return result;
|
|
1021
973
|
}
|
|
1022
974
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
this.
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
this.unresolvedConnectionCandidates.push(candidate);
|
|
1046
|
-
}
|
|
1047
|
-
continue;
|
|
1048
|
-
}
|
|
1049
|
-
if (!this.acceptsExpectedMonitorEndpoint(nodeRoutingId, event)) {
|
|
1050
|
-
continue;
|
|
1051
|
-
}
|
|
1052
|
-
const candidate = this.createConnectionCandidate(nodeRoutingId, event);
|
|
1053
|
-
const existingPeer = this.topology.peer(nodeRoutingId);
|
|
1054
|
-
if (existingPeer !== undefined && existingPeer.connectionId === candidate.connectionId) {
|
|
1055
|
-
this.monitorConnectionStates.set(nodeRoutingId, candidate.connectionId);
|
|
1056
|
-
continue;
|
|
1057
|
-
}
|
|
1058
|
-
if (existingPeer !== undefined) {
|
|
1059
|
-
if (this.liveness.isReady(nodeRoutingId, existingPeer.connectionId)) {
|
|
1060
|
-
const existingCandidate = this.connectionCandidates
|
|
1061
|
-
.get(nodeRoutingId)
|
|
1062
|
-
?.get(existingPeer.connectionId);
|
|
1063
|
-
if (this.isDiscoveredLifecycleReplacement(existingPeer, nodeRoutingId)) {
|
|
1064
|
-
// A current discovery descriptor with the same RID but a
|
|
1065
|
-
// different lifecycle token denotes a replacement process.
|
|
1066
|
-
// Keep its physical pair provisional until its Hello passes
|
|
1067
|
-
// the descriptor fence; the old ready peer remains semantic
|
|
1068
|
-
// current until then.
|
|
1069
|
-
let provisionalCandidates = this.connectionCandidates.get(nodeRoutingId);
|
|
1070
|
-
if (provisionalCandidates === undefined) {
|
|
1071
|
-
provisionalCandidates = new Map();
|
|
1072
|
-
this.connectionCandidates.set(nodeRoutingId, provisionalCandidates);
|
|
1073
|
-
}
|
|
1074
|
-
provisionalCandidates.set(candidate.connectionId, candidate);
|
|
1075
|
-
await this.announcePeer(nodeRoutingId);
|
|
1076
|
-
continue;
|
|
1077
|
-
}
|
|
1078
|
-
if (existingCandidate?.connectionId === candidate.connectionId) {
|
|
1079
|
-
this.removeConnectionCandidate(nodeRoutingId, candidate.connectionId);
|
|
1080
|
-
this.monitorConnectionStates.set(nodeRoutingId, existingPeer.connectionId);
|
|
1081
|
-
continue;
|
|
1082
|
-
}
|
|
1083
|
-
// A non-replacement ready route is the current semantic owner.
|
|
1084
|
-
// A second physical candidate may be admitted only after the
|
|
1085
|
-
// current lease expires; this also prevents a late old-process
|
|
1086
|
-
// reconnect from replacing the ready replacement by arrival order.
|
|
1087
|
-
this.removeConnectionCandidate(nodeRoutingId, candidate.connectionId);
|
|
1088
|
-
continue;
|
|
1089
|
-
}
|
|
1090
|
-
// Keep the physical candidate until the wire descriptor decides
|
|
1091
|
-
// whether it is the current logical peer. READY events can race
|
|
1092
|
-
// with DISCONNECTED events during reconnect; rejecting the READY
|
|
1093
|
-
// here can terminate the replacement before admission evaluates its
|
|
1094
|
-
// lifecycle generation.
|
|
1095
|
-
let provisionalCandidates = this.connectionCandidates.get(nodeRoutingId);
|
|
1096
|
-
if (provisionalCandidates === undefined) {
|
|
1097
|
-
provisionalCandidates = new Map();
|
|
1098
|
-
this.connectionCandidates.set(nodeRoutingId, provisionalCandidates);
|
|
1099
|
-
}
|
|
1100
|
-
provisionalCandidates.set(candidate.connectionId, candidate);
|
|
1101
|
-
this.connectionIds.set(nodeRoutingId, candidate.connectionId);
|
|
1102
|
-
await this.announcePeer(nodeRoutingId);
|
|
1103
|
-
continue;
|
|
1104
|
-
}
|
|
1105
|
-
let candidates = this.connectionCandidates.get(nodeRoutingId);
|
|
1106
|
-
if (candidates === undefined) {
|
|
1107
|
-
candidates = new Map();
|
|
1108
|
-
this.connectionCandidates.set(nodeRoutingId, candidates);
|
|
1109
|
-
}
|
|
1110
|
-
candidates.set(candidate.connectionId, candidate);
|
|
1111
|
-
// Before wire admission the monitor candidate is the only physical
|
|
1112
|
-
// route evidence available to the admission message.
|
|
1113
|
-
this.connectionIds.set(nodeRoutingId, candidate.connectionId);
|
|
1114
|
-
await this.announcePeer(nodeRoutingId);
|
|
1115
|
-
} else if (event.event === MONITOR_DISCONNECTED && nodeRoutingId !== undefined) {
|
|
1116
|
-
const peer = this.topology.peer(nodeRoutingId);
|
|
1117
|
-
const disconnectedId = monitorConnectionId(event, nodeRoutingId);
|
|
1118
|
-
this.removeConnectionCandidate(nodeRoutingId, disconnectedId);
|
|
1119
|
-
if (peer !== undefined && peer.connectionId === disconnectedId) {
|
|
1120
|
-
this.removePeer(peer);
|
|
1121
|
-
}
|
|
1122
|
-
} else if (event.event === MONITOR_DISCONNECTED) {
|
|
1123
|
-
const disconnectedId = monitorConnectionId(event);
|
|
1124
|
-
const index = this.unresolvedConnectionCandidates.findIndex(
|
|
1125
|
-
(candidate) => candidate.connectionId === disconnectedId
|
|
1126
|
-
);
|
|
1127
|
-
if (index >= 0) this.unresolvedConnectionCandidates.splice(index, 1);
|
|
975
|
+
/**
|
|
976
|
+
* The socket's one route observer (Core ROUTER §10.1). It replaces the
|
|
977
|
+
* observation with Core's selected-route snapshot, ends the admission of
|
|
978
|
+
* every RID whose observed route disappeared or was replaced, and starts the
|
|
979
|
+
* handshake of every newly selected route. Returns the number of changes.
|
|
980
|
+
*/
|
|
981
|
+
async observeSelectedRoutes(): Promise<number> {
|
|
982
|
+
const router = this.router;
|
|
983
|
+
if (router === undefined || this.closed) return 0;
|
|
984
|
+
const observed = new Map<string, bigint>();
|
|
985
|
+
for (const route of router.routesSnapshot()) {
|
|
986
|
+
observed.set(route.routingId, route.routeGeneration);
|
|
987
|
+
}
|
|
988
|
+
let changes = 0;
|
|
989
|
+
for (const [nodeRoutingId, generation] of this.selectedRoutes) {
|
|
990
|
+
if (observed.get(nodeRoutingId) === generation) continue;
|
|
991
|
+
changes++;
|
|
992
|
+
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
993
|
+
if (expected !== undefined) delete expected.helloSubmittedGeneration;
|
|
994
|
+
const peer = this.topology.peer(nodeRoutingId);
|
|
995
|
+
if (peer !== undefined && peer.connectionId === routeConnectionId(generation)) {
|
|
996
|
+
this.removePeer(peer);
|
|
1128
997
|
}
|
|
1129
998
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
999
|
+
const selected: string[] = [];
|
|
1000
|
+
for (const [nodeRoutingId, generation] of observed) {
|
|
1001
|
+
if (this.selectedRoutes.get(nodeRoutingId) === generation) continue;
|
|
1002
|
+
if (!this.selectedRoutes.has(nodeRoutingId)) changes++;
|
|
1003
|
+
selected.push(nodeRoutingId);
|
|
1004
|
+
}
|
|
1005
|
+
this.selectedRoutes = observed;
|
|
1006
|
+
// A new selected route admits only through a new handshake.
|
|
1007
|
+
for (const nodeRoutingId of selected) await this.announcePeer(nodeRoutingId);
|
|
1008
|
+
return changes;
|
|
1133
1009
|
}
|
|
1134
1010
|
|
|
1135
1011
|
close(): void {
|
|
1136
1012
|
if (this.closed) return;
|
|
1137
|
-
this.closed = true;
|
|
1138
1013
|
this.applicationJobStop.abort(
|
|
1139
1014
|
new Error('Raw service runtime application job admission stopped.')
|
|
1140
1015
|
);
|
|
@@ -1145,12 +1020,11 @@ export class RawServiceMeshRuntime {
|
|
|
1145
1020
|
if (router !== undefined) {
|
|
1146
1021
|
this.applicationJobQueue.unregisterReceiveFlowTarget?.(router);
|
|
1147
1022
|
}
|
|
1148
|
-
this.monitor?.close();
|
|
1149
|
-
this.monitor = undefined;
|
|
1150
1023
|
const host = this.host;
|
|
1024
|
+
if (host !== undefined) host.close();
|
|
1151
1025
|
this.router = undefined;
|
|
1152
1026
|
this.host = undefined;
|
|
1153
|
-
|
|
1027
|
+
this.closed = true;
|
|
1154
1028
|
}
|
|
1155
1029
|
|
|
1156
1030
|
private requestToTarget(
|
|
@@ -1181,14 +1055,11 @@ export class RawServiceMeshRuntime {
|
|
|
1181
1055
|
for (;;) {
|
|
1182
1056
|
const alternate = this.topology.selectChannel(channelName, (peer) => {
|
|
1183
1057
|
const candidate = peer.descriptor.nodeRoutingId;
|
|
1184
|
-
return !excludedTargets.has(candidate) && this.
|
|
1058
|
+
return !excludedTargets.has(candidate) && this.isPeerRouteReady(candidate);
|
|
1185
1059
|
});
|
|
1186
1060
|
if (alternate === undefined) break;
|
|
1187
1061
|
selectedTargetNodeRoutingId = alternate.descriptor.nodeRoutingId;
|
|
1188
|
-
if (
|
|
1189
|
-
selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId ||
|
|
1190
|
-
this.isPeerRouteReady(selectedTargetNodeRoutingId)
|
|
1191
|
-
) {
|
|
1062
|
+
if (this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
|
|
1192
1063
|
break;
|
|
1193
1064
|
}
|
|
1194
1065
|
excludedTargets.add(selectedTargetNodeRoutingId);
|
|
@@ -1212,10 +1083,7 @@ export class RawServiceMeshRuntime {
|
|
|
1212
1083
|
return;
|
|
1213
1084
|
}
|
|
1214
1085
|
const accepted = this.mailbox.tryEnqueue({
|
|
1215
|
-
owner:
|
|
1216
|
-
channelName === undefined
|
|
1217
|
-
? `node:${this.descriptor.nodeRoutingId}`
|
|
1218
|
-
: `channel:${channelName}`,
|
|
1086
|
+
owner: `node:${this.descriptor.nodeRoutingId}`,
|
|
1219
1087
|
domain: 'application',
|
|
1220
1088
|
parts,
|
|
1221
1089
|
sourceRoutingId: this.descriptor.nodeRoutingId,
|
|
@@ -1241,17 +1109,13 @@ export class RawServiceMeshRuntime {
|
|
|
1241
1109
|
})().catch((error) => this.operations.fail(pending.id, error));
|
|
1242
1110
|
return pending;
|
|
1243
1111
|
}
|
|
1244
|
-
if (
|
|
1245
|
-
//
|
|
1246
|
-
//
|
|
1247
|
-
//
|
|
1248
|
-
// as RequestTargetNotFound without submitting an application frame.
|
|
1249
|
-
const knownTarget =
|
|
1250
|
-
this.topology.peer(selectedTargetNodeRoutingId) !== undefined ||
|
|
1251
|
-
this.topology.knownDescriptor(selectedTargetNodeRoutingId) !== undefined;
|
|
1112
|
+
if (this.topology.peer(selectedTargetNodeRoutingId) === undefined) {
|
|
1113
|
+
// Logical target selection is the requester's decision: an RID that is
|
|
1114
|
+
// not an admitted peer is not a target. Whether an admitted target's
|
|
1115
|
+
// route can carry the request is Core's REQUEST result.
|
|
1252
1116
|
this.operations.complete(pending.id, {
|
|
1253
|
-
terminalResult:
|
|
1254
|
-
failureCode:
|
|
1117
|
+
terminalResult: RequestResult.NotFound,
|
|
1118
|
+
failureCode: REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
|
|
1255
1119
|
});
|
|
1256
1120
|
return pending;
|
|
1257
1121
|
}
|
|
@@ -1320,7 +1184,7 @@ export class RawServiceMeshRuntime {
|
|
|
1320
1184
|
|
|
1321
1185
|
private admitPeer(
|
|
1322
1186
|
descriptor: ServiceNodeDescriptor,
|
|
1323
|
-
|
|
1187
|
+
connectionId: string,
|
|
1324
1188
|
nowMs: number,
|
|
1325
1189
|
expected?: {
|
|
1326
1190
|
readonly endpoint?: string;
|
|
@@ -1340,232 +1204,16 @@ export class RawServiceMeshRuntime {
|
|
|
1340
1204
|
`RouteMesh peer '${descriptor.nodeRoutingId}' descriptor revision is stale or conflicting.`
|
|
1341
1205
|
);
|
|
1342
1206
|
}
|
|
1343
|
-
const result = this.topology.admit(
|
|
1344
|
-
descriptor,
|
|
1345
|
-
connection.connectionId,
|
|
1346
|
-
expected,
|
|
1347
|
-
connection.discriminator
|
|
1348
|
-
);
|
|
1207
|
+
const result = this.topology.admit(descriptor, connectionId, expected);
|
|
1349
1208
|
if (result === 'admitted') {
|
|
1350
|
-
this.
|
|
1351
|
-
this.liveness.
|
|
1352
|
-
this.liveness.requestProbe(descriptor.nodeRoutingId, connection.connectionId, nowMs);
|
|
1353
|
-
this.monitorConnectionStates.set(descriptor.nodeRoutingId, connection.connectionId);
|
|
1354
|
-
if (previous !== undefined && previous.connectionId !== connection.connectionId) {
|
|
1355
|
-
const previousCandidate = this.connectionCandidates
|
|
1356
|
-
.get(descriptor.nodeRoutingId)
|
|
1357
|
-
?.get(previous.connectionId);
|
|
1358
|
-
if (previousCandidate !== undefined) {
|
|
1359
|
-
this.removeConnectionCandidate(descriptor.nodeRoutingId, previousCandidate.connectionId);
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1209
|
+
this.liveness.admit(descriptor.nodeRoutingId, connectionId, nowMs);
|
|
1210
|
+
this.liveness.requestProbe(descriptor.nodeRoutingId, connectionId, nowMs);
|
|
1362
1211
|
} else if (result === 'notRequired' && previous !== undefined) {
|
|
1363
1212
|
this.liveness.disconnect(descriptor.nodeRoutingId, previous.connectionId);
|
|
1364
|
-
} else if (previous !== undefined) {
|
|
1365
|
-
this.connectionIds.set(descriptor.nodeRoutingId, previous.connectionId);
|
|
1366
|
-
if (connection.connectionId !== previous.connectionId) {
|
|
1367
|
-
this.removeConnectionCandidate(descriptor.nodeRoutingId, connection.connectionId);
|
|
1368
|
-
}
|
|
1369
1213
|
}
|
|
1370
1214
|
return result;
|
|
1371
1215
|
}
|
|
1372
1216
|
|
|
1373
|
-
private currentConnectionCandidate(
|
|
1374
|
-
nodeRoutingId: string,
|
|
1375
|
-
advertisedEndpoint: string
|
|
1376
|
-
): PhysicalConnectionCandidate {
|
|
1377
|
-
let connectionId = this.connectionIds.get(nodeRoutingId);
|
|
1378
|
-
let candidate =
|
|
1379
|
-
connectionId === undefined
|
|
1380
|
-
? undefined
|
|
1381
|
-
: this.connectionCandidates.get(nodeRoutingId)?.get(connectionId);
|
|
1382
|
-
if (candidate === undefined) {
|
|
1383
|
-
candidate = this.promoteUnresolvedConnectionCandidate(nodeRoutingId, advertisedEndpoint);
|
|
1384
|
-
connectionId = candidate?.connectionId;
|
|
1385
|
-
}
|
|
1386
|
-
if (candidate === undefined) {
|
|
1387
|
-
const localRid = this.topology.localDescriptor().nodeRoutingId;
|
|
1388
|
-
const endpointOnly = this.endpointOnlyPeers.has(advertisedEndpoint);
|
|
1389
|
-
const direction: PhysicalConnectionDirection = this.expectedPeers.has(nodeRoutingId)
|
|
1390
|
-
? 'outbound'
|
|
1391
|
-
: endpointOnly
|
|
1392
|
-
? localRid.localeCompare(nodeRoutingId) <= 0
|
|
1393
|
-
? 'outbound'
|
|
1394
|
-
: 'inbound'
|
|
1395
|
-
: 'inbound';
|
|
1396
|
-
const initiator =
|
|
1397
|
-
endpointOnly && localRid.localeCompare(nodeRoutingId) > 0
|
|
1398
|
-
? nodeRoutingId
|
|
1399
|
-
: direction === 'outbound'
|
|
1400
|
-
? localRid
|
|
1401
|
-
: nodeRoutingId;
|
|
1402
|
-
connectionId = `unmonitored:${direction}:${randomUUID()}`;
|
|
1403
|
-
candidate = {
|
|
1404
|
-
connectionId,
|
|
1405
|
-
direction,
|
|
1406
|
-
discriminator: `initiator:${initiator}`,
|
|
1407
|
-
localAddress: '',
|
|
1408
|
-
remoteAddress: advertisedEndpoint
|
|
1409
|
-
};
|
|
1410
|
-
let candidates = this.connectionCandidates.get(nodeRoutingId);
|
|
1411
|
-
if (candidates === undefined) {
|
|
1412
|
-
candidates = new Map();
|
|
1413
|
-
this.connectionCandidates.set(nodeRoutingId, candidates);
|
|
1414
|
-
}
|
|
1415
|
-
candidates.set(connectionId, candidate);
|
|
1416
|
-
this.connectionIds.set(nodeRoutingId, connectionId);
|
|
1417
|
-
}
|
|
1418
|
-
return candidate;
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
private createConnectionCandidate(
|
|
1422
|
-
nodeRoutingId: string,
|
|
1423
|
-
event: ZLinkRawMonitorRecord
|
|
1424
|
-
): PhysicalConnectionCandidate {
|
|
1425
|
-
const local = this.topology.localDescriptor();
|
|
1426
|
-
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
1427
|
-
const direction: PhysicalConnectionDirection =
|
|
1428
|
-
event.localAddress === local.advertisedEndpoint
|
|
1429
|
-
? 'inbound'
|
|
1430
|
-
: expected?.endpoint === event.remoteAddress
|
|
1431
|
-
? 'outbound'
|
|
1432
|
-
: this.endpointOnlyPeers.has(event.remoteAddress)
|
|
1433
|
-
? 'outbound'
|
|
1434
|
-
: 'unknown';
|
|
1435
|
-
const initiator =
|
|
1436
|
-
direction === 'outbound'
|
|
1437
|
-
? local.nodeRoutingId
|
|
1438
|
-
: direction === 'inbound'
|
|
1439
|
-
? nodeRoutingId
|
|
1440
|
-
: undefined;
|
|
1441
|
-
return {
|
|
1442
|
-
connectionId: monitorConnectionId(event, nodeRoutingId),
|
|
1443
|
-
direction,
|
|
1444
|
-
discriminator:
|
|
1445
|
-
initiator === undefined
|
|
1446
|
-
? `unknown:${monitorConnectionId(event, nodeRoutingId)}`
|
|
1447
|
-
: `initiator:${initiator}`,
|
|
1448
|
-
localAddress: event.localAddress,
|
|
1449
|
-
remoteAddress: event.remoteAddress
|
|
1450
|
-
};
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
private createUnresolvedConnectionCandidate(
|
|
1454
|
-
event: ZLinkRawMonitorRecord
|
|
1455
|
-
): PhysicalConnectionCandidate {
|
|
1456
|
-
const connectionId = monitorConnectionId(event);
|
|
1457
|
-
const local = this.topology.localDescriptor();
|
|
1458
|
-
const direction: PhysicalConnectionDirection =
|
|
1459
|
-
this.endpointOnlyPeers.has(event.remoteAddress) ||
|
|
1460
|
-
this.expectedPeerRoutingId(event.remoteAddress) !== undefined
|
|
1461
|
-
? 'outbound'
|
|
1462
|
-
: event.localAddress === local.advertisedEndpoint
|
|
1463
|
-
? 'inbound'
|
|
1464
|
-
: 'unknown';
|
|
1465
|
-
return {
|
|
1466
|
-
connectionId,
|
|
1467
|
-
direction,
|
|
1468
|
-
discriminator: `unresolved:${connectionId}`,
|
|
1469
|
-
localAddress: event.localAddress,
|
|
1470
|
-
remoteAddress: event.remoteAddress
|
|
1471
|
-
};
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
private promoteUnresolvedConnectionCandidate(
|
|
1475
|
-
nodeRoutingId: string,
|
|
1476
|
-
advertisedEndpoint: string
|
|
1477
|
-
): PhysicalConnectionCandidate | undefined {
|
|
1478
|
-
const relevant = this.unresolvedConnectionCandidates
|
|
1479
|
-
.map((candidate, index) => ({ candidate, index }))
|
|
1480
|
-
.filter(
|
|
1481
|
-
({ candidate }) =>
|
|
1482
|
-
candidate.remoteAddress === advertisedEndpoint || candidate.direction === 'inbound'
|
|
1483
|
-
);
|
|
1484
|
-
if (relevant.length === 0) return undefined;
|
|
1485
|
-
const directions = new Set(relevant.map((value) => value.candidate.direction));
|
|
1486
|
-
const localRid = this.topology.localDescriptor().nodeRoutingId;
|
|
1487
|
-
const preferredDirection: PhysicalConnectionDirection =
|
|
1488
|
-
directions.has('inbound') && directions.has('outbound')
|
|
1489
|
-
? localRid.localeCompare(nodeRoutingId) <= 0
|
|
1490
|
-
? 'outbound'
|
|
1491
|
-
: 'inbound'
|
|
1492
|
-
: relevant.at(-1)!.candidate.direction;
|
|
1493
|
-
const selected =
|
|
1494
|
-
[...relevant].reverse().find((value) => value.candidate.direction === preferredDirection) ??
|
|
1495
|
-
relevant.at(-1)!;
|
|
1496
|
-
this.unresolvedConnectionCandidates.splice(selected.index, 1);
|
|
1497
|
-
const initiator =
|
|
1498
|
-
selected.candidate.direction === 'outbound'
|
|
1499
|
-
? localRid
|
|
1500
|
-
: selected.candidate.direction === 'inbound'
|
|
1501
|
-
? nodeRoutingId
|
|
1502
|
-
: undefined;
|
|
1503
|
-
const candidate: PhysicalConnectionCandidate = {
|
|
1504
|
-
...selected.candidate,
|
|
1505
|
-
discriminator:
|
|
1506
|
-
initiator === undefined
|
|
1507
|
-
? `unknown:${selected.candidate.connectionId}`
|
|
1508
|
-
: `initiator:${initiator}`
|
|
1509
|
-
};
|
|
1510
|
-
let candidates = this.connectionCandidates.get(nodeRoutingId);
|
|
1511
|
-
if (candidates === undefined) {
|
|
1512
|
-
candidates = new Map();
|
|
1513
|
-
this.connectionCandidates.set(nodeRoutingId, candidates);
|
|
1514
|
-
}
|
|
1515
|
-
candidates.set(candidate.connectionId, candidate);
|
|
1516
|
-
this.connectionIds.set(nodeRoutingId, candidate.connectionId);
|
|
1517
|
-
return candidate;
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
private removeConnectionCandidate(nodeRoutingId: string, connectionId: string): void {
|
|
1521
|
-
const candidates = this.connectionCandidates.get(nodeRoutingId);
|
|
1522
|
-
candidates?.delete(connectionId);
|
|
1523
|
-
if (candidates?.size === 0) this.connectionCandidates.delete(nodeRoutingId);
|
|
1524
|
-
if (this.connectionIds.get(nodeRoutingId) === connectionId) {
|
|
1525
|
-
this.connectionIds.delete(nodeRoutingId);
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
|
|
1529
|
-
private isDiscoveredLifecycleReplacement(
|
|
1530
|
-
admitted: AdmittedServicePeer,
|
|
1531
|
-
nodeRoutingId: string
|
|
1532
|
-
): boolean {
|
|
1533
|
-
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
1534
|
-
// A same-RID replacement is permitted only from a complete discovery
|
|
1535
|
-
// fence. Manual/endpoint-only intent has no authority to replace a ready
|
|
1536
|
-
// peer, and lifecycle generations are opaque equality tokens.
|
|
1537
|
-
return (
|
|
1538
|
-
expected?.endpoint !== undefined &&
|
|
1539
|
-
expected.securityIdentity !== undefined &&
|
|
1540
|
-
expected.lifecycleGeneration !== undefined &&
|
|
1541
|
-
admitted.descriptor.lifecycleGeneration !== expected.lifecycleGeneration
|
|
1542
|
-
);
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
private expectedPeerRoutingId(endpoint: string): string | undefined {
|
|
1546
|
-
for (const [nodeRoutingId, expected] of this.expectedPeers) {
|
|
1547
|
-
if (expected.endpoint === endpoint) return nodeRoutingId;
|
|
1548
|
-
}
|
|
1549
|
-
return undefined;
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1552
|
-
private acceptsExpectedMonitorEndpoint(
|
|
1553
|
-
nodeRoutingId: string,
|
|
1554
|
-
event: Pick<ZLinkRawMonitorRecord, 'remoteAddress' | 'routingId'>
|
|
1555
|
-
): boolean {
|
|
1556
|
-
// A monitor address is the physical socket address, which may be an
|
|
1557
|
-
// ephemeral port. Once Core has resolved the peer routing ID, that ID is
|
|
1558
|
-
// the semantic identity; comparing the physical address with the
|
|
1559
|
-
// discovery advertised endpoint would reject valid READY events.
|
|
1560
|
-
if (event.routingId === nodeRoutingId) return true;
|
|
1561
|
-
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
1562
|
-
return (
|
|
1563
|
-
expected === undefined ||
|
|
1564
|
-
expected.endpoint === undefined ||
|
|
1565
|
-
expected.endpoint === event.remoteAddress
|
|
1566
|
-
);
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
1217
|
private retireNotRequiredExpectedPeer(nodeRoutingId: string, advertisedEndpoint?: string): void {
|
|
1570
1218
|
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
1571
1219
|
const endpoint =
|
|
@@ -1597,9 +1245,6 @@ export class RawServiceMeshRuntime {
|
|
|
1597
1245
|
}
|
|
1598
1246
|
|
|
1599
1247
|
private removePeer(peer: AdmittedServicePeer): void {
|
|
1600
|
-
if (this.monitorConnectionStates.get(peer.descriptor.nodeRoutingId) === peer.connectionId) {
|
|
1601
|
-
this.monitorConnectionStates.set(peer.descriptor.nodeRoutingId, null);
|
|
1602
|
-
}
|
|
1603
1248
|
this.topology.disconnect(peer.descriptor.nodeRoutingId, peer.connectionId);
|
|
1604
1249
|
this.liveness.disconnect(peer.descriptor.nodeRoutingId, peer.connectionId);
|
|
1605
1250
|
this.onPeerDisconnected?.(
|
|
@@ -1609,25 +1254,6 @@ export class RawServiceMeshRuntime {
|
|
|
1609
1254
|
);
|
|
1610
1255
|
}
|
|
1611
1256
|
|
|
1612
|
-
private observeMonitorEvent(event: ZLinkRawMonitorRecord): void {
|
|
1613
|
-
const nodeRoutingId = event.routingId ?? this.expectedPeerRoutingId(event.remoteAddress);
|
|
1614
|
-
if (nodeRoutingId === undefined) return;
|
|
1615
|
-
const connectionId = monitorConnectionId(event, nodeRoutingId);
|
|
1616
|
-
if (event.event === MONITOR_CONNECTION_READY && isConnectionReadyEdge(event)) {
|
|
1617
|
-
if (!this.acceptsExpectedMonitorEndpoint(nodeRoutingId, event)) return;
|
|
1618
|
-
// The event is queued for admission. Updating monitor state here would
|
|
1619
|
-
// allow a late stale READY to overwrite the admitted replacement.
|
|
1620
|
-
return;
|
|
1621
|
-
}
|
|
1622
|
-
if (
|
|
1623
|
-
event.event === MONITOR_DISCONNECTED &&
|
|
1624
|
-
this.monitorConnectionStates.get(nodeRoutingId) === connectionId &&
|
|
1625
|
-
this.topology.peer(nodeRoutingId)?.connectionId === connectionId
|
|
1626
|
-
) {
|
|
1627
|
-
this.monitorConnectionStates.set(nodeRoutingId, null);
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
1257
|
private requireStarted(): ZLinkRawRouterPort {
|
|
1632
1258
|
if (this.router === undefined) throw new Error('Raw service runtime is not started.');
|
|
1633
1259
|
return this.router;
|
|
@@ -1677,38 +1303,15 @@ function isAlreadyDisconnectedError(error: unknown): boolean {
|
|
|
1677
1303
|
if (typeof error !== 'object' || error === null || !('nativeErrno' in error)) {
|
|
1678
1304
|
return false;
|
|
1679
1305
|
}
|
|
1680
|
-
return (error as { readonly nativeErrno?: unknown }).nativeErrno ===
|
|
1681
|
-
}
|
|
1682
|
-
|
|
1683
|
-
function monitorConnectionId(
|
|
1684
|
-
event: ZLinkRawMonitorRecord,
|
|
1685
|
-
resolvedNodeRoutingId = event.routingId ?? ''
|
|
1686
|
-
): string {
|
|
1687
|
-
if (event.connectionId !== undefined && event.connectionId !== 0n) {
|
|
1688
|
-
return JSON.stringify([resolvedNodeRoutingId, 'connection', event.connectionId.toString()]);
|
|
1689
|
-
}
|
|
1690
|
-
return JSON.stringify([
|
|
1691
|
-
// Monitor `value` is event-specific: CONNECTION_READY reports the
|
|
1692
|
-
// socket's ready count and DISCONNECTED reports its reason. It is not a
|
|
1693
|
-
// connection identity. The public monitor record has no native
|
|
1694
|
-
// connection id, so use the stable routing and endpoint tuple instead.
|
|
1695
|
-
resolvedNodeRoutingId,
|
|
1696
|
-
event.localAddress,
|
|
1697
|
-
event.remoteAddress
|
|
1698
|
-
]);
|
|
1306
|
+
return (error as { readonly nativeErrno?: unknown }).nativeErrno === nativeErrnoValues.ENOENT;
|
|
1699
1307
|
}
|
|
1700
1308
|
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
function isConnectionReadyEdge(event: ZLinkRawMonitorRecord): boolean {
|
|
1709
|
-
return event.flags === undefined
|
|
1710
|
-
? event.value > 0n
|
|
1711
|
-
: (event.flags & MONITOR_CONNECTION_READY_EDGE) !== 0;
|
|
1309
|
+
/**
|
|
1310
|
+
* An admission belongs to one Core selected route. Its connection identity is
|
|
1311
|
+
* that route's generation, an opaque token compared only for equality.
|
|
1312
|
+
*/
|
|
1313
|
+
function routeConnectionId(routeGeneration: bigint): string {
|
|
1314
|
+
return `route:${routeGeneration.toString()}`;
|
|
1712
1315
|
}
|
|
1713
1316
|
|
|
1714
1317
|
function describeInvalidAdmissionDescriptor(
|
|
@@ -1778,17 +1381,13 @@ function immutableDescriptorMismatch(
|
|
|
1778
1381
|
return undefined;
|
|
1779
1382
|
}
|
|
1780
1383
|
|
|
1781
|
-
function admissionReason(result: PeerAdmissionResult): number {
|
|
1384
|
+
function admissionReason(result: Exclude<PeerAdmissionResult, 'admitted' | 'notRequired'>): number {
|
|
1782
1385
|
switch (result) {
|
|
1783
1386
|
case 'meshMismatch':
|
|
1784
|
-
return
|
|
1387
|
+
return enumWireRejectReason('topologyMismatch');
|
|
1785
1388
|
case 'staleDescriptor':
|
|
1786
|
-
return
|
|
1389
|
+
return enumWireRejectReason('descriptorRevisionStale');
|
|
1787
1390
|
case 'invalidDescriptor':
|
|
1788
|
-
return
|
|
1789
|
-
case 'notRequired':
|
|
1790
|
-
return 4;
|
|
1791
|
-
case 'admitted':
|
|
1792
|
-
return 1;
|
|
1391
|
+
return enumWireRejectReason('invalidDescriptor');
|
|
1793
1392
|
}
|
|
1794
1393
|
}
|