@zlink-systems/framework 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkMessage.js +5 -5
- package/dist/contracts/Configuration/CodecContentType.js +5 -7
- package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
- package/dist/contracts/Configuration/EndpointNotation.js +4 -8
- package/dist/contracts/Configuration/Registration.js +14 -11
- package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
- package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
- package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
- package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
- package/dist/location-store-integration.js +16 -16
- package/dist/nest-integration.js +17 -11
- package/dist/runtime/abort.js +9 -5
- package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
- package/dist/runtime/actors/actor-authority-publication.js +18 -17
- package/dist/runtime/actors/actor-client.js +83 -63
- package/dist/runtime/actors/actor-context.js +28 -22
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
- package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
- package/dist/runtime/actors/actor-local-native-join.js +18 -19
- package/dist/runtime/actors/actor-mailbox.js +1 -1
- package/dist/runtime/actors/actor-message-follow-context.js +24 -21
- package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
- package/dist/runtime/actors/actor-remote-joiner.js +20 -17
- package/dist/runtime/actors/actor-remote-wire.js +6 -7
- package/dist/runtime/actors/actor-runtime-state.js +87 -81
- package/dist/runtime/actors/actor-transfer-registry.js +3 -5
- package/dist/runtime/actors/bound-session-wire.js +14 -9
- package/dist/runtime/actors/deferred-join-accepted-journal.js +160 -130
- package/dist/runtime/actors/index.js +2 -5
- package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
- package/dist/runtime/actors/post-commit-actor-location.js +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
- package/dist/runtime/admission.js +2 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
- package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
- package/dist/runtime/backend/contracts/index.d.ts +1 -0
- package/dist/runtime/backend/mesh-completion-table.js +1 -3
- package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
- package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +3 -0
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +134 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
- package/dist/runtime/backend/runtime-message.js +3 -3
- package/dist/runtime/backend/runtime-values.d.ts +2 -2
- package/dist/runtime/backend/runtime-values.js +4 -5
- package/dist/runtime/channels/channel-clients.js +27 -24
- package/dist/runtime/channels/channel-dispatch-pipeline.js +12 -20
- package/dist/runtime/channels/channel-dispatch-services.js +7 -4
- package/dist/runtime/channels/channel-dispatchers.js +9 -9
- package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
- package/dist/runtime/channels/channel-envelope.js +83 -47
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-receive-loops.js +20 -22
- package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
- package/dist/runtime/channels/channel-runtime-manager.js +18 -9
- package/dist/runtime/channels/channel-socket-registry.js +126 -123
- package/dist/runtime/channels/channel-transports.js +46 -42
- package/dist/runtime/channels/client-server-location-runtime.js +32 -40
- package/dist/runtime/channels/client-server-service-wire.js +29 -22
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -0
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -39
- package/dist/runtime/channels/fanout-location-runtime.js +34 -47
- package/dist/runtime/channels/fanout-service-wire.js +3 -5
- package/dist/runtime/channels/local-spot-route-transport.js +7 -1
- package/dist/runtime/channels/route-member-snapshot.js +3 -3
- package/dist/runtime/channels/source-spot-router.js +6 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
- package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +6 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
- package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
- package/dist/runtime/diagnostics/flow-context.js +2 -2
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +58 -42
- package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
- package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
- package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
- package/dist/runtime/execution/index.js +7 -6
- package/dist/runtime/execution/serial-execution-queue.js +12 -18
- package/dist/runtime/execution/state-lane.js +2 -2
- package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -27
- package/dist/runtime/foundation/event-loop-resources.js +4 -4
- package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +4 -2
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +169 -144
- package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
- package/dist/runtime/foundation/runtime-state-projections.js +22 -11
- package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
- package/dist/runtime/foundation/service-discovery-registry.js +35 -33
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
- package/dist/runtime/foundation/service-liveness-registry.js +16 -12
- package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
- package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
- package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +1 -0
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -0
- package/dist/runtime/foundation/service-stateful-runtime.js +461 -439
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
- package/dist/runtime/foundation/service-topology-registry.js +105 -96
- package/dist/runtime/foundation/service-weighted-selection.js +6 -11
- package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
- package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
- package/dist/runtime/framework-errors-internal.js +7 -10
- package/dist/runtime/handlers/handler-instance-scope.js +4 -5
- package/dist/runtime/handlers/index.js +3 -1
- package/dist/runtime/host/actor-packet-relay.js +74 -70
- package/dist/runtime/host/actor-placement-coordinator.js +29 -31
- package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
- package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
- package/dist/runtime/host/actor-transfer-runtime.js +176 -153
- package/dist/runtime/host/application-job-queue.js +18 -22
- package/dist/runtime/host/bound-session-relay.js +3 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
- package/dist/runtime/host/host-capacity-status.js +8 -4
- package/dist/runtime/host/index.js +245 -228
- package/dist/runtime/host/instance-activation-authority.js +93 -96
- package/dist/runtime/host/location-runtime-owner.js +16 -14
- package/dist/runtime/host/mesh-router-resolver.js +11 -13
- package/dist/runtime/host/relocation-direct-transfer.js +10 -9
- package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
- package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
- package/dist/runtime/host/remote-bound-session-relay.js +97 -73
- package/dist/runtime/host/route-mesh-runtime.js +64 -69
- package/dist/runtime/host/runtime-shutdown.js +1 -2
- package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
- package/dist/runtime/host/spot-address-transport.js +69 -71
- package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
- package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
- package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
- package/dist/runtime/locations/actor-location-claims.js +26 -20
- package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
- package/dist/runtime/locations/authority-key-codec.js +7 -7
- package/dist/runtime/locations/auto-connect-loop.js +3 -3
- package/dist/runtime/locations/auto-connect-planner.js +25 -19
- package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
- package/dist/runtime/locations/in-memory-authority-store.js +128 -118
- package/dist/runtime/locations/in-memory-location-store.js +195 -168
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
- package/dist/runtime/locations/key-codec.js +1 -1
- package/dist/runtime/locations/lease-tracker.js +23 -21
- package/dist/runtime/locations/lifecycle.js +4 -5
- package/dist/runtime/locations/location-store-repository.js +368 -324
- package/dist/runtime/locations/opaque-record-key.js +2 -2
- package/dist/runtime/locations/resolvers.js +73 -82
- package/dist/runtime/locations/runtime.js +68 -63
- package/dist/runtime/locations/spot-location-claims.js +39 -35
- package/dist/runtime/messaging/framework-json-v1.js +7 -7
- package/dist/runtime/messaging/packet-name.js +7 -6
- package/dist/runtime/messaging/payload-codec.js +21 -18
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
- package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +20 -18
- package/dist/runtime/routing-id.js +3 -5
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
- package/dist/runtime/spots/index.js +209 -220
- package/dist/runtime/spots/spot-activation-registry.js +15 -14
- package/dist/runtime/spots/spot-activation-state.js +17 -15
- package/dist/runtime/spots/spot-activation.js +33 -16
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
- package/dist/runtime/spots/spot-actor-membership.js +1 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +29 -21
- package/dist/runtime/spots/spot-actor-packet-drain.js +14 -10
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
- package/dist/runtime/spots/spot-closing.js +3 -7
- package/dist/runtime/spots/spot-context.js +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +13 -14
- package/dist/runtime/spots/spot-handle.js +6 -3
- package/dist/runtime/spots/spot-handler-registry.js +12 -12
- package/dist/runtime/spots/spot-manager-public.js +5 -6
- package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
- package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +79 -86
- package/dist/runtime/spots/spot-outbound.js +10 -14
- package/dist/runtime/spots/spot-remote-codec.js +22 -26
- package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
- package/dist/runtime/spots/spot-route-packet-dispatch.js +17 -15
- package/dist/runtime/spots/spot-route-replies.js +4 -6
- package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +2 -3
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
- package/dist/runtime/spots/spot-serial-executor.js +5 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
- package/dist/runtime/spots/spot-subscription-dispatch.js +6 -6
- package/dist/runtime/spots/spot-timer.js +26 -30
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
- package/dist/runtime/streams/actor-session-binding-registry.js +168 -148
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +20 -17
- package/dist/runtime/streams/bound-session-response-target.js +8 -1
- package/dist/runtime/streams/bound-session-service.d.ts +1 -0
- package/dist/runtime/streams/bound-session-service.js +14 -12
- package/dist/runtime/streams/index.js +28 -20
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +52 -31
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.d.ts +5 -1
- package/dist/runtime/streams/protocol.js +68 -20
- package/dist/runtime/streams/session-actor-coordinator.js +37 -41
- package/dist/runtime/streams/session-context.d.ts +9 -2
- package/dist/runtime/streams/session-context.js +50 -32
- package/dist/runtime/streams/session-local-actors.d.ts +3 -1
- package/dist/runtime/streams/session-local-actors.js +17 -2
- package/dist/runtime/streams/session-provider.js +2 -2
- package/dist/runtime/streams/session-serial-executor.js +1 -2
- package/dist/runtime/streams/stream-frame-factory.d.ts +1 -1
- package/dist/runtime/streams/stream-frame-factory.js +14 -7
- package/dist/runtime/streams/stream-session-runtime.js +112 -78
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +3 -3
- package/src/contracts/Channels/RouteCalls.ts +6 -1
- package/src/contracts/Common/ZLinkMessage.ts +5 -5
- package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
- package/src/contracts/Configuration/Builders.ts +14 -14
- package/src/contracts/Configuration/CodecContentType.ts +8 -10
- package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
- package/src/contracts/Configuration/EndpointNotation.ts +11 -11
- package/src/contracts/Configuration/ObjectRoles.ts +1 -3
- package/src/contracts/Configuration/Registration.ts +46 -17
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
- package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
- package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
- package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
- package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
- package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
- package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
- package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -6
- package/src/contracts/Errors/index.ts +1 -4
- package/src/contracts/Handlers/Attributes.ts +15 -9
- package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
- package/src/contracts/Handlers/JsonContract.ts +53 -19
- package/src/contracts/Locations/ActorTransfer.ts +1 -5
- package/src/contracts/Locations/Authority.ts +4 -11
- package/src/contracts/Locations/Keys.ts +6 -1
- package/src/contracts/Locations/Options.ts +3 -2
- package/src/contracts/Locations/RelocationStore.ts +1 -4
- package/src/contracts/Locations/Resolvers.ts +5 -5
- package/src/contracts/Locations/RuntimeQuery.ts +6 -2
- package/src/contracts/Locations/Stores.ts +1 -2
- package/src/contracts/Locations/index.ts +2 -8
- package/src/contracts/RouteMesh/Contracts.ts +1 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
- package/src/contracts/Spots/Contracts.ts +2 -8
- package/src/contracts/Spots/SpotKind.ts +16 -8
- package/src/contracts/Spots/ZLinkSpot.ts +8 -11
- package/src/contracts/Streams/IZLinkSession.ts +2 -2
- package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
- package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
- package/src/internal.ts +5 -4
- package/src/location-store-integration.ts +24 -16
- package/src/nest-integration.ts +40 -25
- package/src/runtime/abort.ts +10 -4
- package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
- package/src/runtime/actors/actor-authority-publication.ts +92 -77
- package/src/runtime/actors/actor-client.ts +162 -133
- package/src/runtime/actors/actor-context.ts +142 -134
- package/src/runtime/actors/actor-creation.ts +47 -44
- package/src/runtime/actors/actor-execution-context.ts +6 -4
- package/src/runtime/actors/actor-handoff.ts +269 -293
- package/src/runtime/actors/actor-join-deferred-scope.ts +1 -32
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
- package/src/runtime/actors/actor-local-native-join.ts +131 -159
- package/src/runtime/actors/actor-mailbox.ts +16 -19
- package/src/runtime/actors/actor-message-follow-context.ts +46 -36
- package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
- package/src/runtime/actors/actor-remote-joiner.ts +50 -54
- package/src/runtime/actors/actor-remote-wire.ts +9 -13
- package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
- package/src/runtime/actors/actor-runtime-state.ts +127 -124
- package/src/runtime/actors/actor-transfer-registry.ts +9 -14
- package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
- package/src/runtime/actors/bound-session-wire.ts +37 -17
- package/src/runtime/actors/deferred-join-accepted-journal.ts +353 -326
- package/src/runtime/actors/index.ts +43 -86
- package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
- package/src/runtime/actors/post-commit-actor-location.ts +30 -23
- package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
- package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
- package/src/runtime/admission.ts +9 -9
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
- package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
- package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
- package/src/runtime/backend/contracts/index.ts +77 -52
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
- package/src/runtime/backend/mesh-completion-table.ts +6 -9
- package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
- package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
- package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
- package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +370 -390
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
- package/src/runtime/backend/runtime-message.ts +5 -3
- package/src/runtime/backend/runtime-values.ts +10 -7
- package/src/runtime/channels/channel-autoconnect.ts +1 -4
- package/src/runtime/channels/channel-clients.ts +93 -73
- package/src/runtime/channels/channel-dispatch-pipeline.ts +44 -44
- package/src/runtime/channels/channel-dispatch-services.ts +51 -49
- package/src/runtime/channels/channel-dispatchers.ts +152 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
- package/src/runtime/channels/channel-envelope.ts +256 -150
- package/src/runtime/channels/channel-multipart.ts +13 -5
- package/src/runtime/channels/channel-outbound-operations.ts +37 -41
- package/src/runtime/channels/channel-receive-loops.ts +102 -98
- package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
- package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
- package/src/runtime/channels/channel-runtime-manager.ts +63 -37
- package/src/runtime/channels/channel-socket-options.ts +3 -10
- package/src/runtime/channels/channel-socket-registry.ts +331 -273
- package/src/runtime/channels/channel-transports.ts +218 -206
- package/src/runtime/channels/client-server-location-runtime.ts +116 -100
- package/src/runtime/channels/client-server-service-wire.ts +37 -36
- package/src/runtime/channels/dispatch-error-reporter.ts +12 -47
- package/src/runtime/channels/fanout-location-runtime.ts +91 -94
- package/src/runtime/channels/fanout-service-wire.ts +5 -12
- package/src/runtime/channels/handler-filter-scope.ts +1 -4
- package/src/runtime/channels/index.ts +1 -4
- package/src/runtime/channels/local-spot-route-transport.ts +20 -5
- package/src/runtime/channels/route-member-snapshot.ts +11 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
- package/src/runtime/channels/source-spot-router.ts +26 -22
- package/src/runtime/channels/spot-direct-envelope.ts +10 -8
- package/src/runtime/channels/spot-node-route-transport.ts +13 -16
- package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
- package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
- package/src/runtime/codecs/index.ts +3 -2
- package/src/runtime/diagnostics/dispatch-error-details.ts +62 -0
- package/src/runtime/diagnostics/flow-context.ts +18 -7
- package/src/runtime/diagnostics/index.ts +96 -61
- package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
- package/src/runtime/diagnostics/message-flow.ts +107 -79
- package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
- package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
- package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
- package/src/runtime/execution/index.ts +18 -26
- package/src/runtime/execution/serial-execution-queue.ts +31 -40
- package/src/runtime/execution/state-lane.ts +2 -2
- package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -55
- package/src/runtime/foundation/event-loop-resources.ts +8 -4
- package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
- package/src/runtime/foundation/operation-identity.ts +1 -2
- package/src/runtime/foundation/operation-registry.ts +8 -2
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +364 -396
- package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
- package/src/runtime/foundation/runtime-state-projections.ts +24 -23
- package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
- package/src/runtime/foundation/service-discovery-registry.ts +67 -59
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
- package/src/runtime/foundation/service-liveness-registry.ts +18 -13
- package/src/runtime/foundation/service-mailbox.ts +14 -14
- package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
- package/src/runtime/foundation/service-metadata-codec.ts +2 -9
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
- package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
- package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
- package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
- package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1233 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +170 -159
- package/src/runtime/foundation/service-weighted-selection.ts +9 -15
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
- package/src/runtime/framework-errors-internal.ts +31 -30
- package/src/runtime/handlers/handler-instance-scope.ts +18 -29
- package/src/runtime/handlers/index.ts +18 -8
- package/src/runtime/host/actor-packet-relay.ts +290 -261
- package/src/runtime/host/actor-placement-coordinator.ts +165 -150
- package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
- package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
- package/src/runtime/host/actor-transfer-runtime.ts +391 -395
- package/src/runtime/host/application-job-queue.ts +32 -48
- package/src/runtime/host/bound-session-relay.ts +7 -9
- package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
- package/src/runtime/host/host-capacity-status.ts +10 -9
- package/src/runtime/host/index.ts +861 -789
- package/src/runtime/host/instance-activation-authority.ts +125 -143
- package/src/runtime/host/location-runtime-owner.ts +38 -26
- package/src/runtime/host/mesh-router-resolver.ts +30 -23
- package/src/runtime/host/relocation-direct-transfer.ts +15 -15
- package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
- package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
- package/src/runtime/host/remote-bound-session-relay.ts +274 -247
- package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
- package/src/runtime/host/route-mesh-runtime.ts +227 -181
- package/src/runtime/host/runtime-shutdown.ts +4 -3
- package/src/runtime/host/service-relocation-control.ts +14 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
- package/src/runtime/host/spot-address-transport.ts +284 -237
- package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
- package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
- package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
- package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
- package/src/runtime/locations/actor-location-claims.ts +61 -49
- package/src/runtime/locations/actor-session-route-claims.ts +1 -4
- package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
- package/src/runtime/locations/authority-key-codec.ts +13 -10
- package/src/runtime/locations/auto-connect-loop.ts +14 -11
- package/src/runtime/locations/auto-connect-planner.ts +42 -31
- package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
- package/src/runtime/locations/canonical-codec.ts +3 -1
- package/src/runtime/locations/creation-operation-id.ts +4 -3
- package/src/runtime/locations/domain-store-contract.ts +13 -7
- package/src/runtime/locations/in-memory-authority-store.ts +232 -199
- package/src/runtime/locations/in-memory-location-store.ts +432 -250
- package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
- package/src/runtime/locations/internal-store-contracts.ts +95 -38
- package/src/runtime/locations/key-codec.ts +3 -4
- package/src/runtime/locations/lease-tracker.ts +36 -27
- package/src/runtime/locations/lifecycle-runtime.ts +15 -3
- package/src/runtime/locations/lifecycle.ts +33 -28
- package/src/runtime/locations/location-store-repository.ts +1329 -1185
- package/src/runtime/locations/opaque-record-key.ts +4 -9
- package/src/runtime/locations/resolvers.ts +201 -178
- package/src/runtime/locations/runtime.ts +251 -159
- package/src/runtime/locations/spot-location-claims.ts +110 -112
- package/src/runtime/messaging/creation-payload-codec.ts +4 -1
- package/src/runtime/messaging/framework-json-v1.ts +34 -15
- package/src/runtime/messaging/packet-name.ts +8 -6
- package/src/runtime/messaging/payload-codec.ts +70 -50
- package/src/runtime/messaging/submission-result.ts +6 -9
- package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +19 -18
- package/src/runtime/routing-id.ts +10 -7
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
- package/src/runtime/spots/index.ts +595 -564
- package/src/runtime/spots/spot-activation-registry.ts +38 -34
- package/src/runtime/spots/spot-activation-state.ts +43 -51
- package/src/runtime/spots/spot-activation.ts +179 -116
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
- package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
- package/src/runtime/spots/spot-actor-membership.ts +25 -27
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +196 -148
- package/src/runtime/spots/spot-actor-packet-drain.ts +56 -42
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
- package/src/runtime/spots/spot-closing.ts +11 -12
- package/src/runtime/spots/spot-context.ts +46 -26
- package/src/runtime/spots/spot-entry-activation.ts +84 -65
- package/src/runtime/spots/spot-handle.ts +17 -15
- package/src/runtime/spots/spot-handler-registry.ts +44 -31
- package/src/runtime/spots/spot-location-claim.ts +5 -4
- package/src/runtime/spots/spot-manager-public.ts +62 -82
- package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
- package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
- package/src/runtime/spots/spot-node-runtime-manager.ts +235 -222
- package/src/runtime/spots/spot-outbound.ts +47 -59
- package/src/runtime/spots/spot-publisher-transport.ts +5 -4
- package/src/runtime/spots/spot-remote-codec.ts +66 -65
- package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
- package/src/runtime/spots/spot-route-packet-dispatch.ts +129 -95
- package/src/runtime/spots/spot-route-replies.ts +23 -24
- package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
- package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +13 -18
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
- package/src/runtime/spots/spot-routing-internal.ts +1 -4
- package/src/runtime/spots/spot-runtime-ports.ts +5 -5
- package/src/runtime/spots/spot-serial-executor.ts +5 -9
- package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
- package/src/runtime/spots/spot-subscription-dispatch.ts +58 -47
- package/src/runtime/spots/spot-timer.ts +103 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +421 -292
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +8 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +60 -50
- package/src/runtime/streams/bound-session-response-target.ts +39 -9
- package/src/runtime/streams/bound-session-service.ts +52 -42
- package/src/runtime/streams/index.ts +183 -100
- package/src/runtime/streams/managed-stream.ts +123 -90
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +115 -46
- package/src/runtime/streams/session-actor-coordinator.ts +109 -93
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +96 -51
- package/src/runtime/streams/session-local-actors.ts +19 -3
- package/src/runtime/streams/session-provider.ts +5 -7
- package/src/runtime/streams/session-serial-executor.ts +7 -6
- package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
- package/src/runtime/streams/stream-frame-factory.ts +59 -40
- package/src/runtime/streams/stream-session-runtime.ts +317 -214
- package/src/runtime/workers/index.ts +68 -29
|
@@ -91,13 +91,12 @@ class RawServiceMeshRuntime {
|
|
|
91
91
|
router = host.createRouter();
|
|
92
92
|
const receiveFlowRouter = router;
|
|
93
93
|
router.setRoutingId(this.descriptor.nodeRoutingId);
|
|
94
|
-
this.applicationJobQueue.registerReceiveFlowTarget?.(router, state => receiveFlowRouter.setReceiveFlowState(state), this.onReceiveFlowConfigFailure);
|
|
94
|
+
this.applicationJobQueue.registerReceiveFlowTarget?.(router, (state) => receiveFlowRouter.setReceiveFlowState(state), this.onReceiveFlowConfigFailure);
|
|
95
95
|
router.bind(this.descriptor.advertisedEndpoint);
|
|
96
96
|
const boundEndpoint = router.localEndpoint();
|
|
97
97
|
const next = {
|
|
98
98
|
...this.descriptor,
|
|
99
|
-
advertisedEndpoint: this.resolveAdvertisedEndpoint?.(boundEndpoint)
|
|
100
|
-
?? boundEndpoint,
|
|
99
|
+
advertisedEndpoint: this.resolveAdvertisedEndpoint?.(boundEndpoint) ?? boundEndpoint,
|
|
101
100
|
descriptorRevision: this.descriptor.descriptorRevision + 1n,
|
|
102
101
|
state: 'serving'
|
|
103
102
|
};
|
|
@@ -152,20 +151,16 @@ class RawServiceMeshRuntime {
|
|
|
152
151
|
disconnectPeer(endpoint, nodeRoutingId, lifecycleGeneration) {
|
|
153
152
|
const current = this.topology.peer(nodeRoutingId);
|
|
154
153
|
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
155
|
-
if (lifecycleGeneration !== undefined
|
|
156
|
-
&& (
|
|
154
|
+
if (lifecycleGeneration !== undefined &&
|
|
157
155
|
// Discovery has already fenced this RID to a replacement process.
|
|
158
156
|
// The old auto-connect intent must not use disconnectRid here: that
|
|
159
157
|
// is RID-wide and can close the provisional replacement before its
|
|
160
158
|
// Hello/admission promotes it. admitPeer owns exact old-pair teardown
|
|
161
159
|
// after the replacement descriptor is accepted.
|
|
162
|
-
(expected?.lifecycleGeneration !== undefined
|
|
163
|
-
|
|
164
|
-
||
|
|
165
|
-
|
|
166
|
-
&& current.descriptor.lifecycleGeneration !== lifecycleGeneration)
|
|
167
|
-
|| (current === undefined
|
|
168
|
-
&& expected?.lifecycleGeneration !== lifecycleGeneration))) {
|
|
160
|
+
((expected?.lifecycleGeneration !== undefined &&
|
|
161
|
+
expected.lifecycleGeneration !== lifecycleGeneration) ||
|
|
162
|
+
(current !== undefined && current.descriptor.lifecycleGeneration !== lifecycleGeneration) ||
|
|
163
|
+
(current === undefined && expected?.lifecycleGeneration !== lifecycleGeneration))) {
|
|
169
164
|
return;
|
|
170
165
|
}
|
|
171
166
|
try {
|
|
@@ -185,9 +180,9 @@ class RawServiceMeshRuntime {
|
|
|
185
180
|
if (current !== undefined)
|
|
186
181
|
this.removePeer(current);
|
|
187
182
|
this.topology.forgetNotRequired(nodeRoutingId);
|
|
188
|
-
if (lifecycleGeneration === undefined
|
|
189
|
-
|
|
190
|
-
|
|
183
|
+
if (lifecycleGeneration === undefined ||
|
|
184
|
+
expected?.lifecycleGeneration === undefined ||
|
|
185
|
+
expected.lifecycleGeneration === lifecycleGeneration) {
|
|
191
186
|
this.expectedPeers.delete(nodeRoutingId);
|
|
192
187
|
}
|
|
193
188
|
this.notifyPeerConnectionIntentRemoved(nodeRoutingId);
|
|
@@ -222,7 +217,9 @@ class RawServiceMeshRuntime {
|
|
|
222
217
|
}
|
|
223
218
|
observePeerConnectionIntentRemoved(listener) {
|
|
224
219
|
this.peerConnectionIntentRemoved.add(listener);
|
|
225
|
-
return () => {
|
|
220
|
+
return () => {
|
|
221
|
+
this.peerConnectionIntentRemoved.delete(listener);
|
|
222
|
+
};
|
|
226
223
|
}
|
|
227
224
|
notifyPeerConnectionIntentRemoved(nodeRoutingId) {
|
|
228
225
|
// Only the logical owner's removal publishes lifecycle termination.
|
|
@@ -235,18 +232,19 @@ class RawServiceMeshRuntime {
|
|
|
235
232
|
async announcePeer(nodeRoutingId) {
|
|
236
233
|
if (!this.expectedPeers.has(nodeRoutingId) || this.peerAdmissionSealed?.() === true)
|
|
237
234
|
return false;
|
|
238
|
-
return this.send(nodeRoutingId, [
|
|
235
|
+
return this.send(nodeRoutingId, [
|
|
236
|
+
(0, service_wire_m6a_codec_1.encodeRouteMeshAdmission)(service_wire_m6a_codec_1.M6aServiceWireCommand.hello, this.topology.localDescriptor())
|
|
237
|
+
]);
|
|
239
238
|
}
|
|
240
239
|
isPeerRouteReady(nodeRoutingId, lifecycleGeneration) {
|
|
241
240
|
const peer = this.topology.peer(nodeRoutingId);
|
|
242
241
|
const monitorConnection = this.monitorConnectionStates.get(nodeRoutingId);
|
|
243
|
-
const applicationRouteReady = monitorConnection === undefined
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
&& this.liveness.isReady(nodeRoutingId, peer.connectionId);
|
|
242
|
+
const applicationRouteReady = monitorConnection === undefined || monitorConnection === peer?.connectionId;
|
|
243
|
+
const ready = peer !== undefined &&
|
|
244
|
+
(lifecycleGeneration === undefined ||
|
|
245
|
+
peer.descriptor.lifecycleGeneration === lifecycleGeneration) &&
|
|
246
|
+
applicationRouteReady &&
|
|
247
|
+
this.liveness.isReady(nodeRoutingId, peer.connectionId);
|
|
250
248
|
return ready;
|
|
251
249
|
}
|
|
252
250
|
async announceExpectedPeers() {
|
|
@@ -267,10 +265,10 @@ class RawServiceMeshRuntime {
|
|
|
267
265
|
async updateLocalDescriptor(options) {
|
|
268
266
|
const current = this.topology.localDescriptor();
|
|
269
267
|
const channels = options.state === 'draining'
|
|
270
|
-
? current.channels.map(channel => ({ ...channel, weight: 0 }))
|
|
268
|
+
? current.channels.map((channel) => ({ ...channel, weight: 0 }))
|
|
271
269
|
: options.channelName === undefined
|
|
272
270
|
? current.channels
|
|
273
|
-
: current.channels.map(channel => channel.name === options.channelName
|
|
271
|
+
: current.channels.map((channel) => channel.name === options.channelName
|
|
274
272
|
? { ...channel, weight: options.channelWeight }
|
|
275
273
|
: channel);
|
|
276
274
|
const next = {
|
|
@@ -305,9 +303,10 @@ class RawServiceMeshRuntime {
|
|
|
305
303
|
return this.send(targetNodeRoutingId, [(0, service_wire_m6a_codec_1.encodeNodeSendHeader)(), this.applicationFrame(payload)]);
|
|
306
304
|
}
|
|
307
305
|
async sendToChannel(channelName, payload) {
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
310
|
-
return
|
|
306
|
+
const selection = this.selectChannelTarget(channelName);
|
|
307
|
+
if (selection.kind !== 'selected')
|
|
308
|
+
return selection.submitResult;
|
|
309
|
+
const selected = selection.peer;
|
|
311
310
|
const applicationFrame = this.applicationFrame(payload);
|
|
312
311
|
if (selected.descriptor.nodeRoutingId === this.descriptor.nodeRoutingId) {
|
|
313
312
|
const applicationJobOwner = await this.reserveLocalIngress();
|
|
@@ -322,29 +321,52 @@ class RawServiceMeshRuntime {
|
|
|
322
321
|
});
|
|
323
322
|
if (!accepted)
|
|
324
323
|
applicationJob.close();
|
|
325
|
-
return accepted;
|
|
324
|
+
return accepted ? runtime_values_1.SubmitResult.Ok : runtime_values_1.SubmitResult.NotAdmitted;
|
|
326
325
|
}
|
|
327
326
|
finally {
|
|
328
327
|
applicationJobOwner.close();
|
|
329
328
|
}
|
|
330
329
|
}
|
|
331
|
-
return this.send(selected.descriptor.nodeRoutingId, [
|
|
330
|
+
return (await this.send(selected.descriptor.nodeRoutingId, [
|
|
332
331
|
(0, service_wire_m6a_codec_1.encodeChannelSendHeader)(channelName),
|
|
333
332
|
applicationFrame
|
|
334
|
-
])
|
|
333
|
+
]))
|
|
334
|
+
? runtime_values_1.SubmitResult.Ok
|
|
335
|
+
: runtime_values_1.SubmitResult.NotConnected;
|
|
335
336
|
}
|
|
336
337
|
requestToNode(targetNodeRoutingId, payload, timeoutMs) {
|
|
337
338
|
return this.requestToTarget(targetNodeRoutingId, payload, timeoutMs);
|
|
338
339
|
}
|
|
339
340
|
requestToChannel(channelName, payload, timeoutMs) {
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
341
|
+
const selection = this.selectChannelTarget(channelName);
|
|
342
|
+
if (selection.kind !== 'selected') {
|
|
343
|
+
const pending = this.operations.register(timeoutMs);
|
|
344
|
+
this.operations.complete(pending.id, selection.requestResult);
|
|
345
|
+
return pending;
|
|
346
|
+
}
|
|
347
|
+
return this.requestToTarget(selection.peer.descriptor.nodeRoutingId, payload, timeoutMs, channelName);
|
|
348
|
+
}
|
|
349
|
+
selectChannelTarget(channelName) {
|
|
350
|
+
const selected = this.topology.selectChannel(channelName, (peer) => this.isLocalOrReadyPeer(peer.descriptor.nodeRoutingId));
|
|
351
|
+
if (selected !== undefined)
|
|
352
|
+
return { kind: 'selected', peer: selected };
|
|
353
|
+
return this.topology.hasKnownChannelTarget(channelName)
|
|
354
|
+
? {
|
|
355
|
+
kind: 'knownButNotReady',
|
|
356
|
+
submitResult: runtime_values_1.SubmitResult.NotConnected,
|
|
357
|
+
requestResult: { terminalResult: runtime_values_1.RequestResult.NotConnected, failureCode: 0 }
|
|
358
|
+
}
|
|
359
|
+
: {
|
|
360
|
+
kind: 'noMember',
|
|
361
|
+
submitResult: runtime_values_1.SubmitResult.NotFound,
|
|
362
|
+
requestResult: {
|
|
363
|
+
terminalResult: runtime_values_1.RequestResult.NotFound,
|
|
364
|
+
failureCode: REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
|
|
365
|
+
}
|
|
366
|
+
};
|
|
344
367
|
}
|
|
345
368
|
isLocalOrReadyPeer(nodeRoutingId) {
|
|
346
|
-
return nodeRoutingId === this.descriptor.nodeRoutingId
|
|
347
|
-
|| this.isPeerRouteReady(nodeRoutingId);
|
|
369
|
+
return nodeRoutingId === this.descriptor.nodeRoutingId || this.isPeerRouteReady(nodeRoutingId);
|
|
348
370
|
}
|
|
349
371
|
setServiceIngress(handler) {
|
|
350
372
|
if (this.serviceIngress !== undefined && this.serviceIngress !== handler) {
|
|
@@ -400,7 +422,9 @@ class RawServiceMeshRuntime {
|
|
|
400
422
|
const startedAtMs = performance.now();
|
|
401
423
|
let messages = 0;
|
|
402
424
|
let bytes = 0;
|
|
403
|
-
const observe = (_source, byteCount) => {
|
|
425
|
+
const observe = (_source, byteCount) => {
|
|
426
|
+
bytes += byteCount;
|
|
427
|
+
};
|
|
404
428
|
while (receiveReady && messages < 64 && !this.closed) {
|
|
405
429
|
const result = await this.receiveOne(performance.now(), observe);
|
|
406
430
|
if (result === 'noData') {
|
|
@@ -460,13 +484,13 @@ class RawServiceMeshRuntime {
|
|
|
460
484
|
}
|
|
461
485
|
}
|
|
462
486
|
pullMonitorEvents() {
|
|
463
|
-
this.monitor?.drain(event => {
|
|
487
|
+
this.monitor?.drain((event) => {
|
|
464
488
|
this.observeMonitorEvent(event);
|
|
465
489
|
if (this.monitorEvents.length < MAX_PENDING_MONITOR_EVENTS) {
|
|
466
490
|
this.monitorEvents.push(event);
|
|
467
491
|
return;
|
|
468
492
|
}
|
|
469
|
-
const existingIndex = this.monitorEvents.findIndex(candidate => sameMonitorConnection(candidate, event));
|
|
493
|
+
const existingIndex = this.monitorEvents.findIndex((candidate) => sameMonitorConnection(candidate, event));
|
|
470
494
|
if (existingIndex >= 0)
|
|
471
495
|
this.monitorEvents[existingIndex] = event;
|
|
472
496
|
else {
|
|
@@ -497,7 +521,9 @@ class RawServiceMeshRuntime {
|
|
|
497
521
|
: undefined;
|
|
498
522
|
if (correlation === undefined)
|
|
499
523
|
return false;
|
|
500
|
-
const reply = [
|
|
524
|
+
const reply = [
|
|
525
|
+
(0, service_wire_m6a_codec_1.encodeReplyHeader)(correlation, runtime_values_1.RequestResult.ProtocolError, service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestProtocolError)
|
|
526
|
+
];
|
|
501
527
|
if (received.reply === undefined)
|
|
502
528
|
return false;
|
|
503
529
|
received.reply(reply);
|
|
@@ -510,12 +536,13 @@ class RawServiceMeshRuntime {
|
|
|
510
536
|
}
|
|
511
537
|
}
|
|
512
538
|
async processReceived(received, nowMs, applicationJobOwner) {
|
|
513
|
-
if (received.parts.length === 0
|
|
514
|
-
|
|
515
|
-
&& received.parts[0].byteLength === 0)) {
|
|
539
|
+
if (received.parts.length === 0 ||
|
|
540
|
+
(received.parts.length === 1 && received.parts[0].byteLength === 0)) {
|
|
516
541
|
if (this.peerAdmissionSealed?.() === true)
|
|
517
542
|
return 'dropped';
|
|
518
|
-
return await this.send(received.sourceRid, [
|
|
543
|
+
return (await this.send(received.sourceRid, [
|
|
544
|
+
(0, service_wire_m6a_codec_1.encodeRouteMeshAdmission)(service_wire_m6a_codec_1.M6aServiceWireCommand.hello, this.topology.localDescriptor())
|
|
545
|
+
]))
|
|
519
546
|
? 'infrastructure'
|
|
520
547
|
: 'dropped';
|
|
521
548
|
}
|
|
@@ -524,16 +551,16 @@ class RawServiceMeshRuntime {
|
|
|
524
551
|
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.hello && this.peerAdmissionSealed?.() === true) {
|
|
525
552
|
return 'dropped';
|
|
526
553
|
}
|
|
527
|
-
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.hello
|
|
528
|
-
|
|
529
|
-
|
|
554
|
+
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.hello ||
|
|
555
|
+
header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.admit ||
|
|
556
|
+
header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.update) {
|
|
530
557
|
if (received.parts.length !== 1)
|
|
531
558
|
return 'protocolError';
|
|
532
559
|
const descriptor = (0, service_wire_m6a_codec_1.decodeRouteMeshAdmission)(received.parts[0], header.command, received.sourceRid);
|
|
533
560
|
const expected = this.expectedPeers.get(received.sourceRid);
|
|
534
|
-
if (expected !== undefined
|
|
535
|
-
|
|
536
|
-
|
|
561
|
+
if (expected !== undefined &&
|
|
562
|
+
(expected.meshName !== descriptor.meshName ||
|
|
563
|
+
expected.nodeRoutingId !== descriptor.nodeRoutingId)) {
|
|
537
564
|
await this.send(received.sourceRid, [(0, service_wire_m6a_codec_1.encodeReject)(3)]);
|
|
538
565
|
return 'infrastructure';
|
|
539
566
|
}
|
|
@@ -543,8 +570,8 @@ class RawServiceMeshRuntime {
|
|
|
543
570
|
const detail = result === 'invalidDescriptor'
|
|
544
571
|
? describeInvalidAdmissionDescriptor(descriptor, expected, this.topology.peer(descriptor.nodeRoutingId)?.descriptor)
|
|
545
572
|
: undefined;
|
|
546
|
-
console.warn(`RouteMesh admission rejected peer '${received.sourceRid}' as ${result}`
|
|
547
|
-
|
|
573
|
+
console.warn(`RouteMesh admission rejected peer '${received.sourceRid}' as ${result}` +
|
|
574
|
+
(detail === undefined ? '.' : ` (${detail}).`));
|
|
548
575
|
await this.send(received.sourceRid, [(0, service_wire_m6a_codec_1.encodeReject)(admissionReason(result))]);
|
|
549
576
|
return 'infrastructure';
|
|
550
577
|
}
|
|
@@ -554,7 +581,9 @@ class RawServiceMeshRuntime {
|
|
|
554
581
|
// Hello supplies only the sender's descriptor. Even NotRequired
|
|
555
582
|
// peers must receive ours before the intent owner closes transport;
|
|
556
583
|
// submitting a response does not guarantee delivery before close.
|
|
557
|
-
await this.send(received.sourceRid, [
|
|
584
|
+
await this.send(received.sourceRid, [
|
|
585
|
+
(0, service_wire_m6a_codec_1.encodeRouteMeshAdmission)(service_wire_m6a_codec_1.M6aServiceWireCommand.admit, this.topology.localDescriptor())
|
|
586
|
+
]);
|
|
558
587
|
}
|
|
559
588
|
else if (result === 'notRequired') {
|
|
560
589
|
this.retireNotRequiredExpectedPeer(received.sourceRid, descriptor.advertisedEndpoint);
|
|
@@ -588,17 +617,20 @@ class RawServiceMeshRuntime {
|
|
|
588
617
|
const peer = this.topology.peer(received.sourceRid);
|
|
589
618
|
if (peer === undefined)
|
|
590
619
|
return 'protocolError';
|
|
591
|
-
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe
|
|
592
|
-
|
|
620
|
+
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe ||
|
|
621
|
+
header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck) {
|
|
593
622
|
if (received.parts.length !== 1)
|
|
594
623
|
return 'protocolError';
|
|
595
624
|
const record = livenessCodec.decodeLivenessRecord(received.parts[0]);
|
|
596
625
|
if (record.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe) {
|
|
597
626
|
const ack = this.liveness.acknowledgeProbe(received.sourceRid, peer.connectionId, record.probeId);
|
|
598
|
-
const sent = ack !== undefined &&
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
627
|
+
const sent = ack !== undefined &&
|
|
628
|
+
(await this.send(received.sourceRid, [
|
|
629
|
+
livenessCodec.encodeLivenessRecord({
|
|
630
|
+
command: service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck,
|
|
631
|
+
probeId: record.probeId
|
|
632
|
+
})
|
|
633
|
+
]));
|
|
602
634
|
if (!sent) {
|
|
603
635
|
return 'protocolError';
|
|
604
636
|
}
|
|
@@ -621,7 +653,7 @@ class RawServiceMeshRuntime {
|
|
|
621
653
|
});
|
|
622
654
|
if (stateful !== undefined)
|
|
623
655
|
return stateful;
|
|
624
|
-
if (header.flags === 0
|
|
656
|
+
if (header.flags === 0 &&
|
|
625
657
|
// A bare infrastructure control is normally exactly one frame, but a
|
|
626
658
|
// relocation Prepare now rides its bound-session journal as
|
|
627
659
|
// node-internal ZLNI frames trailing the canonical command frame
|
|
@@ -633,8 +665,8 @@ class RawServiceMeshRuntime {
|
|
|
633
665
|
// protocolError (surfaced downstream as `invalid_frame`, stalling
|
|
634
666
|
// the source's Prepare resend loop past the relocation admission
|
|
635
667
|
// budget).
|
|
636
|
-
|
|
637
|
-
|
|
668
|
+
received.parts.length >= 1 &&
|
|
669
|
+
isBareInfrastructureControl(header.command)) {
|
|
638
670
|
const accepted = this.mailbox.tryEnqueue({
|
|
639
671
|
owner: `node:${this.descriptor.nodeRoutingId}`,
|
|
640
672
|
domain: 'infrastructure',
|
|
@@ -646,9 +678,9 @@ class RawServiceMeshRuntime {
|
|
|
646
678
|
});
|
|
647
679
|
return accepted ? 'infrastructure' : 'dropped';
|
|
648
680
|
}
|
|
649
|
-
if (header.flags !== 0
|
|
650
|
-
|
|
651
|
-
|
|
681
|
+
if (header.flags !== 0 ||
|
|
682
|
+
received.parts.length !== 2 ||
|
|
683
|
+
![
|
|
652
684
|
service_wire_m6a_codec_1.M6aServiceWireCommand.nodeSend,
|
|
653
685
|
service_wire_m6a_codec_1.M6aServiceWireCommand.nodeRequest,
|
|
654
686
|
service_wire_m6a_codec_1.M6aServiceWireCommand.channelSend,
|
|
@@ -694,9 +726,7 @@ class RawServiceMeshRuntime {
|
|
|
694
726
|
sourceRoute: received.sourceRoute,
|
|
695
727
|
requestSequence: received.requestSeq,
|
|
696
728
|
...(received.reply === undefined ? {} : { reply: received.reply })
|
|
697
|
-
}, [
|
|
698
|
-
(0, service_wire_m6a_codec_1.encodeReplyHeader)(correlation, runtime_values_1.RequestResult.NotConnected, 0)
|
|
699
|
-
]);
|
|
729
|
+
}, [(0, service_wire_m6a_codec_1.encodeReplyHeader)(correlation, runtime_values_1.RequestResult.NotConnected, 0)]);
|
|
700
730
|
return 'infrastructure';
|
|
701
731
|
}
|
|
702
732
|
return 'dropped';
|
|
@@ -711,10 +741,12 @@ class RawServiceMeshRuntime {
|
|
|
711
741
|
const result = this.liveness.tick(nowMs);
|
|
712
742
|
this.requireStarted();
|
|
713
743
|
for (const probe of result.probes) {
|
|
714
|
-
await this.send(probe.nodeRoutingId, [
|
|
744
|
+
await this.send(probe.nodeRoutingId, [
|
|
745
|
+
livenessCodec.encodeLivenessRecord({
|
|
715
746
|
command: service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe,
|
|
716
747
|
probeId: probe.probeId
|
|
717
|
-
})
|
|
748
|
+
})
|
|
749
|
+
]);
|
|
718
750
|
}
|
|
719
751
|
for (const nodeRoutingId of result.timedOutNodes) {
|
|
720
752
|
const peer = this.topology.peer(nodeRoutingId);
|
|
@@ -739,13 +771,13 @@ class RawServiceMeshRuntime {
|
|
|
739
771
|
this.monitorEvents.length = 0;
|
|
740
772
|
for (const event of events) {
|
|
741
773
|
handled++;
|
|
742
|
-
const nodeRoutingId = event.routingId
|
|
743
|
-
?? this.expectedPeerRoutingId(event.remoteAddress);
|
|
774
|
+
const nodeRoutingId = event.routingId ?? this.expectedPeerRoutingId(event.remoteAddress);
|
|
744
775
|
if (event.event === MONITOR_CONNECTION_READY && isConnectionReadyEdge(event)) {
|
|
745
776
|
if (nodeRoutingId === undefined) {
|
|
746
777
|
const candidate = this.createUnresolvedConnectionCandidate(event);
|
|
747
|
-
const alreadyQueued = this.unresolvedConnectionCandidates.some(value => value.connectionId === candidate.connectionId);
|
|
748
|
-
if (!alreadyQueued &&
|
|
778
|
+
const alreadyQueued = this.unresolvedConnectionCandidates.some((value) => value.connectionId === candidate.connectionId);
|
|
779
|
+
if (!alreadyQueued &&
|
|
780
|
+
this.unresolvedConnectionCandidates.length < MAX_UNRESOLVED_CONNECTION_CANDIDATES) {
|
|
749
781
|
this.unresolvedConnectionCandidates.push(candidate);
|
|
750
782
|
}
|
|
751
783
|
continue;
|
|
@@ -762,7 +794,8 @@ class RawServiceMeshRuntime {
|
|
|
762
794
|
if (existingPeer !== undefined) {
|
|
763
795
|
if (this.liveness.isReady(nodeRoutingId, existingPeer.connectionId)) {
|
|
764
796
|
const existingCandidate = this.connectionCandidates
|
|
765
|
-
.get(nodeRoutingId)
|
|
797
|
+
.get(nodeRoutingId)
|
|
798
|
+
?.get(existingPeer.connectionId);
|
|
766
799
|
if (this.isDiscoveredLifecycleReplacement(existingPeer, nodeRoutingId)) {
|
|
767
800
|
// A current discovery descriptor with the same RID but a
|
|
768
801
|
// different lifecycle token denotes a replacement process.
|
|
@@ -816,8 +849,7 @@ class RawServiceMeshRuntime {
|
|
|
816
849
|
this.connectionIds.set(nodeRoutingId, candidate.connectionId);
|
|
817
850
|
await this.announcePeer(nodeRoutingId);
|
|
818
851
|
}
|
|
819
|
-
else if (event.event === MONITOR_DISCONNECTED
|
|
820
|
-
&& nodeRoutingId !== undefined) {
|
|
852
|
+
else if (event.event === MONITOR_DISCONNECTED && nodeRoutingId !== undefined) {
|
|
821
853
|
const peer = this.topology.peer(nodeRoutingId);
|
|
822
854
|
const disconnectedId = monitorConnectionId(event, nodeRoutingId);
|
|
823
855
|
this.removeConnectionCandidate(nodeRoutingId, disconnectedId);
|
|
@@ -827,7 +859,7 @@ class RawServiceMeshRuntime {
|
|
|
827
859
|
}
|
|
828
860
|
else if (event.event === MONITOR_DISCONNECTED) {
|
|
829
861
|
const disconnectedId = monitorConnectionId(event);
|
|
830
|
-
const index = this.unresolvedConnectionCandidates.findIndex(candidate => candidate.connectionId === disconnectedId);
|
|
862
|
+
const index = this.unresolvedConnectionCandidates.findIndex((candidate) => candidate.connectionId === disconnectedId);
|
|
831
863
|
if (index >= 0)
|
|
832
864
|
this.unresolvedConnectionCandidates.splice(index, 1);
|
|
833
865
|
}
|
|
@@ -864,8 +896,8 @@ class RawServiceMeshRuntime {
|
|
|
864
896
|
const encodedPayload = this.applicationFrame(payload);
|
|
865
897
|
const pending = this.operations.register(timeoutMs);
|
|
866
898
|
let selectedTargetNodeRoutingId = targetNodeRoutingId;
|
|
867
|
-
if (selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId
|
|
868
|
-
|
|
899
|
+
if (selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId &&
|
|
900
|
+
!this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
|
|
869
901
|
// Channel selection happens before native admission. If that selection
|
|
870
902
|
// becomes stale during a peer drain, choose another ready channel peer
|
|
871
903
|
// while no request has been submitted yet. Reusing the same pending
|
|
@@ -874,16 +906,15 @@ class RawServiceMeshRuntime {
|
|
|
874
906
|
if (channelName !== undefined) {
|
|
875
907
|
const excludedTargets = new Set([selectedTargetNodeRoutingId]);
|
|
876
908
|
for (;;) {
|
|
877
|
-
const alternate = this.topology.selectChannel(channelName, peer => {
|
|
909
|
+
const alternate = this.topology.selectChannel(channelName, (peer) => {
|
|
878
910
|
const candidate = peer.descriptor.nodeRoutingId;
|
|
879
|
-
return !excludedTargets.has(candidate)
|
|
880
|
-
&& this.isLocalOrReadyPeer(candidate);
|
|
911
|
+
return !excludedTargets.has(candidate) && this.isLocalOrReadyPeer(candidate);
|
|
881
912
|
});
|
|
882
913
|
if (alternate === undefined)
|
|
883
914
|
break;
|
|
884
915
|
selectedTargetNodeRoutingId = alternate.descriptor.nodeRoutingId;
|
|
885
|
-
if (selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId
|
|
886
|
-
|
|
916
|
+
if (selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId ||
|
|
917
|
+
this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
|
|
887
918
|
break;
|
|
888
919
|
}
|
|
889
920
|
excludedTargets.add(selectedTargetNodeRoutingId);
|
|
@@ -930,7 +961,7 @@ class RawServiceMeshRuntime {
|
|
|
930
961
|
finally {
|
|
931
962
|
applicationJobOwner.close();
|
|
932
963
|
}
|
|
933
|
-
})().catch(error => this.operations.fail(pending.id, error));
|
|
964
|
+
})().catch((error) => this.operations.fail(pending.id, error));
|
|
934
965
|
return pending;
|
|
935
966
|
}
|
|
936
967
|
if (!this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
|
|
@@ -938,12 +969,10 @@ class RawServiceMeshRuntime {
|
|
|
938
969
|
// topology has never observed. A known peer without a usable route is
|
|
939
970
|
// a Framework NotConnected result; an unknown RID is completed locally
|
|
940
971
|
// as RequestTargetNotFound without submitting an application frame.
|
|
941
|
-
const knownTarget = this.topology.peer(selectedTargetNodeRoutingId) !== undefined
|
|
942
|
-
|
|
972
|
+
const knownTarget = this.topology.peer(selectedTargetNodeRoutingId) !== undefined ||
|
|
973
|
+
this.topology.knownDescriptor(selectedTargetNodeRoutingId) !== undefined;
|
|
943
974
|
this.operations.complete(pending.id, {
|
|
944
|
-
terminalResult: knownTarget
|
|
945
|
-
? runtime_values_1.RequestResult.NotConnected
|
|
946
|
-
: runtime_values_1.RequestResult.NotFound,
|
|
975
|
+
terminalResult: knownTarget ? runtime_values_1.RequestResult.NotConnected : runtime_values_1.RequestResult.NotFound,
|
|
947
976
|
failureCode: knownTarget ? 0 : REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
|
|
948
977
|
});
|
|
949
978
|
return pending;
|
|
@@ -959,7 +988,7 @@ class RawServiceMeshRuntime {
|
|
|
959
988
|
this.operations.fail(pending.id, error);
|
|
960
989
|
return pending;
|
|
961
990
|
}
|
|
962
|
-
void request.then(replyParts => {
|
|
991
|
+
void request.then((replyParts) => {
|
|
963
992
|
try {
|
|
964
993
|
if (replyParts.length < 1 || replyParts.length > 2) {
|
|
965
994
|
throw new service_wire_m6a_codec_1.ServiceWireProtocolError('Invalid reply parts.');
|
|
@@ -987,7 +1016,7 @@ class RawServiceMeshRuntime {
|
|
|
987
1016
|
catch (error) {
|
|
988
1017
|
this.operations.fail(pending.id, error);
|
|
989
1018
|
}
|
|
990
|
-
}, error => {
|
|
1019
|
+
}, (error) => {
|
|
991
1020
|
this.operations.fail(pending.id, error);
|
|
992
1021
|
});
|
|
993
1022
|
return pending;
|
|
@@ -1004,11 +1033,11 @@ class RawServiceMeshRuntime {
|
|
|
1004
1033
|
}
|
|
1005
1034
|
admitPeer(descriptor, connection, nowMs, expected) {
|
|
1006
1035
|
const previous = this.topology.peer(descriptor.nodeRoutingId);
|
|
1007
|
-
if (previous !== undefined
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1036
|
+
if (previous !== undefined &&
|
|
1037
|
+
previous.descriptor.lifecycleGeneration === descriptor.lifecycleGeneration &&
|
|
1038
|
+
(descriptor.descriptorRevision < previous.descriptor.descriptorRevision ||
|
|
1039
|
+
(descriptor.descriptorRevision === previous.descriptor.descriptorRevision &&
|
|
1040
|
+
!(0, service_topology_registry_1.sameServiceNodeDescriptor)(previous.descriptor, descriptor)))) {
|
|
1012
1041
|
throw new service_wire_m6a_codec_1.ServiceWireProtocolError(`RouteMesh peer '${descriptor.nodeRoutingId}' descriptor revision is stale or conflicting.`);
|
|
1013
1042
|
}
|
|
1014
1043
|
const result = this.topology.admit(descriptor, connection.connectionId, expected, connection.discriminator);
|
|
@@ -1019,7 +1048,8 @@ class RawServiceMeshRuntime {
|
|
|
1019
1048
|
this.monitorConnectionStates.set(descriptor.nodeRoutingId, connection.connectionId);
|
|
1020
1049
|
if (previous !== undefined && previous.connectionId !== connection.connectionId) {
|
|
1021
1050
|
const previousCandidate = this.connectionCandidates
|
|
1022
|
-
.get(descriptor.nodeRoutingId)
|
|
1051
|
+
.get(descriptor.nodeRoutingId)
|
|
1052
|
+
?.get(previous.connectionId);
|
|
1023
1053
|
if (previousCandidate !== undefined) {
|
|
1024
1054
|
this.removeConnectionCandidate(descriptor.nodeRoutingId, previousCandidate.connectionId);
|
|
1025
1055
|
}
|
|
@@ -1106,8 +1136,8 @@ class RawServiceMeshRuntime {
|
|
|
1106
1136
|
createUnresolvedConnectionCandidate(event) {
|
|
1107
1137
|
const connectionId = monitorConnectionId(event);
|
|
1108
1138
|
const local = this.topology.localDescriptor();
|
|
1109
|
-
const direction = this.endpointOnlyPeers.has(event.remoteAddress)
|
|
1110
|
-
|
|
1139
|
+
const direction = this.endpointOnlyPeers.has(event.remoteAddress) ||
|
|
1140
|
+
this.expectedPeerRoutingId(event.remoteAddress) !== undefined
|
|
1111
1141
|
? 'outbound'
|
|
1112
1142
|
: event.localAddress === local.advertisedEndpoint
|
|
1113
1143
|
? 'inbound'
|
|
@@ -1123,21 +1153,18 @@ class RawServiceMeshRuntime {
|
|
|
1123
1153
|
promoteUnresolvedConnectionCandidate(nodeRoutingId, advertisedEndpoint) {
|
|
1124
1154
|
const relevant = this.unresolvedConnectionCandidates
|
|
1125
1155
|
.map((candidate, index) => ({ candidate, index }))
|
|
1126
|
-
.filter(({ candidate }) => candidate.remoteAddress === advertisedEndpoint
|
|
1127
|
-
|| candidate.direction === 'inbound');
|
|
1156
|
+
.filter(({ candidate }) => candidate.remoteAddress === advertisedEndpoint || candidate.direction === 'inbound');
|
|
1128
1157
|
if (relevant.length === 0)
|
|
1129
1158
|
return undefined;
|
|
1130
|
-
const directions = new Set(relevant.map(value => value.candidate.direction));
|
|
1159
|
+
const directions = new Set(relevant.map((value) => value.candidate.direction));
|
|
1131
1160
|
const localRid = this.topology.localDescriptor().nodeRoutingId;
|
|
1132
1161
|
const preferredDirection = directions.has('inbound') && directions.has('outbound')
|
|
1133
1162
|
? localRid.localeCompare(nodeRoutingId) <= 0
|
|
1134
1163
|
? 'outbound'
|
|
1135
1164
|
: 'inbound'
|
|
1136
1165
|
: relevant.at(-1).candidate.direction;
|
|
1137
|
-
const selected = [...relevant]
|
|
1138
|
-
.
|
|
1139
|
-
.find(value => value.candidate.direction === preferredDirection)
|
|
1140
|
-
?? relevant.at(-1);
|
|
1166
|
+
const selected = [...relevant].reverse().find((value) => value.candidate.direction === preferredDirection) ??
|
|
1167
|
+
relevant.at(-1);
|
|
1141
1168
|
this.unresolvedConnectionCandidates.splice(selected.index, 1);
|
|
1142
1169
|
const initiator = selected.candidate.direction === 'outbound'
|
|
1143
1170
|
? localRid
|
|
@@ -1173,10 +1200,10 @@ class RawServiceMeshRuntime {
|
|
|
1173
1200
|
// A same-RID replacement is permitted only from a complete discovery
|
|
1174
1201
|
// fence. Manual/endpoint-only intent has no authority to replace a ready
|
|
1175
1202
|
// peer, and lifecycle generations are opaque equality tokens.
|
|
1176
|
-
return expected?.endpoint !== undefined
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1203
|
+
return (expected?.endpoint !== undefined &&
|
|
1204
|
+
expected.securityIdentity !== undefined &&
|
|
1205
|
+
expected.lifecycleGeneration !== undefined &&
|
|
1206
|
+
admitted.descriptor.lifecycleGeneration !== expected.lifecycleGeneration);
|
|
1180
1207
|
}
|
|
1181
1208
|
expectedPeerRoutingId(endpoint) {
|
|
1182
1209
|
for (const [nodeRoutingId, expected] of this.expectedPeers) {
|
|
@@ -1193,14 +1220,14 @@ class RawServiceMeshRuntime {
|
|
|
1193
1220
|
if (event.routingId === nodeRoutingId)
|
|
1194
1221
|
return true;
|
|
1195
1222
|
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
1196
|
-
return expected === undefined ||
|
|
1197
|
-
|
|
1223
|
+
return (expected === undefined ||
|
|
1224
|
+
expected.endpoint === undefined ||
|
|
1225
|
+
expected.endpoint === event.remoteAddress);
|
|
1198
1226
|
}
|
|
1199
1227
|
retireNotRequiredExpectedPeer(nodeRoutingId, advertisedEndpoint) {
|
|
1200
1228
|
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
1201
|
-
const endpoint = expected?.endpoint
|
|
1202
|
-
|
|
1203
|
-
&& this.endpointOnlyPeers.has(advertisedEndpoint)
|
|
1229
|
+
const endpoint = expected?.endpoint ??
|
|
1230
|
+
(advertisedEndpoint !== undefined && this.endpointOnlyPeers.has(advertisedEndpoint)
|
|
1204
1231
|
? advertisedEndpoint
|
|
1205
1232
|
: undefined);
|
|
1206
1233
|
if (endpoint !== undefined) {
|
|
@@ -1235,8 +1262,7 @@ class RawServiceMeshRuntime {
|
|
|
1235
1262
|
this.onPeerDisconnected?.(peer.descriptor.nodeRoutingId, peer.descriptor.advertisedEndpoint, peer.descriptor.lifecycleGeneration);
|
|
1236
1263
|
}
|
|
1237
1264
|
observeMonitorEvent(event) {
|
|
1238
|
-
const nodeRoutingId = event.routingId
|
|
1239
|
-
?? this.expectedPeerRoutingId(event.remoteAddress);
|
|
1265
|
+
const nodeRoutingId = event.routingId ?? this.expectedPeerRoutingId(event.remoteAddress);
|
|
1240
1266
|
if (nodeRoutingId === undefined)
|
|
1241
1267
|
return;
|
|
1242
1268
|
const connectionId = monitorConnectionId(event, nodeRoutingId);
|
|
@@ -1247,9 +1273,9 @@ class RawServiceMeshRuntime {
|
|
|
1247
1273
|
// allow a late stale READY to overwrite the admitted replacement.
|
|
1248
1274
|
return;
|
|
1249
1275
|
}
|
|
1250
|
-
if (event.event === MONITOR_DISCONNECTED
|
|
1251
|
-
|
|
1252
|
-
|
|
1276
|
+
if (event.event === MONITOR_DISCONNECTED &&
|
|
1277
|
+
this.monitorConnectionStates.get(nodeRoutingId) === connectionId &&
|
|
1278
|
+
this.topology.peer(nodeRoutingId)?.connectionId === connectionId) {
|
|
1253
1279
|
this.monitorConnectionStates.set(nodeRoutingId, null);
|
|
1254
1280
|
}
|
|
1255
1281
|
}
|
|
@@ -1307,11 +1333,7 @@ function isAlreadyDisconnectedError(error) {
|
|
|
1307
1333
|
}
|
|
1308
1334
|
function monitorConnectionId(event, resolvedNodeRoutingId = event.routingId ?? '') {
|
|
1309
1335
|
if (event.connectionId !== undefined && event.connectionId !== 0n) {
|
|
1310
|
-
return JSON.stringify([
|
|
1311
|
-
resolvedNodeRoutingId,
|
|
1312
|
-
'connection',
|
|
1313
|
-
event.connectionId.toString()
|
|
1314
|
-
]);
|
|
1336
|
+
return JSON.stringify([resolvedNodeRoutingId, 'connection', event.connectionId.toString()]);
|
|
1315
1337
|
}
|
|
1316
1338
|
return JSON.stringify([
|
|
1317
1339
|
// Monitor `value` is event-specific: CONNECTION_READY reports the
|
|
@@ -1324,8 +1346,8 @@ function monitorConnectionId(event, resolvedNodeRoutingId = event.routingId ?? '
|
|
|
1324
1346
|
]);
|
|
1325
1347
|
}
|
|
1326
1348
|
function sameMonitorConnection(left, right) {
|
|
1327
|
-
return monitorConnectionId(left) === monitorConnectionId(right)
|
|
1328
|
-
|
|
1349
|
+
return (monitorConnectionId(left) === monitorConnectionId(right) &&
|
|
1350
|
+
left.remoteAddress === right.remoteAddress);
|
|
1329
1351
|
}
|
|
1330
1352
|
function isConnectionReadyEdge(event) {
|
|
1331
1353
|
return event.flags === undefined
|
|
@@ -1339,21 +1361,20 @@ function describeInvalidAdmissionDescriptor(descriptor, expected, current) {
|
|
|
1339
1361
|
catch (error) {
|
|
1340
1362
|
return `descriptor validation: ${error instanceof Error ? error.message : String(error)}`;
|
|
1341
1363
|
}
|
|
1342
|
-
if (expected?.endpoint !== undefined
|
|
1343
|
-
&& descriptor.advertisedEndpoint !== expected.endpoint) {
|
|
1364
|
+
if (expected?.endpoint !== undefined && descriptor.advertisedEndpoint !== expected.endpoint) {
|
|
1344
1365
|
return `advertisedEndpoint expected='${expected.endpoint}' actual='${descriptor.advertisedEndpoint}'`;
|
|
1345
1366
|
}
|
|
1346
|
-
if (expected?.securityIdentity !== undefined
|
|
1347
|
-
|
|
1367
|
+
if (expected?.securityIdentity !== undefined &&
|
|
1368
|
+
descriptor.securityIdentity !== expected.securityIdentity) {
|
|
1348
1369
|
return `securityIdentity expected='${expected.securityIdentity}' actual='${descriptor.securityIdentity}'`;
|
|
1349
1370
|
}
|
|
1350
|
-
if (expected?.lifecycleGeneration !== undefined
|
|
1351
|
-
|
|
1371
|
+
if (expected?.lifecycleGeneration !== undefined &&
|
|
1372
|
+
descriptor.lifecycleGeneration !== expected.lifecycleGeneration) {
|
|
1352
1373
|
return `lifecycleGeneration expected=${expected.lifecycleGeneration} actual=${descriptor.lifecycleGeneration}`;
|
|
1353
1374
|
}
|
|
1354
|
-
if (current !== undefined
|
|
1355
|
-
|
|
1356
|
-
|
|
1375
|
+
if (current !== undefined &&
|
|
1376
|
+
current.lifecycleGeneration === descriptor.lifecycleGeneration &&
|
|
1377
|
+
descriptor.descriptorRevision > current.descriptorRevision) {
|
|
1357
1378
|
const immutableField = immutableDescriptorMismatch(current, descriptor);
|
|
1358
1379
|
if (immutableField !== undefined)
|
|
1359
1380
|
return immutableField;
|
|
@@ -1362,8 +1383,12 @@ function describeInvalidAdmissionDescriptor(descriptor, expected, current) {
|
|
|
1362
1383
|
}
|
|
1363
1384
|
function immutableDescriptorMismatch(current, descriptor) {
|
|
1364
1385
|
const fields = [
|
|
1365
|
-
'advertisedEndpoint',
|
|
1366
|
-
'
|
|
1386
|
+
'advertisedEndpoint',
|
|
1387
|
+
'securityIdentity',
|
|
1388
|
+
'applicationVersion',
|
|
1389
|
+
'objectRole',
|
|
1390
|
+
'activeCapacityLimit',
|
|
1391
|
+
'pendingCapacityLimit'
|
|
1367
1392
|
];
|
|
1368
1393
|
for (const field of fields) {
|
|
1369
1394
|
if (current[field] !== descriptor[field]) {
|
|
@@ -1373,8 +1398,8 @@ function immutableDescriptorMismatch(current, descriptor) {
|
|
|
1373
1398
|
if (JSON.stringify(current.protocolCapabilities) !== JSON.stringify(descriptor.protocolCapabilities)) {
|
|
1374
1399
|
return `protocolCapabilities changed within lifecycle expected=${JSON.stringify(current.protocolCapabilities)} actual=${JSON.stringify(descriptor.protocolCapabilities)}`;
|
|
1375
1400
|
}
|
|
1376
|
-
if (JSON.stringify(current.channels.map(channel => channel.name))
|
|
1377
|
-
|
|
1401
|
+
if (JSON.stringify(current.channels.map((channel) => channel.name)) !==
|
|
1402
|
+
JSON.stringify(descriptor.channels.map((channel) => channel.name))) {
|
|
1378
1403
|
return 'channels changed within lifecycle';
|
|
1379
1404
|
}
|
|
1380
1405
|
return undefined;
|