@zlink-systems/framework 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkMessage.js +5 -5
- package/dist/contracts/Configuration/CodecContentType.js +5 -7
- package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
- package/dist/contracts/Configuration/EndpointNotation.js +4 -8
- package/dist/contracts/Configuration/Registration.js +14 -11
- package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
- package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
- package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
- package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/location-store-integration.js +16 -16
- package/dist/nest-integration.js +17 -11
- package/dist/runtime/abort.js +9 -5
- package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
- package/dist/runtime/actors/actor-authority-publication.js +18 -17
- package/dist/runtime/actors/actor-client.js +83 -63
- package/dist/runtime/actors/actor-context.js +24 -18
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-local-native-join.js +18 -19
- package/dist/runtime/actors/actor-mailbox.js +1 -1
- package/dist/runtime/actors/actor-message-follow-context.js +24 -21
- package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
- package/dist/runtime/actors/actor-remote-joiner.js +20 -17
- package/dist/runtime/actors/actor-remote-wire.js +6 -7
- package/dist/runtime/actors/actor-runtime-state.js +87 -81
- package/dist/runtime/actors/actor-transfer-registry.js +3 -5
- package/dist/runtime/actors/bound-session-wire.js +14 -9
- package/dist/runtime/actors/deferred-join-accepted-journal.js +158 -124
- package/dist/runtime/actors/index.js +2 -5
- package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
- package/dist/runtime/actors/post-commit-actor-location.js +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
- package/dist/runtime/admission.js +2 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
- package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
- package/dist/runtime/backend/mesh-completion-table.js +1 -3
- package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
- package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +116 -113
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
- package/dist/runtime/backend/runtime-message.js +3 -3
- package/dist/runtime/backend/runtime-values.d.ts +2 -2
- package/dist/runtime/backend/runtime-values.js +4 -5
- package/dist/runtime/channels/channel-clients.js +27 -24
- package/dist/runtime/channels/channel-dispatch-pipeline.js +10 -18
- package/dist/runtime/channels/channel-dispatch-services.js +7 -4
- package/dist/runtime/channels/channel-dispatchers.js +9 -9
- package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
- package/dist/runtime/channels/channel-envelope.js +83 -47
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-receive-loops.js +20 -22
- package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
- package/dist/runtime/channels/channel-runtime-manager.js +18 -9
- package/dist/runtime/channels/channel-socket-registry.js +126 -123
- package/dist/runtime/channels/channel-transports.js +43 -33
- package/dist/runtime/channels/client-server-location-runtime.js +32 -40
- package/dist/runtime/channels/client-server-service-wire.js +29 -22
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -7
- package/dist/runtime/channels/fanout-location-runtime.js +34 -47
- package/dist/runtime/channels/fanout-service-wire.js +3 -5
- package/dist/runtime/channels/local-spot-route-transport.js +7 -1
- package/dist/runtime/channels/route-member-snapshot.js +3 -3
- package/dist/runtime/channels/source-spot-router.js +6 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
- package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +47 -39
- package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
- package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
- package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
- package/dist/runtime/execution/index.js +7 -6
- package/dist/runtime/execution/serial-execution-queue.js +12 -18
- package/dist/runtime/execution/state-lane.js +2 -2
- package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -23
- package/dist/runtime/foundation/event-loop-resources.js +4 -4
- package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +136 -136
- package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
- package/dist/runtime/foundation/runtime-state-projections.js +22 -11
- package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
- package/dist/runtime/foundation/service-discovery-registry.js +35 -33
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
- package/dist/runtime/foundation/service-liveness-registry.js +16 -12
- package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
- package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
- package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.js +416 -438
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.js +96 -95
- package/dist/runtime/foundation/service-weighted-selection.js +6 -11
- package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
- package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
- package/dist/runtime/framework-errors-internal.js +7 -10
- package/dist/runtime/handlers/handler-instance-scope.js +4 -5
- package/dist/runtime/handlers/index.js +3 -1
- package/dist/runtime/host/actor-packet-relay.js +74 -70
- package/dist/runtime/host/actor-placement-coordinator.js +29 -31
- package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
- package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
- package/dist/runtime/host/actor-transfer-runtime.js +176 -153
- package/dist/runtime/host/application-job-queue.js +18 -22
- package/dist/runtime/host/bound-session-relay.js +3 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
- package/dist/runtime/host/host-capacity-status.js +8 -4
- package/dist/runtime/host/index.js +244 -227
- package/dist/runtime/host/instance-activation-authority.js +93 -96
- package/dist/runtime/host/location-runtime-owner.js +16 -14
- package/dist/runtime/host/mesh-router-resolver.js +11 -13
- package/dist/runtime/host/relocation-direct-transfer.js +10 -9
- package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
- package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
- package/dist/runtime/host/remote-bound-session-relay.js +97 -73
- package/dist/runtime/host/route-mesh-runtime.js +64 -69
- package/dist/runtime/host/runtime-shutdown.js +1 -2
- package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
- package/dist/runtime/host/spot-address-transport.js +69 -71
- package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
- package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
- package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
- package/dist/runtime/locations/actor-location-claims.js +26 -20
- package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
- package/dist/runtime/locations/authority-key-codec.js +7 -7
- package/dist/runtime/locations/auto-connect-loop.js +3 -3
- package/dist/runtime/locations/auto-connect-planner.js +25 -19
- package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
- package/dist/runtime/locations/in-memory-authority-store.js +128 -118
- package/dist/runtime/locations/in-memory-location-store.js +195 -168
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
- package/dist/runtime/locations/key-codec.js +1 -1
- package/dist/runtime/locations/lease-tracker.js +23 -21
- package/dist/runtime/locations/lifecycle.js +4 -5
- package/dist/runtime/locations/location-store-repository.js +368 -324
- package/dist/runtime/locations/opaque-record-key.js +2 -2
- package/dist/runtime/locations/resolvers.js +73 -82
- package/dist/runtime/locations/runtime.js +68 -63
- package/dist/runtime/locations/spot-location-claims.js +39 -35
- package/dist/runtime/messaging/framework-json-v1.js +7 -7
- package/dist/runtime/messaging/packet-name.js +7 -6
- package/dist/runtime/messaging/payload-codec.js +21 -18
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
- package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
- package/dist/runtime/routing-id.js +3 -5
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
- package/dist/runtime/spots/index.js +208 -219
- package/dist/runtime/spots/spot-activation-registry.js +15 -14
- package/dist/runtime/spots/spot-activation-state.js +17 -15
- package/dist/runtime/spots/spot-activation.js +33 -16
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
- package/dist/runtime/spots/spot-actor-membership.js +1 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +23 -20
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -10
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
- package/dist/runtime/spots/spot-closing.js +3 -7
- package/dist/runtime/spots/spot-context.js +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +13 -14
- package/dist/runtime/spots/spot-handle.js +6 -3
- package/dist/runtime/spots/spot-handler-registry.js +12 -12
- package/dist/runtime/spots/spot-manager-public.js +5 -6
- package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
- package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +74 -85
- package/dist/runtime/spots/spot-outbound.js +10 -14
- package/dist/runtime/spots/spot-remote-codec.js +22 -26
- package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
- package/dist/runtime/spots/spot-route-packet-dispatch.js +16 -14
- package/dist/runtime/spots/spot-route-replies.js +4 -6
- package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
- package/dist/runtime/spots/spot-serial-executor.js +5 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
- package/dist/runtime/spots/spot-subscription-dispatch.js +5 -5
- package/dist/runtime/spots/spot-timer.js +25 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +98 -107
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +18 -16
- package/dist/runtime/streams/bound-session-service.js +8 -9
- package/dist/runtime/streams/index.js +20 -19
- package/dist/runtime/streams/managed-stream.js +32 -30
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.js +29 -18
- package/dist/runtime/streams/session-actor-coordinator.js +34 -37
- package/dist/runtime/streams/session-context.js +30 -28
- package/dist/runtime/streams/session-provider.js +2 -2
- package/dist/runtime/streams/session-serial-executor.js +1 -2
- package/dist/runtime/streams/stream-frame-factory.js +11 -5
- package/dist/runtime/streams/stream-session-runtime.js +70 -66
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +2 -2
- package/src/contracts/Channels/RouteCalls.ts +6 -1
- package/src/contracts/Common/ZLinkMessage.ts +5 -5
- package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
- package/src/contracts/Configuration/Builders.ts +14 -14
- package/src/contracts/Configuration/CodecContentType.ts +8 -10
- package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
- package/src/contracts/Configuration/EndpointNotation.ts +11 -11
- package/src/contracts/Configuration/ObjectRoles.ts +1 -3
- package/src/contracts/Configuration/Registration.ts +46 -17
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
- package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
- package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
- package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
- package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
- package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
- package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
- package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -6
- package/src/contracts/Errors/index.ts +1 -4
- package/src/contracts/Handlers/Attributes.ts +15 -9
- package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
- package/src/contracts/Handlers/JsonContract.ts +53 -19
- package/src/contracts/Locations/ActorTransfer.ts +1 -5
- package/src/contracts/Locations/Authority.ts +4 -11
- package/src/contracts/Locations/Keys.ts +6 -1
- package/src/contracts/Locations/Options.ts +3 -2
- package/src/contracts/Locations/RelocationStore.ts +1 -4
- package/src/contracts/Locations/Resolvers.ts +5 -5
- package/src/contracts/Locations/RuntimeQuery.ts +6 -2
- package/src/contracts/Locations/Stores.ts +1 -2
- package/src/contracts/Locations/index.ts +2 -8
- package/src/contracts/RouteMesh/Contracts.ts +1 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
- package/src/contracts/Spots/Contracts.ts +2 -8
- package/src/contracts/Spots/SpotKind.ts +16 -8
- package/src/contracts/Spots/ZLinkSpot.ts +8 -11
- package/src/contracts/Streams/IZLinkSession.ts +0 -1
- package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
- package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
- package/src/internal.ts +5 -4
- package/src/location-store-integration.ts +24 -16
- package/src/nest-integration.ts +40 -25
- package/src/runtime/abort.ts +10 -4
- package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
- package/src/runtime/actors/actor-authority-publication.ts +92 -77
- package/src/runtime/actors/actor-client.ts +162 -133
- package/src/runtime/actors/actor-context.ts +138 -130
- package/src/runtime/actors/actor-creation.ts +47 -44
- package/src/runtime/actors/actor-execution-context.ts +6 -4
- package/src/runtime/actors/actor-handoff.ts +269 -293
- package/src/runtime/actors/actor-join-deferred-scope.ts +5 -4
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
- package/src/runtime/actors/actor-local-native-join.ts +131 -159
- package/src/runtime/actors/actor-mailbox.ts +16 -19
- package/src/runtime/actors/actor-message-follow-context.ts +46 -36
- package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
- package/src/runtime/actors/actor-remote-joiner.ts +50 -54
- package/src/runtime/actors/actor-remote-wire.ts +9 -13
- package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
- package/src/runtime/actors/actor-runtime-state.ts +127 -124
- package/src/runtime/actors/actor-transfer-registry.ts +9 -14
- package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
- package/src/runtime/actors/bound-session-wire.ts +37 -17
- package/src/runtime/actors/deferred-join-accepted-journal.ts +351 -320
- package/src/runtime/actors/index.ts +43 -86
- package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
- package/src/runtime/actors/post-commit-actor-location.ts +30 -23
- package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
- package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
- package/src/runtime/admission.ts +9 -9
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
- package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
- package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
- package/src/runtime/backend/contracts/index.ts +73 -52
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
- package/src/runtime/backend/mesh-completion-table.ts +6 -9
- package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
- package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
- package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
- package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +335 -383
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
- package/src/runtime/backend/runtime-message.ts +5 -3
- package/src/runtime/backend/runtime-values.ts +10 -7
- package/src/runtime/channels/channel-autoconnect.ts +1 -4
- package/src/runtime/channels/channel-clients.ts +93 -73
- package/src/runtime/channels/channel-dispatch-pipeline.ts +40 -42
- package/src/runtime/channels/channel-dispatch-services.ts +51 -49
- package/src/runtime/channels/channel-dispatchers.ts +152 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
- package/src/runtime/channels/channel-envelope.ts +256 -150
- package/src/runtime/channels/channel-multipart.ts +13 -5
- package/src/runtime/channels/channel-outbound-operations.ts +37 -41
- package/src/runtime/channels/channel-receive-loops.ts +102 -98
- package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
- package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
- package/src/runtime/channels/channel-runtime-manager.ts +63 -37
- package/src/runtime/channels/channel-socket-options.ts +3 -10
- package/src/runtime/channels/channel-socket-registry.ts +331 -273
- package/src/runtime/channels/channel-transports.ts +215 -197
- package/src/runtime/channels/client-server-location-runtime.ts +116 -100
- package/src/runtime/channels/client-server-service-wire.ts +37 -36
- package/src/runtime/channels/dispatch-error-reporter.ts +11 -8
- package/src/runtime/channels/fanout-location-runtime.ts +91 -94
- package/src/runtime/channels/fanout-service-wire.ts +5 -12
- package/src/runtime/channels/handler-filter-scope.ts +1 -4
- package/src/runtime/channels/index.ts +1 -4
- package/src/runtime/channels/local-spot-route-transport.ts +20 -5
- package/src/runtime/channels/route-member-snapshot.ts +11 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
- package/src/runtime/channels/source-spot-router.ts +26 -22
- package/src/runtime/channels/spot-direct-envelope.ts +10 -8
- package/src/runtime/channels/spot-node-route-transport.ts +13 -16
- package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
- package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
- package/src/runtime/codecs/index.ts +3 -2
- package/src/runtime/diagnostics/flow-context.ts +12 -3
- package/src/runtime/diagnostics/index.ts +96 -61
- package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
- package/src/runtime/diagnostics/message-flow.ts +95 -76
- package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
- package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
- package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
- package/src/runtime/execution/index.ts +18 -26
- package/src/runtime/execution/serial-execution-queue.ts +31 -40
- package/src/runtime/execution/state-lane.ts +2 -2
- package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -51
- package/src/runtime/foundation/event-loop-resources.ts +8 -4
- package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
- package/src/runtime/foundation/operation-identity.ts +1 -2
- package/src/runtime/foundation/operation-registry.ts +8 -2
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +312 -385
- package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
- package/src/runtime/foundation/runtime-state-projections.ts +24 -23
- package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
- package/src/runtime/foundation/service-discovery-registry.ts +67 -59
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
- package/src/runtime/foundation/service-liveness-registry.ts +18 -13
- package/src/runtime/foundation/service-mailbox.ts +14 -14
- package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
- package/src/runtime/foundation/service-metadata-codec.ts +2 -9
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
- package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
- package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
- package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
- package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1174 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +157 -159
- package/src/runtime/foundation/service-weighted-selection.ts +9 -15
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
- package/src/runtime/framework-errors-internal.ts +31 -30
- package/src/runtime/handlers/handler-instance-scope.ts +18 -29
- package/src/runtime/handlers/index.ts +18 -8
- package/src/runtime/host/actor-packet-relay.ts +290 -261
- package/src/runtime/host/actor-placement-coordinator.ts +165 -150
- package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
- package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
- package/src/runtime/host/actor-transfer-runtime.ts +391 -395
- package/src/runtime/host/application-job-queue.ts +32 -48
- package/src/runtime/host/bound-session-relay.ts +7 -9
- package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
- package/src/runtime/host/host-capacity-status.ts +10 -9
- package/src/runtime/host/index.ts +861 -789
- package/src/runtime/host/instance-activation-authority.ts +125 -143
- package/src/runtime/host/location-runtime-owner.ts +38 -26
- package/src/runtime/host/mesh-router-resolver.ts +30 -23
- package/src/runtime/host/relocation-direct-transfer.ts +15 -15
- package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
- package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
- package/src/runtime/host/remote-bound-session-relay.ts +274 -247
- package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
- package/src/runtime/host/route-mesh-runtime.ts +227 -181
- package/src/runtime/host/runtime-shutdown.ts +4 -3
- package/src/runtime/host/service-relocation-control.ts +14 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
- package/src/runtime/host/spot-address-transport.ts +284 -237
- package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
- package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
- package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
- package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
- package/src/runtime/locations/actor-location-claims.ts +61 -49
- package/src/runtime/locations/actor-session-route-claims.ts +1 -4
- package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
- package/src/runtime/locations/authority-key-codec.ts +13 -10
- package/src/runtime/locations/auto-connect-loop.ts +14 -11
- package/src/runtime/locations/auto-connect-planner.ts +42 -31
- package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
- package/src/runtime/locations/canonical-codec.ts +3 -1
- package/src/runtime/locations/creation-operation-id.ts +4 -3
- package/src/runtime/locations/domain-store-contract.ts +13 -7
- package/src/runtime/locations/in-memory-authority-store.ts +232 -199
- package/src/runtime/locations/in-memory-location-store.ts +432 -250
- package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
- package/src/runtime/locations/internal-store-contracts.ts +95 -38
- package/src/runtime/locations/key-codec.ts +3 -4
- package/src/runtime/locations/lease-tracker.ts +36 -27
- package/src/runtime/locations/lifecycle-runtime.ts +15 -3
- package/src/runtime/locations/lifecycle.ts +33 -28
- package/src/runtime/locations/location-store-repository.ts +1329 -1185
- package/src/runtime/locations/opaque-record-key.ts +4 -9
- package/src/runtime/locations/resolvers.ts +201 -178
- package/src/runtime/locations/runtime.ts +251 -159
- package/src/runtime/locations/spot-location-claims.ts +110 -112
- package/src/runtime/messaging/creation-payload-codec.ts +4 -1
- package/src/runtime/messaging/framework-json-v1.ts +34 -15
- package/src/runtime/messaging/packet-name.ts +8 -6
- package/src/runtime/messaging/payload-codec.ts +70 -50
- package/src/runtime/messaging/submission-result.ts +6 -9
- package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/routing-id.ts +10 -7
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
- package/src/runtime/spots/index.ts +593 -563
- package/src/runtime/spots/spot-activation-registry.ts +38 -34
- package/src/runtime/spots/spot-activation-state.ts +43 -51
- package/src/runtime/spots/spot-activation.ts +179 -116
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
- package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
- package/src/runtime/spots/spot-actor-membership.ts +25 -27
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +184 -153
- package/src/runtime/spots/spot-actor-packet-drain.ts +54 -42
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
- package/src/runtime/spots/spot-closing.ts +11 -12
- package/src/runtime/spots/spot-context.ts +46 -26
- package/src/runtime/spots/spot-entry-activation.ts +84 -65
- package/src/runtime/spots/spot-handle.ts +17 -15
- package/src/runtime/spots/spot-handler-registry.ts +44 -31
- package/src/runtime/spots/spot-location-claim.ts +5 -4
- package/src/runtime/spots/spot-manager-public.ts +62 -82
- package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
- package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
- package/src/runtime/spots/spot-node-runtime-manager.ts +230 -221
- package/src/runtime/spots/spot-outbound.ts +47 -59
- package/src/runtime/spots/spot-publisher-transport.ts +5 -4
- package/src/runtime/spots/spot-remote-codec.ts +66 -65
- package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
- package/src/runtime/spots/spot-route-packet-dispatch.ts +128 -95
- package/src/runtime/spots/spot-route-replies.ts +23 -24
- package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
- package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +11 -17
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
- package/src/runtime/spots/spot-routing-internal.ts +1 -4
- package/src/runtime/spots/spot-runtime-ports.ts +5 -5
- package/src/runtime/spots/spot-serial-executor.ts +5 -9
- package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
- package/src/runtime/spots/spot-subscription-dispatch.ts +56 -46
- package/src/runtime/spots/spot-timer.ts +98 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +277 -235
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +7 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +53 -51
- package/src/runtime/streams/bound-session-response-target.ts +29 -8
- package/src/runtime/streams/bound-session-service.ts +39 -39
- package/src/runtime/streams/index.ts +176 -100
- package/src/runtime/streams/managed-stream.ts +98 -87
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +73 -43
- package/src/runtime/streams/session-actor-coordinator.ts +97 -89
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +66 -48
- package/src/runtime/streams/session-provider.ts +5 -7
- package/src/runtime/streams/session-serial-executor.ts +7 -6
- package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
- package/src/runtime/streams/stream-frame-factory.ts +55 -38
- package/src/runtime/streams/stream-session-runtime.ts +268 -210
- package/src/runtime/workers/index.ts +68 -29
|
@@ -17,15 +17,9 @@ import {
|
|
|
17
17
|
type ReceiveRecord
|
|
18
18
|
} from '../foundation/service-runtime-contracts';
|
|
19
19
|
import type { ServiceMessageFollowRecord } from '../foundation/service-stateful-wire-codec';
|
|
20
|
-
import {
|
|
21
|
-
runtimeAcceptsWork,
|
|
22
|
-
runtimeStateIsReady
|
|
23
|
-
} from '../foundation/runtime-state-projections';
|
|
20
|
+
import { runtimeAcceptsWork, runtimeStateIsReady } from '../foundation/runtime-state-projections';
|
|
24
21
|
import { createDeadlineExceededError, isDeadlineExceededError } from '../abort';
|
|
25
|
-
import {
|
|
26
|
-
meshActorSessionNodeAdapter,
|
|
27
|
-
ZLinkNodeBackendAdapterFactory
|
|
28
|
-
} from '../backend';
|
|
22
|
+
import { meshActorSessionNodeAdapter, ZLinkNodeBackendAdapterFactory } from '../backend';
|
|
29
23
|
import type {
|
|
30
24
|
ZLinkBackendAdapterFactory,
|
|
31
25
|
ZLinkBackendContext,
|
|
@@ -49,9 +43,7 @@ import type {
|
|
|
49
43
|
ZLinkFrameworkTerminationResult,
|
|
50
44
|
ZLinkRouteMeshRuntime
|
|
51
45
|
} from '../../contracts';
|
|
52
|
-
import type {
|
|
53
|
-
ZLinkLocationOwnerToken
|
|
54
|
-
} from '../../contracts/Locations';
|
|
46
|
+
import type { ZLinkLocationOwnerToken } from '../../contracts/Locations';
|
|
55
47
|
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
56
48
|
import type { Type } from '../../contracts/Common/CoreTypes';
|
|
57
49
|
import type { ZLinkRuntimeEventPublisher } from '../diagnostics';
|
|
@@ -90,9 +82,7 @@ import {
|
|
|
90
82
|
encodeChannelErrorReplyParts,
|
|
91
83
|
encodeChannelReplyParts
|
|
92
84
|
} from '../channels/channel-envelope';
|
|
93
|
-
import {
|
|
94
|
-
ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET
|
|
95
|
-
} from '../actors';
|
|
85
|
+
import { ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET } from '../actors';
|
|
96
86
|
import {
|
|
97
87
|
ZLINK_INTERNAL_ACTOR_TRANSPORT_DELIVERY_GATE,
|
|
98
88
|
type ZLinkInternalActorTransportDeliveryGate
|
|
@@ -101,10 +91,7 @@ import {
|
|
|
101
91
|
ZLINK_INTERNAL_APPLICATION_JOB_QUEUE_HANDLER_START_GATE,
|
|
102
92
|
type ZLinkInternalApplicationJobQueueHandlerStartGate
|
|
103
93
|
} from '../application-jobs/application-job-queue-handler-start-gate';
|
|
104
|
-
import {
|
|
105
|
-
ZLinkFrameworkExecutionState,
|
|
106
|
-
ZLinkRuntimeTaskErrorSink
|
|
107
|
-
} from '../execution';
|
|
94
|
+
import { ZLinkFrameworkExecutionState, ZLinkRuntimeTaskErrorSink } from '../execution';
|
|
108
95
|
import {
|
|
109
96
|
createDiagnosticsContext,
|
|
110
97
|
createInboundFlow,
|
|
@@ -130,14 +117,8 @@ import {
|
|
|
130
117
|
type ZLinkDetachedTaskRunner,
|
|
131
118
|
type ZLinkSpotManagerOptions
|
|
132
119
|
} from '../spots';
|
|
133
|
-
import type {
|
|
134
|
-
|
|
135
|
-
ZLinkActorManagerOptions
|
|
136
|
-
} from '../actors';
|
|
137
|
-
import {
|
|
138
|
-
messageFollowOwnerNodeRid,
|
|
139
|
-
ownerFence
|
|
140
|
-
} from '../actors/actor-message-follow-context';
|
|
120
|
+
import type { DefaultZLinkActorManager, ZLinkActorManagerOptions } from '../actors';
|
|
121
|
+
import { messageFollowOwnerNodeRid, ownerFence } from '../actors/actor-message-follow-context';
|
|
141
122
|
import {
|
|
142
123
|
DefaultZLinkActorClient,
|
|
143
124
|
ZLinkActorHandoffCoordinator,
|
|
@@ -171,14 +152,8 @@ import { ZLinkEntryActorRuntimeService } from './entry-actor-runtime';
|
|
|
171
152
|
import { ZLinkLocationRuntimeOwner } from './location-runtime-owner';
|
|
172
153
|
import { MeshRouterResolver } from './mesh-router-resolver';
|
|
173
154
|
import { ZLinkBoundSessionRelay } from './bound-session-relay';
|
|
174
|
-
import {
|
|
175
|
-
|
|
176
|
-
encodeRoutingIdStorageHex,
|
|
177
|
-
routingIdsEqual
|
|
178
|
-
} from '../routing-id';
|
|
179
|
-
import {
|
|
180
|
-
rewriteServiceAuthorityOwner
|
|
181
|
-
} from '../foundation/service-authority-payload-codec';
|
|
155
|
+
import { decodeRoutingId, encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
|
|
156
|
+
import { rewriteServiceAuthorityOwner } from '../foundation/service-authority-payload-codec';
|
|
182
157
|
import {
|
|
183
158
|
replaceServiceRelocationAuthorityApplicationPayload,
|
|
184
159
|
serviceRelocationAuthorityApplicationPayload
|
|
@@ -188,10 +163,7 @@ import { ZLinkChannelRuntimeOptionsFactory } from './channel-runtime-options-fac
|
|
|
188
163
|
import { ZLinkSpotNodeRuntimeOptionsFactory } from './spot-node-runtime-options-factory';
|
|
189
164
|
import { rollbackRuntimeStart, stopRuntimeParts } from './runtime-shutdown';
|
|
190
165
|
import { ZLinkRuntimeAdmissionGate } from '../admission';
|
|
191
|
-
import {
|
|
192
|
-
ZLinkRetiringRollbackError,
|
|
193
|
-
ZLinkRouteMeshRuntimeCoordinator
|
|
194
|
-
} from './route-mesh-runtime';
|
|
166
|
+
import { ZLinkRetiringRollbackError, ZLinkRouteMeshRuntimeCoordinator } from './route-mesh-runtime';
|
|
195
167
|
import { ZLinkConfigurationException } from '../../contracts/Configuration/ConfigurationException';
|
|
196
168
|
import { ZLinkStatefulAuthorityRouteRuntime } from './stateful-authority-route-runtime';
|
|
197
169
|
import { ZLinkInstanceActivationAuthority } from './instance-activation-authority';
|
|
@@ -199,10 +171,7 @@ import type {
|
|
|
199
171
|
ServiceAsyncInstanceActivationAuthority,
|
|
200
172
|
ServiceInstanceApplicationLifecycle
|
|
201
173
|
} from '../foundation/service-stateful-runtime';
|
|
202
|
-
import {
|
|
203
|
-
hasObjectClientCapability,
|
|
204
|
-
ZLinkHostSpotAddressTransport
|
|
205
|
-
} from './spot-address-transport';
|
|
174
|
+
import { hasObjectClientCapability, ZLinkHostSpotAddressTransport } from './spot-address-transport';
|
|
206
175
|
import { ZLinkUserSpotCreationCoordinator } from './user-spot-creation-coordinator';
|
|
207
176
|
import { ZLinkActorPlacementCoordinator } from './actor-placement-coordinator';
|
|
208
177
|
import {
|
|
@@ -240,10 +209,9 @@ export interface ZLinkFrameworkRuntimeHostOptions {
|
|
|
240
209
|
readonly runtimeEventPublisher?: ZLinkRuntimeEventPublisher;
|
|
241
210
|
}
|
|
242
211
|
|
|
243
|
-
export class ZLinkFrameworkRuntimeHost
|
|
244
|
-
ZLinkFrameworkRuntimeLifecycle,
|
|
245
|
-
|
|
246
|
-
ZLinkMessageFlowControl {
|
|
212
|
+
export class ZLinkFrameworkRuntimeHost
|
|
213
|
+
implements ZLinkFrameworkRuntimeLifecycle, ZLinkFrameworkRuntime, ZLinkMessageFlowControl
|
|
214
|
+
{
|
|
247
215
|
private readonly backendAdapterFactory: ZLinkBackendAdapterFactory;
|
|
248
216
|
private readonly lifecycleSink?: string[];
|
|
249
217
|
private executionState?: ZLinkFrameworkExecutionState;
|
|
@@ -285,7 +253,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
285
253
|
private readonly metrics: ZLinkRuntimeMetrics;
|
|
286
254
|
private readonly applicationJobQueue: ApplicationJobQueue;
|
|
287
255
|
private readonly capacityStatus: HostCapacityStatusProjection;
|
|
288
|
-
private readonly metricRegistrations: import('../diagnostics').ZLinkRuntimeMetricRegistration[] =
|
|
256
|
+
private readonly metricRegistrations: import('../diagnostics').ZLinkRuntimeMetricRegistration[] =
|
|
257
|
+
[];
|
|
289
258
|
private readonly admission = new ZLinkRuntimeAdmissionGate(() => this.ownerAdmissionOpen());
|
|
290
259
|
private cachedLocationSpotRouteResolver?: ZLinkSpotRouteResolver;
|
|
291
260
|
private actorClientLocationResolver?: ZLinkStoreLocationResolvers;
|
|
@@ -294,7 +263,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
294
263
|
private readonly messageFlowModeCell: ZLinkMessageFlowModeCell = {
|
|
295
264
|
mode: 'errors'
|
|
296
265
|
};
|
|
297
|
-
private readonly dispatchErrorReporters = new WeakMap<
|
|
266
|
+
private readonly dispatchErrorReporters = new WeakMap<
|
|
267
|
+
ZLinkDispatchErrorSink,
|
|
268
|
+
ZLinkDispatchErrorReporter
|
|
269
|
+
>();
|
|
298
270
|
private readonly runtimeOrPreStartErrorSink: ZLinkDispatchErrorSink = {
|
|
299
271
|
reportRuntimeTaskException: (taskName: string, error: unknown) =>
|
|
300
272
|
(this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException(taskName, error)
|
|
@@ -303,11 +275,14 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
303
275
|
private readonly preStartErrorSink = new ZLinkRuntimeTaskErrorSink();
|
|
304
276
|
readonly channelTransport = () => this.channelRuntime;
|
|
305
277
|
readonly channelRuntimeOptions = new DefaultZLinkChannelRuntimeOptions(() => this.channelRuntime);
|
|
306
|
-
readonly routeMeshRuntimeOptions =
|
|
307
|
-
|
|
278
|
+
readonly routeMeshRuntimeOptions = new DefaultZLinkRouteMeshRuntimeOptions(
|
|
279
|
+
() => this.spotNodeRuntime
|
|
280
|
+
);
|
|
308
281
|
readonly routeTransport: ZLinkRuntimeRouteTransport;
|
|
309
282
|
readonly spotAddressTransport: ZLinkHostSpotAddressTransport;
|
|
310
|
-
readonly spotPublisherTransport = new ZLinkRuntimeSpotPublisherTransport(
|
|
283
|
+
readonly spotPublisherTransport = new ZLinkRuntimeSpotPublisherTransport(
|
|
284
|
+
() => this.spotNodeRuntime
|
|
285
|
+
);
|
|
311
286
|
readonly streamBindingRuntime: ZLinkStreamBindingRuntime;
|
|
312
287
|
readonly boundSessionFactory: DefaultZLinkBoundSessionFactory;
|
|
313
288
|
readonly spotRouterChannelIdForMesh: (meshName: string) => string;
|
|
@@ -315,23 +290,29 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
315
290
|
readonly clientServerRuntime: ZLinkClientServerRuntime;
|
|
316
291
|
readonly fanoutRuntime: ZLinkFanoutRuntime;
|
|
317
292
|
private readonly routeMeshCoordinator: ZLinkRouteMeshRuntimeCoordinator;
|
|
318
|
-
constructor(
|
|
293
|
+
constructor(
|
|
294
|
+
readonly options: ZLinkFrameworkRuntimeHostOptions,
|
|
295
|
+
internalOptions?: unknown
|
|
296
|
+
) {
|
|
319
297
|
this.backendAdapterFactory = resolveBackendAdapterFactory(internalOptions);
|
|
320
298
|
this.lifecycleSink = options.lifecycleSink;
|
|
321
|
-
this.runtimeEventPublisher =
|
|
299
|
+
this.runtimeEventPublisher =
|
|
300
|
+
options.runtimeEventPublisher ?? new DefaultZLinkRuntimeEventPublisher();
|
|
322
301
|
this.metrics = new ZLinkRuntimeMetrics(options.registration.metrics?.meterProvider);
|
|
323
302
|
this.applicationJobQueue = new ApplicationJobQueue(
|
|
324
|
-
resolveApplicationJobQueueConfiguration(
|
|
325
|
-
options.registration.
|
|
326
|
-
() => nodeEffectiveProcessorCount(options.registration.worker?.maxThreads)
|
|
303
|
+
resolveApplicationJobQueueConfiguration(options.registration.applicationJobQueue, () =>
|
|
304
|
+
nodeEffectiveProcessorCount(options.registration.worker?.maxThreads)
|
|
327
305
|
),
|
|
328
306
|
undefined,
|
|
329
307
|
() => {
|
|
330
308
|
try {
|
|
331
|
-
return
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
309
|
+
return (
|
|
310
|
+
this.options.providerResolver
|
|
311
|
+
?.get?.(
|
|
312
|
+
ZLINK_INTERNAL_APPLICATION_JOB_QUEUE_HANDLER_START_GATE as unknown as Type<ZLinkInternalApplicationJobQueueHandlerStartGate>
|
|
313
|
+
)
|
|
314
|
+
?.shouldHoldPermitBeforeHandler() === true
|
|
315
|
+
);
|
|
335
316
|
} catch {
|
|
336
317
|
return false;
|
|
337
318
|
}
|
|
@@ -352,8 +333,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
352
333
|
this.meshRouters = new MeshRouterResolver(options.registration);
|
|
353
334
|
this.spotRouterChannelIdForMesh = this.meshRouters.spotRouterChannelIdByMesh();
|
|
354
335
|
const sendTimeoutMsForSpotMesh = (meshName: string): number =>
|
|
355
|
-
options.registration.spotNodes.get(meshName)?.router?.sendTimeoutMs
|
|
356
|
-
|
|
336
|
+
options.registration.spotNodes.get(meshName)?.router?.sendTimeoutMs ??
|
|
337
|
+
LEGACY_MESH_SEND_TIMEOUT_MS;
|
|
357
338
|
const sendTimeoutMsForSpotRouteChannel = (routeChannelId: string): number => {
|
|
358
339
|
const routeChannel = options.registration.routeChannelOptions.get(routeChannelId);
|
|
359
340
|
if (routeChannel !== undefined) {
|
|
@@ -363,11 +344,11 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
363
344
|
};
|
|
364
345
|
const defaultSpotSendTimeoutMs = Math.max(
|
|
365
346
|
LEGACY_MESH_SEND_TIMEOUT_MS,
|
|
366
|
-
...[...options.registration.spotNodes.values()].map(
|
|
367
|
-
node.router?.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS
|
|
347
|
+
...[...options.registration.spotNodes.values()].map(
|
|
348
|
+
(node) => node.router?.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS
|
|
368
349
|
),
|
|
369
|
-
...[...options.registration.routeChannelOptions.values()].map(
|
|
370
|
-
route.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS
|
|
350
|
+
...[...options.registration.routeChannelOptions.values()].map(
|
|
351
|
+
(route) => route.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS
|
|
371
352
|
)
|
|
372
353
|
);
|
|
373
354
|
this.routeTransport = new ZLinkRuntimeRouteTransport(
|
|
@@ -377,17 +358,17 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
377
358
|
{ serializers: options.registration.messageSerializers },
|
|
378
359
|
(meshName, targetNodeRid) =>
|
|
379
360
|
this.meshRouters.classifyManualNodeTarget(meshName, targetNodeRid),
|
|
380
|
-
(meshName, sourceNodeRid, parts) =>
|
|
381
|
-
this.submitLocalMeshRoute(meshName, sourceNodeRid, parts),
|
|
361
|
+
(meshName, sourceNodeRid, parts) => this.submitLocalMeshRoute(meshName, sourceNodeRid, parts),
|
|
382
362
|
this.metrics,
|
|
383
363
|
() => this.flowCreationEnabled()
|
|
384
364
|
);
|
|
385
365
|
this.spotAddressTransport = new ZLinkHostSpotAddressTransport({
|
|
386
366
|
resolver: () => this.createLocationSpotRouteResolver(),
|
|
387
367
|
routed: this.routeTransport,
|
|
388
|
-
meshNames: () =>
|
|
389
|
-
.
|
|
390
|
-
|
|
368
|
+
meshNames: () =>
|
|
369
|
+
[...this.options.registration.spotNodes]
|
|
370
|
+
.filter(([, node]) => hasObjectClientCapability(node.objectRole))
|
|
371
|
+
.map(([meshName]) => meshName),
|
|
391
372
|
isMeshConfigured: (meshName) => this.options.registration.spotNodes.has(meshName),
|
|
392
373
|
meshNode: (meshName) => this.spotNodeRuntime?.meshNode(meshName),
|
|
393
374
|
completions: (meshName) => this.spotNodeRuntime?.meshCompletionTable(meshName),
|
|
@@ -410,16 +391,18 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
410
391
|
streamCompression: options.registration.streamCompression,
|
|
411
392
|
messageSerializers: options.registration.messageSerializers,
|
|
412
393
|
sessionRelocationSealTimeoutMs:
|
|
413
|
-
options.registration.locations.options.sessionRelocationSealTimeoutMs
|
|
414
|
-
|
|
394
|
+
options.registration.locations.options.sessionRelocationSealTimeoutMs ??
|
|
395
|
+
zlinkDefaultLocationOptions.sessionRelocationSealTimeoutMs,
|
|
415
396
|
metrics: this.metrics,
|
|
416
397
|
flowCreationEnabled: () => this.flowCreationEnabled(),
|
|
417
398
|
errorSink: () => this.errorSink ?? this.preStartErrorSink,
|
|
418
399
|
nativeActorNodeProvider: () => this.spotNodeRuntime?.primaryMeshNode,
|
|
419
400
|
nativeActorMeshNameProvider: () => this.meshRouters.primaryMeshName(),
|
|
420
401
|
actorAuthorityFenceResolver: async (actorId, signal) => {
|
|
421
|
-
const resolution = await this.createActorLocationResolver()
|
|
422
|
-
|
|
402
|
+
const resolution = await this.createActorLocationResolver()?.resolveDirectActorRoute(
|
|
403
|
+
actorId,
|
|
404
|
+
signal
|
|
405
|
+
);
|
|
423
406
|
return resolution === undefined || resolution.kind !== 'ready'
|
|
424
407
|
? undefined
|
|
425
408
|
: {
|
|
@@ -436,12 +419,12 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
436
419
|
return sessionNode === undefined
|
|
437
420
|
? Promise.resolve()
|
|
438
421
|
: this.boundSessionRelay.actorPackets.confirmRemoteSessionBinding(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
422
|
+
actor,
|
|
423
|
+
sessionNode.status().routingId as never,
|
|
424
|
+
sessionRid,
|
|
425
|
+
signal,
|
|
426
|
+
options
|
|
427
|
+
);
|
|
445
428
|
},
|
|
446
429
|
relay: (actor, header, payload, signal) =>
|
|
447
430
|
this.boundSessionRelay.actorPackets.relayActorPacket(actor, header, payload, signal),
|
|
@@ -457,18 +440,19 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
457
440
|
const state = this.actorManager?.getState(actorId);
|
|
458
441
|
const current = state?.nativeActorRef;
|
|
459
442
|
const meshName = state?.meshName;
|
|
460
|
-
const node =
|
|
461
|
-
? undefined
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
443
|
+
const node =
|
|
444
|
+
meshName === undefined ? undefined : this.spotNodeRuntime?.meshNode(meshName)?.status();
|
|
445
|
+
if (
|
|
446
|
+
owner === undefined ||
|
|
447
|
+
state === undefined ||
|
|
448
|
+
current === undefined ||
|
|
449
|
+
meshName === undefined ||
|
|
450
|
+
node === undefined ||
|
|
451
|
+
state.locationGeneration === undefined ||
|
|
452
|
+
state.ownerLeaseGeneration === undefined ||
|
|
453
|
+
state.ownerLeaseGeneration !== owner.leaseGeneration ||
|
|
454
|
+
!routingIdsEqual(node.routingId, current.nodeRid)
|
|
455
|
+
) {
|
|
472
456
|
throw new ZLinkConfigurationException(
|
|
473
457
|
`Actor '${actorId}' handoff requires a committed source owner fence.`
|
|
474
458
|
);
|
|
@@ -487,23 +471,24 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
487
471
|
validateReplySource: (source) => {
|
|
488
472
|
const owner = this.locationOwner.currentRuntime?.currentOwnerToken;
|
|
489
473
|
const node = this.spotNodeRuntime?.meshNode(source.meshName)?.status();
|
|
490
|
-
if (
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
474
|
+
if (
|
|
475
|
+
owner === undefined ||
|
|
476
|
+
node === undefined ||
|
|
477
|
+
owner.ownerId !== source.ownerId ||
|
|
478
|
+
owner.leaseGeneration !== source.ownerLeaseGeneration ||
|
|
479
|
+
node.lifecycleGeneration !== source.nodeGeneration
|
|
480
|
+
) {
|
|
494
481
|
return false;
|
|
495
482
|
}
|
|
496
|
-
return routingIdsEqual(
|
|
497
|
-
node.routingId,
|
|
498
|
-
decodeRoutingId(source.nodeRid, source.nodeRidHex)
|
|
499
|
-
);
|
|
483
|
+
return routingIdsEqual(node.routingId, decodeRoutingId(source.nodeRid, source.nodeRidHex));
|
|
500
484
|
},
|
|
501
485
|
onMarker: (marker, actorId, index, context) => {
|
|
502
486
|
if (marker === 'message_follow_relay' && context !== undefined) {
|
|
503
|
-
this.options.providerResolver
|
|
504
|
-
|
|
505
|
-
Type<ZLinkInternalActorTransportDeliveryGate>
|
|
506
|
-
|
|
487
|
+
this.options.providerResolver
|
|
488
|
+
?.get?.(
|
|
489
|
+
ZLINK_INTERNAL_ACTOR_TRANSPORT_DELIVERY_GATE as unknown as Type<ZLinkInternalActorTransportDeliveryGate>
|
|
490
|
+
)
|
|
491
|
+
?.recordMessageFollowRelay?.(actorId, context);
|
|
507
492
|
}
|
|
508
493
|
if (marker === 'message_follow_route_removed') {
|
|
509
494
|
this.serviceRelocation.completeActorJoinSourceCleanup(actorId);
|
|
@@ -530,9 +515,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
530
515
|
try {
|
|
531
516
|
const objectGeneration = BigInt(context.objectGeneration);
|
|
532
517
|
if (targetActorRef.objectGeneration !== objectGeneration) {
|
|
533
|
-
throw new Error(
|
|
534
|
-
`Actor Message Follow changed object generation for '${actorId}'.`
|
|
535
|
-
);
|
|
518
|
+
throw new Error(`Actor Message Follow changed object generation for '${actorId}'.`);
|
|
536
519
|
}
|
|
537
520
|
const sent = await this.spotNodeRuntime?.sendMessageFollowNotification(
|
|
538
521
|
messageFollowOwnerNodeRid(context.sourceOwner),
|
|
@@ -547,9 +530,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
547
530
|
},
|
|
548
531
|
targetNodeRid: messageFollowOwnerNodeRid(context.sourceOwner),
|
|
549
532
|
targetNodeGeneration: BigInt(context.sourceOwner.nodeGeneration),
|
|
550
|
-
authorityOwnerGeneration: BigInt(
|
|
551
|
-
context.sourceOwner.authorityOwnerGeneration
|
|
552
|
-
),
|
|
533
|
+
authorityOwnerGeneration: BigInt(context.sourceOwner.authorityOwnerGeneration),
|
|
553
534
|
ownerLeaseGeneration: BigInt(context.sourceOwner.ownerLeaseGeneration)
|
|
554
535
|
},
|
|
555
536
|
target: {
|
|
@@ -561,9 +542,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
561
542
|
},
|
|
562
543
|
targetNodeRid: messageFollowOwnerNodeRid(context.targetOwner),
|
|
563
544
|
targetNodeGeneration: BigInt(context.targetOwner.nodeGeneration),
|
|
564
|
-
authorityOwnerGeneration: BigInt(
|
|
565
|
-
context.targetOwner.authorityOwnerGeneration
|
|
566
|
-
),
|
|
545
|
+
authorityOwnerGeneration: BigInt(context.targetOwner.authorityOwnerGeneration),
|
|
567
546
|
ownerLeaseGeneration: BigInt(context.targetOwner.ownerLeaseGeneration)
|
|
568
547
|
},
|
|
569
548
|
hopCount: context.hopCount,
|
|
@@ -591,9 +570,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
591
570
|
const state = this.actorManager?.getState(actorId);
|
|
592
571
|
const current = state?.nativeActorRef;
|
|
593
572
|
if (actorRef === undefined) return state?.remoteActorPacketTarget !== undefined;
|
|
594
|
-
return
|
|
595
|
-
current
|
|
596
|
-
|
|
573
|
+
return (
|
|
574
|
+
current !== undefined &&
|
|
575
|
+
(current.generation !== actorRef.objectGeneration ||
|
|
576
|
+
!routingIdsEqual(current.nodeRid, actorRef.nodeRid))
|
|
597
577
|
);
|
|
598
578
|
},
|
|
599
579
|
isCurrentHandoffTarget: (actorId, spotId) => {
|
|
@@ -602,21 +582,29 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
602
582
|
},
|
|
603
583
|
isCurrentActorRef: (actorId, actorRef) => {
|
|
604
584
|
const current = this.actorManager?.getState(actorId)?.nativeActorRef;
|
|
605
|
-
return
|
|
606
|
-
|
|
607
|
-
|
|
585
|
+
return (
|
|
586
|
+
current !== undefined &&
|
|
587
|
+
current.generation === actorRef.objectGeneration &&
|
|
588
|
+
routingIdsEqual(current.nodeRid, actorRef.nodeRid)
|
|
589
|
+
);
|
|
608
590
|
},
|
|
609
591
|
currentOwnerFence: (actorId) => {
|
|
610
592
|
const state = this.actorManager?.getState(actorId);
|
|
611
593
|
const current = state?.nativeActorRef;
|
|
612
594
|
const owner = this.locationOwner.currentRuntime?.currentOwnerToken;
|
|
613
|
-
const node =
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
595
|
+
const node =
|
|
596
|
+
state?.meshName === undefined
|
|
597
|
+
? undefined
|
|
598
|
+
: this.spotNodeRuntime?.meshNode(state.meshName)?.status();
|
|
599
|
+
if (
|
|
600
|
+
state === undefined ||
|
|
601
|
+
current === undefined ||
|
|
602
|
+
owner === undefined ||
|
|
603
|
+
node === undefined ||
|
|
604
|
+
state.locationGeneration === undefined ||
|
|
605
|
+
state.ownerLeaseGeneration === undefined ||
|
|
606
|
+
!routingIdsEqual(node.routingId, current.nodeRid)
|
|
607
|
+
) {
|
|
620
608
|
return undefined;
|
|
621
609
|
}
|
|
622
610
|
return ownerFence({
|
|
@@ -638,8 +626,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
638
626
|
this.boundSessionRelay = new ZLinkBoundSessionRelay({
|
|
639
627
|
requestTimeoutMs: options.registration.requestTimeoutMs,
|
|
640
628
|
sessionRelocationSealTimeoutMs:
|
|
641
|
-
options.registration.locations.options.sessionRelocationSealTimeoutMs
|
|
642
|
-
|
|
629
|
+
options.registration.locations.options.sessionRelocationSealTimeoutMs ??
|
|
630
|
+
zlinkDefaultLocationOptions.sessionRelocationSealTimeoutMs,
|
|
643
631
|
routeTransport: this.routeTransport,
|
|
644
632
|
streamBindingRuntime: () => this.streamBindingRuntime,
|
|
645
633
|
meshRouters: this.meshRouters,
|
|
@@ -649,14 +637,16 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
649
637
|
detachedTaskRunner: this.detachedTaskRunner(),
|
|
650
638
|
actorSessionNode: (actorId) => {
|
|
651
639
|
const state = this.actorManager?.getState(actorId);
|
|
652
|
-
const meshName =
|
|
653
|
-
|
|
640
|
+
const meshName =
|
|
641
|
+
state?.meshName ??
|
|
642
|
+
(state?.actorType === undefined
|
|
654
643
|
? undefined
|
|
655
644
|
: this.meshRouters.actorMeshName(state.actorType));
|
|
656
645
|
const runtime = this.spotNodeRuntime;
|
|
657
|
-
const node =
|
|
658
|
-
|
|
659
|
-
|
|
646
|
+
const node =
|
|
647
|
+
meshName === undefined || typeof runtime?.meshNode !== 'function'
|
|
648
|
+
? runtime?.primaryMeshNode
|
|
649
|
+
: runtime.meshNode(meshName);
|
|
660
650
|
return node === undefined
|
|
661
651
|
? undefined
|
|
662
652
|
: meshActorSessionNodeAdapter(
|
|
@@ -686,7 +676,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
686
676
|
streamBindingRuntime: this.streamBindingRuntime,
|
|
687
677
|
boundSessionRelay: this.boundSessionRelay,
|
|
688
678
|
reportPostCommitError: (error) =>
|
|
689
|
-
(this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException(
|
|
679
|
+
(this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException(
|
|
680
|
+
'entry actor commit',
|
|
681
|
+
error
|
|
682
|
+
),
|
|
690
683
|
shutdownSignal: () => this.executionState?.abortController.signal
|
|
691
684
|
});
|
|
692
685
|
this.actorTransferRuntime = new ZLinkActorTransferRuntime({
|
|
@@ -705,8 +698,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
705
698
|
actorTransferRegistry: this.actorTransferRegistry,
|
|
706
699
|
authorityStore: () => this.locationOwner.currentStores?.locationStore,
|
|
707
700
|
currentOwner: () => this.locationOwner.currentRuntime?.currentOwnerToken,
|
|
708
|
-
relocationStore: () =>
|
|
709
|
-
this.options.registration.locations.relocationStoreInstance,
|
|
701
|
+
relocationStore: () => this.options.registration.locations.relocationStoreInstance,
|
|
710
702
|
liveDescriptors: (meshName, signal) => {
|
|
711
703
|
const runtime = this.locationOwner.currentRuntime;
|
|
712
704
|
if (runtime === undefined) {
|
|
@@ -719,9 +711,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
719
711
|
this.boundSessionRelay.clearRemoteActorPacketTarget(actorId),
|
|
720
712
|
prepareApplicationJob: async (preparationSignal) => {
|
|
721
713
|
const runtimeSignal = this.executionState?.abortController.signal;
|
|
722
|
-
const signal =
|
|
723
|
-
|
|
724
|
-
|
|
714
|
+
const signal =
|
|
715
|
+
runtimeSignal === undefined
|
|
716
|
+
? preparationSignal
|
|
717
|
+
: AbortSignal.any([runtimeSignal, preparationSignal]);
|
|
725
718
|
const permit = await this.applicationJobQueue.acquire(signal);
|
|
726
719
|
let state: 'ready' | 'running' | 'closed' = 'ready';
|
|
727
720
|
let closedReason: unknown;
|
|
@@ -762,7 +755,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
762
755
|
};
|
|
763
756
|
},
|
|
764
757
|
reportPostCommitError: (error) =>
|
|
765
|
-
(this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException(
|
|
758
|
+
(this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException(
|
|
759
|
+
'source actor departure',
|
|
760
|
+
error
|
|
761
|
+
),
|
|
766
762
|
onSourceDepartureCompleted: (actorId) =>
|
|
767
763
|
this.publishActorHandoffEvent({ marker: 'source_cleanup', actorId }),
|
|
768
764
|
shutdownSignal: () => this.executionState?.abortController.signal,
|
|
@@ -774,10 +770,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
774
770
|
locationStore: () => this.locationOwner.currentStores?.locationStore,
|
|
775
771
|
currentOwner: () => this.locationOwner.currentRuntime?.currentOwnerToken,
|
|
776
772
|
liveDescriptors: (meshName, signal) =>
|
|
777
|
-
this.locationOwner.currentRuntime?.listLiveMeshNodes(meshName, signal)
|
|
778
|
-
|
|
779
|
-
localDescriptor: (meshName) =>
|
|
780
|
-
this.spotNodeRuntime?.meshNodeDescriptor(meshName),
|
|
773
|
+
this.locationOwner.currentRuntime?.listLiveMeshNodes(meshName, signal) ??
|
|
774
|
+
Promise.resolve([]),
|
|
775
|
+
localDescriptor: (meshName) => this.spotNodeRuntime?.meshNodeDescriptor(meshName),
|
|
781
776
|
meshNode: (meshName) => this.spotNodeRuntime?.meshNode(meshName),
|
|
782
777
|
completions: (meshName) => this.spotNodeRuntime?.meshCompletionTable(meshName),
|
|
783
778
|
spotManager: () => this.spotManager,
|
|
@@ -786,14 +781,15 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
786
781
|
actorTransfer: this.actorTransferRuntime,
|
|
787
782
|
boundSessionRelocation: {
|
|
788
783
|
receiveSeal: (value, signal) =>
|
|
789
|
-
this.boundSessionRelay.boundSessions.receiveServiceWireSessionRelocationSeal(
|
|
790
|
-
|
|
784
|
+
this.boundSessionRelay.boundSessions.receiveServiceWireSessionRelocationSeal(
|
|
785
|
+
value,
|
|
786
|
+
signal
|
|
787
|
+
),
|
|
788
|
+
receiveRoute: (value) =>
|
|
791
789
|
this.boundSessionRelay.boundSessions.receiveServiceWireSessionRelocationRoute(value),
|
|
792
|
-
clear: () =>
|
|
793
|
-
this.boundSessionRelay.boundSessions.clearServiceWireSessionRelocations()
|
|
790
|
+
clear: () => this.boundSessionRelay.boundSessions.clearServiceWireSessionRelocations()
|
|
794
791
|
},
|
|
795
|
-
trackInstanceSpot: (input) =>
|
|
796
|
-
this.locationOwner.currentLifecycle?.trackInstanceSpot(input),
|
|
792
|
+
trackInstanceSpot: (input) => this.locationOwner.currentLifecycle?.trackInstanceSpot(input),
|
|
797
793
|
invalidateActorRoute: (actorId) =>
|
|
798
794
|
this.actorClientLocationResolver?.invalidateActorRoute(actorId),
|
|
799
795
|
reconcileStatefulAuthorityRoutes: (signal) =>
|
|
@@ -813,8 +809,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
813
809
|
meshNames: [...options.registration.spotNodes.keys()],
|
|
814
810
|
meshOptions: options.registration.spotNodes,
|
|
815
811
|
meshNode: (meshName) => this.spotNodeRuntime?.meshNode(meshName),
|
|
816
|
-
meshNodeDescriptor: (meshName) =>
|
|
817
|
-
this.spotNodeRuntime?.meshNodeDescriptor(meshName),
|
|
812
|
+
meshNodeDescriptor: (meshName) => this.spotNodeRuntime?.meshNodeDescriptor(meshName),
|
|
818
813
|
localPlacementCounts: (meshName) => {
|
|
819
814
|
const spotManager = this.spotManager;
|
|
820
815
|
const actorManager = this.actorManager;
|
|
@@ -829,18 +824,13 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
829
824
|
return true;
|
|
830
825
|
}
|
|
831
826
|
const runtime = this.locationOwner.currentRuntime;
|
|
832
|
-
return runtime !== undefined
|
|
833
|
-
&& runtime.ownerLeaseUsable
|
|
834
|
-
&& runtime.lastError === undefined;
|
|
827
|
+
return runtime !== undefined && runtime.ownerLeaseUsable && runtime.lastError === undefined;
|
|
835
828
|
},
|
|
836
829
|
hostState: () => this.runtimeState,
|
|
837
830
|
admission: this.admission,
|
|
838
|
-
publishRetiring: (meshName, signal) =>
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
this.publishMeshServing(meshName, signal),
|
|
842
|
-
publishDraining: (meshName, signal) =>
|
|
843
|
-
this.publishMeshDraining(meshName, signal),
|
|
831
|
+
publishRetiring: (meshName, signal) => this.publishMeshRetiring(meshName, signal),
|
|
832
|
+
rollbackRetiring: (meshName, signal) => this.publishMeshServing(meshName, signal),
|
|
833
|
+
publishDraining: (meshName, signal) => this.publishMeshDraining(meshName, signal),
|
|
844
834
|
publishHostDraining: (signal) => this.publishHostDraining(signal),
|
|
845
835
|
drainResources: (meshName, signal, stopStartingSignal) =>
|
|
846
836
|
this.performMeshDrain(meshName, signal, stopStartingSignal),
|
|
@@ -851,9 +841,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
851
841
|
this.metricRegistrations.push(
|
|
852
842
|
this.metrics.registerHostState(() => runtimeStateMetricName(this.runtimeState)),
|
|
853
843
|
this.metrics.registerHostCapacity(() =>
|
|
854
|
-
this.capacityStatus.snapshot(this.context?.getCoreHwmBudgetSnapshot())
|
|
855
|
-
|
|
856
|
-
|
|
844
|
+
this.capacityStatus.snapshot(this.context?.getCoreHwmBudgetSnapshot())
|
|
845
|
+
),
|
|
846
|
+
this.metrics.registerApplicationJobQueuePressure(() => this.applicationJobQueue.snapshot()),
|
|
857
847
|
this.metrics.registerMeshSnapshots(() => this.runtimeMetricMeshSnapshots())
|
|
858
848
|
);
|
|
859
849
|
this.routeMeshRuntime = this.routeMeshCoordinator;
|
|
@@ -867,10 +857,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
867
857
|
return {
|
|
868
858
|
state: this.runtimeState,
|
|
869
859
|
isReady: runtimeStateIsReady(this.runtimeState),
|
|
870
|
-
acceptingWork: runtimeAcceptsWork(
|
|
871
|
-
this.runtimeState,
|
|
872
|
-
this.admission.acceptsNewWork
|
|
873
|
-
),
|
|
860
|
+
acceptingWork: runtimeAcceptsWork(this.runtimeState, this.admission.acceptsNewWork),
|
|
874
861
|
capacity: this.capacityStatus.snapshot(this.context?.getCoreHwmBudgetSnapshot()),
|
|
875
862
|
safeToShutdown: this.serviceRelocation.isSafeToShutdown(),
|
|
876
863
|
deadline: this.runtimeDeadline,
|
|
@@ -933,9 +920,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
933
920
|
mode: options.mode,
|
|
934
921
|
effectiveTargetApplicationVersion,
|
|
935
922
|
outcome: ZLinkFrameworkRelocationOutcome.Blocked,
|
|
936
|
-
reason:
|
|
937
|
-
|
|
938
|
-
|
|
923
|
+
reason:
|
|
924
|
+
this.runtimeState === ZLinkFrameworkRuntimeState.Relocating
|
|
925
|
+
? ZLinkFrameworkRelocationReason.OperationInProgress
|
|
926
|
+
: ZLinkFrameworkRelocationReason.RuntimeNotReady
|
|
939
927
|
});
|
|
940
928
|
}
|
|
941
929
|
if (!this.admission.acceptsNewWork) {
|
|
@@ -989,11 +977,13 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
989
977
|
stopStartingSignal: AbortSignal
|
|
990
978
|
): Promise<ZLinkFrameworkRelocationResult> {
|
|
991
979
|
if (!this.isStarted) {
|
|
992
|
-
return this.completeRelocation(
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
980
|
+
return this.completeRelocation(
|
|
981
|
+
blockedRelocation(
|
|
982
|
+
mode,
|
|
983
|
+
effectiveTargetApplicationVersion,
|
|
984
|
+
ZLinkFrameworkRelocationReason.RuntimeNotReady
|
|
985
|
+
)
|
|
986
|
+
);
|
|
997
987
|
}
|
|
998
988
|
const deadlineAtMs = performance.now() + deadlineMs;
|
|
999
989
|
const remainingDeadlineMs = () => Math.max(1, deadlineAtMs - performance.now());
|
|
@@ -1008,23 +998,22 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1008
998
|
effectiveTargetApplicationVersion
|
|
1009
999
|
);
|
|
1010
1000
|
if (blocker !== undefined) {
|
|
1011
|
-
return this.resetBlockedRelocation(
|
|
1012
|
-
mode,
|
|
1013
|
-
|
|
1014
|
-
blocker
|
|
1015
|
-
));
|
|
1001
|
+
return this.resetBlockedRelocation(
|
|
1002
|
+
blockedRelocation(mode, effectiveTargetApplicationVersion, blocker)
|
|
1003
|
+
);
|
|
1016
1004
|
}
|
|
1017
|
-
const descriptorPreparation =
|
|
1018
|
-
remainingDeadlineMs()
|
|
1019
|
-
);
|
|
1005
|
+
const descriptorPreparation =
|
|
1006
|
+
await this.routeMeshCoordinator.prepareHostRetire(remainingDeadlineMs());
|
|
1020
1007
|
if (descriptorPreparation !== 'prepared') {
|
|
1021
|
-
return this.resetBlockedRelocation(
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1008
|
+
return this.resetBlockedRelocation(
|
|
1009
|
+
blockedRelocation(
|
|
1010
|
+
mode,
|
|
1011
|
+
effectiveTargetApplicationVersion,
|
|
1012
|
+
descriptorPreparation === 'deadline_exceeded'
|
|
1013
|
+
? ZLinkFrameworkRelocationReason.DeadlineExceeded
|
|
1014
|
+
: ZLinkFrameworkRelocationReason.StoreUnavailable
|
|
1015
|
+
)
|
|
1016
|
+
);
|
|
1028
1017
|
}
|
|
1029
1018
|
this.setRuntimeState(ZLinkFrameworkRuntimeState.Relocating);
|
|
1030
1019
|
const drained = await this.routeMeshCoordinator.relocateHost(
|
|
@@ -1032,15 +1021,17 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1032
1021
|
stopStartingSignal
|
|
1033
1022
|
);
|
|
1034
1023
|
if (drained.kind === 'forceStopped') {
|
|
1035
|
-
return this.resetBlockedRelocation(
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1024
|
+
return this.resetBlockedRelocation(
|
|
1025
|
+
blockedRelocation(
|
|
1026
|
+
mode,
|
|
1027
|
+
effectiveTargetApplicationVersion,
|
|
1028
|
+
stopStartingSignal.aborted
|
|
1029
|
+
? ZLinkFrameworkRelocationReason.ShutdownRequested
|
|
1030
|
+
: drained.error instanceof ZLinkRelocationStateIncompatibleError
|
|
1031
|
+
? ZLinkFrameworkRelocationReason.StateIncompatible
|
|
1032
|
+
: relocationReason(drained.reason)
|
|
1033
|
+
)
|
|
1034
|
+
);
|
|
1044
1035
|
}
|
|
1045
1036
|
await this.publishHostRelocated();
|
|
1046
1037
|
return this.completeRelocation({
|
|
@@ -1056,10 +1047,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1056
1047
|
stopStartingSignal.aborted
|
|
1057
1048
|
? ZLinkFrameworkRelocationReason.ShutdownRequested
|
|
1058
1049
|
: isDeadlineExceededError(error)
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1050
|
+
? ZLinkFrameworkRelocationReason.DeadlineExceeded
|
|
1051
|
+
: error instanceof ZLinkRelocationStateIncompatibleError
|
|
1052
|
+
? ZLinkFrameworkRelocationReason.StateIncompatible
|
|
1053
|
+
: ZLinkFrameworkRelocationReason.RelocationFailed
|
|
1063
1054
|
);
|
|
1064
1055
|
return error instanceof ZLinkRetiringRollbackError
|
|
1065
1056
|
? this.completeRelocation(result)
|
|
@@ -1072,8 +1063,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1072
1063
|
try {
|
|
1073
1064
|
this.admission.close();
|
|
1074
1065
|
this.setRuntimeState(ZLinkFrameworkRuntimeState.Draining);
|
|
1075
|
-
if (
|
|
1076
|
-
|
|
1066
|
+
if (
|
|
1067
|
+
this.relocationOperation !== undefined &&
|
|
1068
|
+
this.relocationStopStarting?.signal.aborted === true
|
|
1069
|
+
) {
|
|
1077
1070
|
await this.relocationOperation;
|
|
1078
1071
|
}
|
|
1079
1072
|
// Seal application admission before the public status reports that the
|
|
@@ -1091,9 +1084,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1091
1084
|
if (drain.kind === 'forceStopped') {
|
|
1092
1085
|
return this.completeTermination({
|
|
1093
1086
|
outcome: ZLinkFrameworkTerminationOutcome.ForceStopped,
|
|
1094
|
-
reason:
|
|
1095
|
-
|
|
1096
|
-
|
|
1087
|
+
reason:
|
|
1088
|
+
drain.reason === 'deadline_exceeded'
|
|
1089
|
+
? ZLinkFrameworkTerminationReason.DeadlineExceeded
|
|
1090
|
+
: ZLinkFrameworkTerminationReason.TeardownFailed
|
|
1097
1091
|
});
|
|
1098
1092
|
}
|
|
1099
1093
|
if (performance.now() >= deadlineAtMs) {
|
|
@@ -1136,9 +1130,11 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1136
1130
|
this.runtimeRelocationResult = result;
|
|
1137
1131
|
this.runtimeDeadline = undefined;
|
|
1138
1132
|
this.recordRelocationResult(result);
|
|
1139
|
-
this.setRuntimeState(
|
|
1140
|
-
|
|
1141
|
-
|
|
1133
|
+
this.setRuntimeState(
|
|
1134
|
+
result.outcome === ZLinkFrameworkRelocationOutcome.Relocated
|
|
1135
|
+
? ZLinkFrameworkRuntimeState.Relocated
|
|
1136
|
+
: ZLinkFrameworkRuntimeState.Error
|
|
1137
|
+
);
|
|
1142
1138
|
return result;
|
|
1143
1139
|
}
|
|
1144
1140
|
|
|
@@ -1149,9 +1145,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1149
1145
|
Math.max(0, performance.now() - this.relocationOperationStartedAt) / 1000,
|
|
1150
1146
|
{
|
|
1151
1147
|
mode: relocationModeMetricName(result.mode),
|
|
1152
|
-
outcome:
|
|
1153
|
-
? 'relocated'
|
|
1154
|
-
: 'blocked'
|
|
1148
|
+
outcome:
|
|
1149
|
+
result.outcome === ZLinkFrameworkRelocationOutcome.Relocated ? 'relocated' : 'blocked'
|
|
1155
1150
|
}
|
|
1156
1151
|
);
|
|
1157
1152
|
}
|
|
@@ -1182,9 +1177,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1182
1177
|
'zlink.host.shutdown.duration',
|
|
1183
1178
|
Math.max(0, performance.now() - this.shutdownOperationStartedAt) / 1000,
|
|
1184
1179
|
{
|
|
1185
|
-
outcome:
|
|
1186
|
-
|
|
1187
|
-
|
|
1180
|
+
outcome:
|
|
1181
|
+
result.outcome === ZLinkFrameworkTerminationOutcome.Stopped
|
|
1182
|
+
? 'stopped'
|
|
1183
|
+
: 'force_stopped'
|
|
1188
1184
|
}
|
|
1189
1185
|
);
|
|
1190
1186
|
}
|
|
@@ -1225,10 +1221,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1225
1221
|
private notifyTopologyHostStateChanged(): void {
|
|
1226
1222
|
const callbacks = [
|
|
1227
1223
|
() => this.routeMeshCoordinator.hostStateChanged(),
|
|
1228
|
-
() => (this.clientServerRuntime as ZLinkClientServerRuntimeProjection)
|
|
1229
|
-
|
|
1230
|
-
() => (this.fanoutRuntime as ZLinkFanoutRuntimeProjection)
|
|
1231
|
-
.hostStateChanged()
|
|
1224
|
+
() => (this.clientServerRuntime as ZLinkClientServerRuntimeProjection).hostStateChanged(),
|
|
1225
|
+
() => (this.fanoutRuntime as ZLinkFanoutRuntimeProjection).hostStateChanged()
|
|
1232
1226
|
];
|
|
1233
1227
|
for (const callback of callbacks) {
|
|
1234
1228
|
try {
|
|
@@ -1249,10 +1243,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1249
1243
|
private stopTopologyObservers(): void {
|
|
1250
1244
|
const callbacks = [
|
|
1251
1245
|
() => this.routeMeshCoordinator.stopObservers(),
|
|
1252
|
-
() => (this.clientServerRuntime as ZLinkClientServerRuntimeProjection)
|
|
1253
|
-
|
|
1254
|
-
() => (this.fanoutRuntime as ZLinkFanoutRuntimeProjection)
|
|
1255
|
-
.stopObservers()
|
|
1246
|
+
() => (this.clientServerRuntime as ZLinkClientServerRuntimeProjection).stopObservers(),
|
|
1247
|
+
() => (this.fanoutRuntime as ZLinkFanoutRuntimeProjection).stopObservers()
|
|
1256
1248
|
];
|
|
1257
1249
|
for (const callback of callbacks) {
|
|
1258
1250
|
try {
|
|
@@ -1345,8 +1337,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1345
1337
|
this.executionState = new ZLinkFrameworkExecutionState(context);
|
|
1346
1338
|
// Seed the shared live-mode cell from the configured mode (default errorsOnly).
|
|
1347
1339
|
this.messageFlowModeCell.mode =
|
|
1348
|
-
this.options.registration.dispatch?.diagnostics.messageFlow ??
|
|
1349
|
-
'errors';
|
|
1340
|
+
this.options.registration.dispatch?.diagnostics.messageFlow ?? 'errors';
|
|
1350
1341
|
const dispatchErrors = this.createDispatchErrorReporter(this.executionState.errorSink);
|
|
1351
1342
|
channelRuntime = new ZLinkChannelRuntimeManager(
|
|
1352
1343
|
this.options.registration,
|
|
@@ -1366,7 +1357,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1366
1357
|
channelRuntime.bindRouteMeshRouters();
|
|
1367
1358
|
// Start bound receivers before publishing Serving descriptors. A
|
|
1368
1359
|
// discovered ClientServer endpoint must already be able to dispatch.
|
|
1369
|
-
this.executionState.listenerTasks.push(
|
|
1360
|
+
this.executionState.listenerTasks.push(
|
|
1361
|
+
...channelRuntime.start(this.executionState.taskRunner)
|
|
1362
|
+
);
|
|
1370
1363
|
const locationRuntime = await this.locationOwner.startForRuntime(
|
|
1371
1364
|
this.meshRouters.primaryMeshName(),
|
|
1372
1365
|
spotNodeRuntime,
|
|
@@ -1401,9 +1394,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1401
1394
|
dispatchErrors,
|
|
1402
1395
|
metrics: this.metrics,
|
|
1403
1396
|
applicationJobQueue: this.applicationJobQueue,
|
|
1404
|
-
acceptNewSession: (meshName) =>
|
|
1405
|
-
? this.admission.acceptsNewWork
|
|
1406
|
-
: this.admission.accepts(meshName),
|
|
1397
|
+
acceptNewSession: (meshName) =>
|
|
1398
|
+
meshName === undefined ? this.admission.acceptsNewWork : this.admission.accepts(meshName),
|
|
1407
1399
|
primaryMeshName: this.meshRouters.primaryMeshName(),
|
|
1408
1400
|
nativeMeshNode: spotNodeRuntime.primaryMeshNode,
|
|
1409
1401
|
meshCompletions: spotNodeRuntime.primaryMeshCompletions,
|
|
@@ -1457,27 +1449,28 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1457
1449
|
continue;
|
|
1458
1450
|
}
|
|
1459
1451
|
const descriptor = this.spotNodeRuntime?.meshNodeDescriptor(meshName);
|
|
1460
|
-
const hasManual =
|
|
1461
|
-
|
|
1462
|
-
|
|
1452
|
+
const hasManual =
|
|
1453
|
+
(options.router?.manualConnections?.length ?? 0) > 0 ||
|
|
1454
|
+
(options.router?.manualPeerConnections?.length ?? 0) > 0 ||
|
|
1455
|
+
(options.pubSub?.manualConnections?.length ?? 0) > 0;
|
|
1463
1456
|
const hasDiscovery = hasConfiguredLocationStore(this.options.registration);
|
|
1464
|
-
const source =
|
|
1465
|
-
? 'manual_and_redis'
|
|
1466
|
-
: hasManual ? 'manual' : 'redis';
|
|
1457
|
+
const source =
|
|
1458
|
+
hasManual && hasDiscovery ? 'manual_and_redis' : hasManual ? 'manual' : 'redis';
|
|
1467
1459
|
const emptyCapacity = { active: 0, reserved: 0, limit: 0 };
|
|
1468
1460
|
snapshots.push({
|
|
1469
1461
|
meshName,
|
|
1470
1462
|
source,
|
|
1471
1463
|
configuredPeers: status.peers.length,
|
|
1472
|
-
connectedPeers: status.peers.filter(peer => peer.state !== ZLinkPeerState.NotConnected)
|
|
1464
|
+
connectedPeers: status.peers.filter((peer) => peer.state !== ZLinkPeerState.NotConnected)
|
|
1465
|
+
.length,
|
|
1473
1466
|
readyPeers: status.readyPeerCount,
|
|
1474
|
-
channels: status.channels.map(channel => ({
|
|
1467
|
+
channels: status.channels.map((channel) => ({
|
|
1475
1468
|
channelName: channel.channelName,
|
|
1476
1469
|
readyMembers: channel.readyTargetCount
|
|
1477
1470
|
})),
|
|
1478
1471
|
actorCapacity: descriptor?.populationCapacity.actors ?? emptyCapacity,
|
|
1479
1472
|
spotCapacity: descriptor?.populationCapacity.spots ?? emptyCapacity,
|
|
1480
|
-
spotTypeCapacities: (descriptor?.populationCapacity.spotTypes ?? []).map(capacity => ({
|
|
1473
|
+
spotTypeCapacities: (descriptor?.populationCapacity.spotTypes ?? []).map((capacity) => ({
|
|
1481
1474
|
spotKind: capacity.objectKind === 'instance_spot' ? 'instance' : 'user',
|
|
1482
1475
|
stableType: capacity.stableType,
|
|
1483
1476
|
active: capacity.active,
|
|
@@ -1535,14 +1528,12 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1535
1528
|
): void {
|
|
1536
1529
|
const handler = () => {
|
|
1537
1530
|
if (!this.ownerAdmissionOpen()) return;
|
|
1538
|
-
void this.resumeOwnerLeaseOwnedWork(runtime, spotNodeRuntime, channelRuntime)
|
|
1539
|
-
|
|
1531
|
+
void this.resumeOwnerLeaseOwnedWork(runtime, spotNodeRuntime, channelRuntime).catch(
|
|
1532
|
+
(error) => {
|
|
1540
1533
|
runtime.closeOwnerLeaseAdmission(error);
|
|
1541
|
-
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException(
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
);
|
|
1545
|
-
});
|
|
1534
|
+
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException('owner lease recovery', error);
|
|
1535
|
+
}
|
|
1536
|
+
);
|
|
1546
1537
|
};
|
|
1547
1538
|
this.ownerLeaseRecoveryRuntime = runtime;
|
|
1548
1539
|
this.ownerLeaseRecoveryHandler = handler;
|
|
@@ -1558,10 +1549,12 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1558
1549
|
const signal = this.executionState?.abortController.signal;
|
|
1559
1550
|
await spotNodeRuntime.publishMeshNodeState(ZLinkFrameworkRuntimeState.Preparing, signal);
|
|
1560
1551
|
const store = this.locationOwner.currentStores?.locationStore;
|
|
1561
|
-
if (
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1552
|
+
if (
|
|
1553
|
+
this.statefulAuthorityRoutes === undefined &&
|
|
1554
|
+
store !== undefined &&
|
|
1555
|
+
this.executionState !== undefined &&
|
|
1556
|
+
this.requiresStatefulAuthorityRuntime()
|
|
1557
|
+
) {
|
|
1565
1558
|
const routes = this.createStatefulAuthorityRoutes(store, spotNodeRuntime);
|
|
1566
1559
|
await routes.start(signal);
|
|
1567
1560
|
this.statefulAuthorityRoutes = routes;
|
|
@@ -1584,24 +1577,25 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1584
1577
|
relocationStore: this.options.registration.locations.relocationStoreInstance,
|
|
1585
1578
|
meshNodes: spotNodeRuntime.meshNodesByName,
|
|
1586
1579
|
pollingIntervalMs:
|
|
1587
|
-
this.options.registration.locations.options.pollingIntervalMs
|
|
1588
|
-
|
|
1580
|
+
this.options.registration.locations.options.pollingIntervalMs ??
|
|
1581
|
+
zlinkDefaultLocationOptions.pollingIntervalMs,
|
|
1589
1582
|
pageSize: 1000,
|
|
1590
1583
|
reportError: (error) =>
|
|
1591
1584
|
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException(
|
|
1592
1585
|
'stateful authority route reconciliation',
|
|
1593
1586
|
error
|
|
1594
1587
|
),
|
|
1595
|
-
onSpotRouteChanged: (spotId) =>
|
|
1596
|
-
this.cachedLocationSpotRouteResolver?.invalidate?.(spotId)
|
|
1588
|
+
onSpotRouteChanged: (spotId) => this.cachedLocationSpotRouteResolver?.invalidate?.(spotId)
|
|
1597
1589
|
});
|
|
1598
1590
|
}
|
|
1599
1591
|
|
|
1600
1592
|
private requiresStatefulAuthorityRuntime(): boolean {
|
|
1601
1593
|
for (const options of this.options.registration.spotNodes.values()) {
|
|
1602
|
-
if (
|
|
1603
|
-
|
|
1604
|
-
|
|
1594
|
+
if (
|
|
1595
|
+
Object.keys(options.spotFactoryRegistrations ?? {}).length > 0 ||
|
|
1596
|
+
Object.keys(options.instanceSpotFactoryRegistrations ?? {}).length > 0 ||
|
|
1597
|
+
Object.keys(options.actorFactoryRegistrations ?? {}).length > 0
|
|
1598
|
+
) {
|
|
1605
1599
|
return true;
|
|
1606
1600
|
}
|
|
1607
1601
|
}
|
|
@@ -1620,7 +1614,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1620
1614
|
registerInstanceIntent: (
|
|
1621
1615
|
instanceType: string,
|
|
1622
1616
|
route: import('../foundation/service-stateful-wire-codec').ServiceInstanceRouteFence,
|
|
1623
|
-
expectedCurrentRoute?:
|
|
1617
|
+
expectedCurrentRoute?:
|
|
1618
|
+
import('../foundation/service-stateful-wire-codec').ServiceInstanceRouteFence | null
|
|
1624
1619
|
) => void;
|
|
1625
1620
|
registerInstanceApplicationLifecycle?: (
|
|
1626
1621
|
lifecycle: ServiceInstanceApplicationLifecycle
|
|
@@ -1661,7 +1656,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1661
1656
|
}
|
|
1662
1657
|
|
|
1663
1658
|
private removeOwnerLeaseRecoveryPublication(): void {
|
|
1664
|
-
if (
|
|
1659
|
+
if (
|
|
1660
|
+
this.ownerLeaseRecoveryRuntime !== undefined &&
|
|
1661
|
+
this.ownerLeaseRecoveryHandler !== undefined
|
|
1662
|
+
) {
|
|
1665
1663
|
this.ownerLeaseRecoveryRuntime.removeOwnerLeaseRenewedHandler(this.ownerLeaseRecoveryHandler);
|
|
1666
1664
|
}
|
|
1667
1665
|
this.ownerLeaseRecoveryRuntime = undefined;
|
|
@@ -1697,16 +1695,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1697
1695
|
|
|
1698
1696
|
private async performMeshShutdown(meshName: string, signal: AbortSignal): Promise<void> {
|
|
1699
1697
|
await this.spotManager?.drainForShutdown(meshName, signal, this.runtimeDeadline);
|
|
1700
|
-
await awaitWithDrainSignal(
|
|
1701
|
-
this.streamRuntime?.notifyServerDrain(meshName),
|
|
1702
|
-
signal
|
|
1703
|
-
);
|
|
1698
|
+
await awaitWithDrainSignal(this.streamRuntime?.notifyServerDrain(meshName), signal);
|
|
1704
1699
|
}
|
|
1705
1700
|
|
|
1706
|
-
private async publishMeshRetiring(
|
|
1707
|
-
meshName: string,
|
|
1708
|
-
signal?: AbortSignal
|
|
1709
|
-
): Promise<void> {
|
|
1701
|
+
private async publishMeshRetiring(meshName: string, signal?: AbortSignal): Promise<void> {
|
|
1710
1702
|
await this.spotNodeRuntime?.publishMeshNodeState(
|
|
1711
1703
|
ZLinkFrameworkRuntimeState.Relocating,
|
|
1712
1704
|
signal,
|
|
@@ -1714,10 +1706,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1714
1706
|
);
|
|
1715
1707
|
}
|
|
1716
1708
|
|
|
1717
|
-
private async publishMeshServing(
|
|
1718
|
-
meshName: string,
|
|
1719
|
-
signal?: AbortSignal
|
|
1720
|
-
): Promise<void> {
|
|
1709
|
+
private async publishMeshServing(meshName: string, signal?: AbortSignal): Promise<void> {
|
|
1721
1710
|
await this.spotNodeRuntime?.reconcileAndPublishMeshNodeState(
|
|
1722
1711
|
ZLinkFrameworkRuntimeState.Serving,
|
|
1723
1712
|
meshName,
|
|
@@ -1731,10 +1720,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1731
1720
|
await this.statefulAuthorityRoutes?.reconcile(signal);
|
|
1732
1721
|
}
|
|
1733
1722
|
|
|
1734
|
-
private async publishMeshDraining(
|
|
1735
|
-
meshName: string,
|
|
1736
|
-
signal?: AbortSignal
|
|
1737
|
-
): Promise<void> {
|
|
1723
|
+
private async publishMeshDraining(meshName: string, signal?: AbortSignal): Promise<void> {
|
|
1738
1724
|
const node = this.spotNodeRuntime?.meshNode(meshName);
|
|
1739
1725
|
if (node !== undefined) {
|
|
1740
1726
|
await node.publishDraining?.();
|
|
@@ -1761,22 +1747,22 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1761
1747
|
let storeUnavailable = false;
|
|
1762
1748
|
while (performance.now() < deadlineAt) {
|
|
1763
1749
|
try {
|
|
1764
|
-
if (await this.hasExactAutomaticPeerReadiness(
|
|
1765
|
-
|
|
1766
|
-
targetApplicationVersion
|
|
1767
|
-
)) return undefined;
|
|
1750
|
+
if (await this.hasExactAutomaticPeerReadiness(location, targetApplicationVersion))
|
|
1751
|
+
return undefined;
|
|
1768
1752
|
storeUnavailable = false;
|
|
1769
1753
|
} catch {
|
|
1770
1754
|
storeUnavailable = true;
|
|
1771
1755
|
}
|
|
1772
|
-
await new Promise((resolve) =>
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1756
|
+
await new Promise((resolve) =>
|
|
1757
|
+
setTimeout(
|
|
1758
|
+
resolve,
|
|
1759
|
+
Math.min(
|
|
1760
|
+
this.options.registration.locations.options.pollingIntervalMs ??
|
|
1761
|
+
zlinkDefaultLocationOptions.pollingIntervalMs,
|
|
1762
|
+
Math.max(1, deadlineAt - performance.now())
|
|
1763
|
+
)
|
|
1778
1764
|
)
|
|
1779
|
-
)
|
|
1765
|
+
);
|
|
1780
1766
|
}
|
|
1781
1767
|
return storeUnavailable
|
|
1782
1768
|
? ZLinkFrameworkRelocationReason.StoreUnavailable
|
|
@@ -1798,8 +1784,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1798
1784
|
targetApplicationVersion: bigint
|
|
1799
1785
|
): Promise<boolean> {
|
|
1800
1786
|
for (const [meshName, registration] of this.options.registration.spotNodes) {
|
|
1801
|
-
if (
|
|
1802
|
-
|
|
1787
|
+
if (
|
|
1788
|
+
(registration.router?.manualConnections?.length ?? 0) > 0 ||
|
|
1789
|
+
(registration.router?.manualPeerConnections?.length ?? 0) > 0
|
|
1790
|
+
) {
|
|
1803
1791
|
continue;
|
|
1804
1792
|
}
|
|
1805
1793
|
const node = this.spotNodeRuntime?.meshNode(meshName);
|
|
@@ -1809,28 +1797,38 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1809
1797
|
if (localDescriptor === undefined) return false;
|
|
1810
1798
|
const descriptors = await location.listLiveMeshNodes(meshName);
|
|
1811
1799
|
const peers = node.peers();
|
|
1812
|
-
if (
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1800
|
+
if (
|
|
1801
|
+
!hasExactPeerReadiness(
|
|
1802
|
+
descriptors,
|
|
1803
|
+
{
|
|
1804
|
+
...local,
|
|
1805
|
+
applicationVersion: targetApplicationVersion,
|
|
1806
|
+
maintenanceWave: localDescriptor.maintenanceWave
|
|
1807
|
+
},
|
|
1808
|
+
peers
|
|
1809
|
+
)
|
|
1810
|
+
)
|
|
1811
|
+
return false;
|
|
1817
1812
|
}
|
|
1818
1813
|
return true;
|
|
1819
1814
|
}
|
|
1820
1815
|
|
|
1821
1816
|
private async publishHostRelocated(): Promise<void> {
|
|
1822
|
-
await Promise.all(
|
|
1823
|
-
this.
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1817
|
+
await Promise.all(
|
|
1818
|
+
[...this.options.registration.spotNodes.keys()].map((meshName) =>
|
|
1819
|
+
this.spotNodeRuntime?.publishMeshNodeState(
|
|
1820
|
+
ZLinkFrameworkRuntimeState.Relocated,
|
|
1821
|
+
undefined,
|
|
1822
|
+
meshName
|
|
1823
|
+
)
|
|
1824
|
+
)
|
|
1825
|
+
);
|
|
1828
1826
|
}
|
|
1829
1827
|
|
|
1830
1828
|
private async publishHostDraining(signal: AbortSignal): Promise<void> {
|
|
1831
1829
|
try {
|
|
1832
1830
|
const runtime = this.locationOwner.currentRuntime;
|
|
1833
|
-
if (runtime !== undefined && !await runtime.publishDraining(signal)) {
|
|
1831
|
+
if (runtime !== undefined && !(await runtime.publishDraining(signal))) {
|
|
1834
1832
|
throw new Error('Draining descriptor publication returned false.');
|
|
1835
1833
|
}
|
|
1836
1834
|
} catch (error) {
|
|
@@ -1871,25 +1869,12 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1871
1869
|
target.targetSpotId as never
|
|
1872
1870
|
),
|
|
1873
1871
|
isMaterializing: (target) =>
|
|
1874
|
-
spotManager.isInstanceMaterializing(
|
|
1875
|
-
|
|
1876
|
-
target.targetSpotId as never
|
|
1877
|
-
),
|
|
1878
|
-
isClosing: (target) =>
|
|
1879
|
-
spotManager.isInstanceClosing(
|
|
1880
|
-
meshName,
|
|
1881
|
-
target.targetSpotId as never
|
|
1882
|
-
),
|
|
1872
|
+
spotManager.isInstanceMaterializing(meshName, target.targetSpotId as never),
|
|
1873
|
+
isClosing: (target) => spotManager.isInstanceClosing(meshName, target.targetSpotId as never),
|
|
1883
1874
|
isIdleEvicting: (target) =>
|
|
1884
|
-
spotManager.isInstanceSpotIdleEvicting(
|
|
1885
|
-
meshName,
|
|
1886
|
-
target.targetSpotId as never
|
|
1887
|
-
),
|
|
1875
|
+
spotManager.isInstanceSpotIdleEvicting(meshName, target.targetSpotId as never),
|
|
1888
1876
|
beginIdleEviction: (target) =>
|
|
1889
|
-
spotManager.beginInstanceSpotIdleEviction(
|
|
1890
|
-
meshName,
|
|
1891
|
-
target.targetSpotId as never
|
|
1892
|
-
),
|
|
1877
|
+
spotManager.beginInstanceSpotIdleEviction(meshName, target.targetSpotId as never),
|
|
1893
1878
|
materialize: (target, objectGeneration) =>
|
|
1894
1879
|
spotManager.materializeInstance(
|
|
1895
1880
|
meshName,
|
|
@@ -1898,8 +1883,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1898
1883
|
objectGeneration,
|
|
1899
1884
|
this.executionState?.abortController.signal
|
|
1900
1885
|
),
|
|
1901
|
-
discard: (target) =>
|
|
1902
|
-
spotManager.discardInstance(meshName, target.targetSpotId as never),
|
|
1886
|
+
discard: (target) => spotManager.discardInstance(meshName, target.targetSpotId as never),
|
|
1903
1887
|
beginTerminal: (target) =>
|
|
1904
1888
|
spotManager.beginInstanceTerminal(
|
|
1905
1889
|
meshName,
|
|
@@ -1950,9 +1934,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1950
1934
|
placementCreate: async (actorId, actorType, createOnly, call, signal) => {
|
|
1951
1935
|
const placement = this.actorPlacement;
|
|
1952
1936
|
if (placement === undefined) {
|
|
1953
|
-
throw new ZLinkConfigurationException(
|
|
1954
|
-
'Actor placement runtime is not initialized.'
|
|
1955
|
-
);
|
|
1937
|
+
throw new ZLinkConfigurationException('Actor placement runtime is not initialized.');
|
|
1956
1938
|
}
|
|
1957
1939
|
const requestPayload = encodeFrameworkCreationPayload(
|
|
1958
1940
|
call.request,
|
|
@@ -1987,56 +1969,58 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
1987
1969
|
this.ensureLocationRuntime();
|
|
1988
1970
|
return {
|
|
1989
1971
|
...new ZLinkSpotRuntimeOptionsFactory({
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
1972
|
+
registration: this.options.registration,
|
|
1973
|
+
channelTransport: this.channelTransport,
|
|
1974
|
+
routeTransport: this.routeTransport,
|
|
1975
|
+
addressTransport: this.spotAddressTransport,
|
|
1976
|
+
spotPublisherTransport: this.spotPublisherTransport,
|
|
1977
|
+
meshRouters: this.meshRouters,
|
|
1978
|
+
runtimeEventPublisher: this.runtimeEventPublisher,
|
|
1979
|
+
spotNodeRuntime: () => this.spotNodeRuntime,
|
|
1980
|
+
actorManager: () => this.actorManager,
|
|
1981
|
+
// User Spot visibility is published only by the generic authority
|
|
1982
|
+
// coordinator after application initialization. The legacy location
|
|
1983
|
+
// claim would expose a Creating object before that Ready barrier.
|
|
1984
|
+
locationLifecycle: () => undefined,
|
|
1985
|
+
releaseInstanceAuthority: (meshName, spotId, objectGeneration) =>
|
|
1986
|
+
this.locationOwner.currentLifecycle?.releaseSpot(meshName, spotId, objectGeneration) ??
|
|
1987
|
+
Promise.resolve(),
|
|
1988
|
+
beginInstanceIdleClosingAuthority: (meshName, spotId) =>
|
|
1989
|
+
this.locationOwner.currentLifecycle?.beginInstanceSpotClosing(meshName, spotId) ??
|
|
1990
|
+
Promise.resolve(undefined),
|
|
1991
|
+
beginInstanceClosingAuthority: (meshName, spotId) =>
|
|
1992
|
+
this.locationOwner.currentLifecycle?.beginInstanceSpotClosing(meshName, spotId) ??
|
|
1993
|
+
Promise.resolve(undefined),
|
|
1994
|
+
createLocationSpotRouteResolver: () => this.createLocationSpotRouteResolver(),
|
|
1995
|
+
boundSessionRelay: this.boundSessionRelay,
|
|
1996
|
+
actorHandoff: this.actorHandoff,
|
|
1997
|
+
dispatchErrorReporter: (errorSink) => this.createDispatchErrorReporter(errorSink),
|
|
1998
|
+
runtimeOrPreStartErrorSink: this.runtimeOrPreStartErrorSink,
|
|
1999
|
+
detachedTaskRunner: this.detachedTaskRunner(),
|
|
2000
|
+
metrics: this.metrics,
|
|
2001
|
+
admission: this.admission,
|
|
2002
|
+
statefulExecutionAllowed: () => this.ownerAdmissionOpen()
|
|
2003
|
+
}).create(this.actorTransferRuntime),
|
|
2022
2004
|
activationConcurrencyLimitProvider: (meshName: string) =>
|
|
2023
2005
|
this.options.registration.spotNodes.get(meshName)?.activationConcurrencyLimit ?? 128,
|
|
2024
2006
|
onInstanceActivationConcurrencyChanged: (meshName: string) => {
|
|
2025
|
-
void this.spotNodeRuntime
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2007
|
+
void this.spotNodeRuntime
|
|
2008
|
+
?.publishMeshNodeState(
|
|
2009
|
+
this.runtimeState,
|
|
2010
|
+
this.executionState?.abortController.signal,
|
|
2011
|
+
meshName
|
|
2012
|
+
)
|
|
2013
|
+
.catch(() => undefined);
|
|
2030
2014
|
}
|
|
2031
2015
|
};
|
|
2032
2016
|
}
|
|
2033
2017
|
|
|
2034
|
-
createPublicSpotManager(
|
|
2018
|
+
createPublicSpotManager(
|
|
2019
|
+
local: DefaultZLinkSpotManager
|
|
2020
|
+
): import('../../contracts').ZLinkSpotManager {
|
|
2035
2021
|
const locationStore = this.locationOwner.locationStore();
|
|
2036
2022
|
if (locationStore === undefined) {
|
|
2037
|
-
throw new ZLinkConfigurationException(
|
|
2038
|
-
'User Spot creation requires a Location Store.'
|
|
2039
|
-
);
|
|
2023
|
+
throw new ZLinkConfigurationException('User Spot creation requires a Location Store.');
|
|
2040
2024
|
}
|
|
2041
2025
|
this.actorPlacement ??= new ZLinkActorPlacementCoordinator({
|
|
2042
2026
|
store: locationStore,
|
|
@@ -2050,7 +2034,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2050
2034
|
}
|
|
2051
2035
|
return node.requestActorCreate(targetNodeRid, request, timeoutMs);
|
|
2052
2036
|
},
|
|
2053
|
-
decodeRemoteReply: payload => {
|
|
2037
|
+
decodeRemoteReply: (payload) => {
|
|
2054
2038
|
const message = RuntimeMessage.from(payload);
|
|
2055
2039
|
try {
|
|
2056
2040
|
return decodeFrameworkPayloadMessage(
|
|
@@ -2091,18 +2075,20 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2091
2075
|
descriptors,
|
|
2092
2076
|
meshNode,
|
|
2093
2077
|
signal,
|
|
2094
|
-
descriptor => {
|
|
2095
|
-
const capability = descriptor.objectCapabilities.find(
|
|
2096
|
-
candidate.objectKind === 'actor'
|
|
2097
|
-
|
|
2078
|
+
(descriptor) => {
|
|
2079
|
+
const capability = descriptor.objectCapabilities.find(
|
|
2080
|
+
(candidate) => candidate.objectKind === 'actor' && candidate.stableType === stableType
|
|
2081
|
+
);
|
|
2098
2082
|
const actors = descriptor.populationCapacity.actors;
|
|
2099
|
-
return
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2083
|
+
return (
|
|
2084
|
+
descriptor.state === ZLinkFrameworkRuntimeState.Serving &&
|
|
2085
|
+
descriptor.objectRole === 'server' &&
|
|
2086
|
+
descriptor.placementWeight > 0 &&
|
|
2087
|
+
descriptor.entrySpotId !== undefined &&
|
|
2088
|
+
excludedNodeRids?.has(String(descriptor.rid)) !== true &&
|
|
2089
|
+
(actors.limit === 0 || actors.active + actors.reserved < actors.limit) &&
|
|
2090
|
+
capability !== undefined
|
|
2091
|
+
);
|
|
2106
2092
|
}
|
|
2107
2093
|
);
|
|
2108
2094
|
if (selected === undefined) return undefined;
|
|
@@ -2124,8 +2110,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2124
2110
|
ownerId: selected.ownerId,
|
|
2125
2111
|
leaseGeneration: selected.leaseGeneration
|
|
2126
2112
|
},
|
|
2127
|
-
isLocal:
|
|
2128
|
-
|
|
2113
|
+
isLocal:
|
|
2114
|
+
String(localStatus.routingId) === String(selected.rid) &&
|
|
2115
|
+
localStatus.lifecycleGeneration === selected.lifecycleGeneration
|
|
2129
2116
|
};
|
|
2130
2117
|
}
|
|
2131
2118
|
});
|
|
@@ -2137,11 +2124,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2137
2124
|
},
|
|
2138
2125
|
forgetReadyRoute: (meshName, route) => {
|
|
2139
2126
|
this.cachedLocationSpotRouteResolver?.invalidate?.(route.spot.spotId);
|
|
2140
|
-
this.spotNodeRuntime
|
|
2141
|
-
|
|
2142
|
-
route.authorityOwnerGeneration,
|
|
2143
|
-
route.storeVersion
|
|
2144
|
-
);
|
|
2127
|
+
this.spotNodeRuntime
|
|
2128
|
+
?.meshNode(meshName)
|
|
2129
|
+
?.forgetSpotRoute?.(route.spot, route.authorityOwnerGeneration, route.storeVersion);
|
|
2145
2130
|
},
|
|
2146
2131
|
remoteCreate: (meshName, targetNodeRid, request, timeoutMs) => {
|
|
2147
2132
|
const node = this.spotNodeRuntime?.meshNode(meshName);
|
|
@@ -2153,7 +2138,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2153
2138
|
}
|
|
2154
2139
|
return node.requestUserSpotCreate(targetNodeRid, request, timeoutMs);
|
|
2155
2140
|
},
|
|
2156
|
-
decodeRemoteReply: payload => {
|
|
2141
|
+
decodeRemoteReply: (payload) => {
|
|
2157
2142
|
const message = RuntimeMessage.from(payload);
|
|
2158
2143
|
try {
|
|
2159
2144
|
return decodeFrameworkPayloadMessage(
|
|
@@ -2200,24 +2185,27 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2200
2185
|
descriptors,
|
|
2201
2186
|
meshNode,
|
|
2202
2187
|
signal,
|
|
2203
|
-
descriptor => {
|
|
2204
|
-
const capability = descriptor.objectCapabilities.find(
|
|
2205
|
-
candidate
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2188
|
+
(descriptor) => {
|
|
2189
|
+
const capability = descriptor.objectCapabilities.find(
|
|
2190
|
+
(candidate) =>
|
|
2191
|
+
candidate.objectKind === 'user_spot' && candidate.stableType === request.stableType
|
|
2192
|
+
);
|
|
2193
|
+
const spotTypeCapacity = descriptor.populationCapacity.spotTypes.find(
|
|
2194
|
+
(candidate) =>
|
|
2195
|
+
candidate.objectKind === 'user_spot' && candidate.stableType === request.stableType
|
|
2196
|
+
);
|
|
2210
2197
|
const spots = descriptor.populationCapacity.spots;
|
|
2211
|
-
return
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2198
|
+
return (
|
|
2199
|
+
descriptor.state === 1 &&
|
|
2200
|
+
descriptor.objectRole === 'server' &&
|
|
2201
|
+
descriptor.placementWeight > 0 &&
|
|
2202
|
+
excludedNodeRids?.has(String(descriptor.rid)) !== true &&
|
|
2203
|
+
(spots.limit === 0 || spots.active + spots.reserved < spots.limit) &&
|
|
2204
|
+
capability !== undefined &&
|
|
2205
|
+
(spotTypeCapacity === undefined ||
|
|
2206
|
+
spotTypeCapacity.limit === 0 ||
|
|
2207
|
+
spotTypeCapacity.active + spotTypeCapacity.reserved < spotTypeCapacity.limit)
|
|
2208
|
+
);
|
|
2221
2209
|
}
|
|
2222
2210
|
);
|
|
2223
2211
|
if (selected === undefined) return undefined;
|
|
@@ -2230,9 +2218,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2230
2218
|
ownerId: selected.ownerId,
|
|
2231
2219
|
leaseGeneration: selected.leaseGeneration
|
|
2232
2220
|
},
|
|
2233
|
-
isLocal:
|
|
2234
|
-
|
|
2235
|
-
|
|
2221
|
+
isLocal:
|
|
2222
|
+
localStatus !== undefined &&
|
|
2223
|
+
String(localStatus.routingId) === String(selected.rid) &&
|
|
2224
|
+
localStatus.lifecycleGeneration === selected.lifecycleGeneration
|
|
2236
2225
|
};
|
|
2237
2226
|
}
|
|
2238
2227
|
});
|
|
@@ -2247,135 +2236,158 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2247
2236
|
const node = runtime.meshNode(meshName);
|
|
2248
2237
|
if (node === undefined) continue;
|
|
2249
2238
|
node.registerUserSpotOperationHandler({
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2239
|
+
create: async (record, signal) => {
|
|
2240
|
+
const coordinated = await coordinator.handleRemoteCreate(
|
|
2241
|
+
record,
|
|
2242
|
+
async (requestPayload, authority, createSignal) => {
|
|
2243
|
+
const selected = factories.get(meshName)?.get(record.stableType);
|
|
2244
|
+
if (selected === undefined) {
|
|
2245
|
+
throw new ZLinkConfigurationException(
|
|
2246
|
+
`User Spot factory '${record.stableType}' is not registered on RouteMesh '${meshName}'.`
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
2249
|
+
const request = decodeFrameworkCreationPayload(
|
|
2250
|
+
requestPayload,
|
|
2251
|
+
this.options.registration.messageSerializers
|
|
2258
2252
|
);
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2253
|
+
local.beginUserSpotPublication(meshName, record.spotId as never);
|
|
2254
|
+
try {
|
|
2255
|
+
const result = await local.getOrCreateWithAuthority(
|
|
2256
|
+
meshName,
|
|
2257
|
+
selected.implementation as never,
|
|
2258
|
+
record.spotId as never,
|
|
2259
|
+
request,
|
|
2260
|
+
{
|
|
2261
|
+
stableType: record.stableType,
|
|
2262
|
+
objectGeneration: authority.objectGeneration,
|
|
2263
|
+
authorityOwnerGeneration: authority.authorityOwnerGeneration
|
|
2264
|
+
},
|
|
2265
|
+
createSignal
|
|
2266
|
+
);
|
|
2267
|
+
return {
|
|
2268
|
+
...result,
|
|
2269
|
+
publication: {
|
|
2270
|
+
publish: () => local.publishUserSpot(meshName, record.spotId as never),
|
|
2271
|
+
abort: () => local.abortUserSpotPublication(meshName, record.spotId as never)
|
|
2272
|
+
}
|
|
2273
|
+
};
|
|
2274
|
+
} catch (error) {
|
|
2275
|
+
local.abortUserSpotPublication(meshName, record.spotId as never);
|
|
2276
|
+
throw error;
|
|
2277
|
+
}
|
|
2278
|
+
},
|
|
2279
|
+
async (cleanupSignal) => {
|
|
2280
|
+
await local.close(meshName, record.spotId as never, cleanupSignal);
|
|
2281
|
+
},
|
|
2282
|
+
signal
|
|
2283
|
+
);
|
|
2284
|
+
const reply = coordinated.result.reply;
|
|
2285
|
+
let payload;
|
|
2286
|
+
if (reply !== undefined && coordinated.result.state !== ZLinkSpotCreateState.Existing) {
|
|
2287
|
+
const message = encodeFrameworkPayloadMessage(
|
|
2288
|
+
reply,
|
|
2262
2289
|
this.options.registration.messageSerializers
|
|
2263
2290
|
);
|
|
2264
|
-
local.beginUserSpotPublication(meshName, record.spotId as never);
|
|
2265
2291
|
try {
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
request,
|
|
2271
|
-
{
|
|
2272
|
-
stableType: record.stableType,
|
|
2273
|
-
objectGeneration: authority.objectGeneration,
|
|
2274
|
-
authorityOwnerGeneration: authority.authorityOwnerGeneration
|
|
2275
|
-
},
|
|
2276
|
-
createSignal
|
|
2277
|
-
);
|
|
2278
|
-
return {
|
|
2279
|
-
...result,
|
|
2280
|
-
publication: {
|
|
2281
|
-
publish: () => local.publishUserSpot(meshName, record.spotId as never),
|
|
2282
|
-
abort: () => local.abortUserSpotPublication(meshName, record.spotId as never)
|
|
2283
|
-
}
|
|
2292
|
+
payload = {
|
|
2293
|
+
packetName: 'ZLinkFrameworkUserSpotReply',
|
|
2294
|
+
contentType: 'application/octet-stream',
|
|
2295
|
+
payload: Buffer.from(message.data())
|
|
2284
2296
|
};
|
|
2285
|
-
}
|
|
2286
|
-
|
|
2287
|
-
throw error;
|
|
2297
|
+
} finally {
|
|
2298
|
+
message.close();
|
|
2288
2299
|
}
|
|
2289
|
-
},
|
|
2290
|
-
async cleanupSignal => {
|
|
2291
|
-
await local.close(meshName, record.spotId as never, cleanupSignal);
|
|
2292
|
-
},
|
|
2293
|
-
signal
|
|
2294
|
-
);
|
|
2295
|
-
const reply = coordinated.result.reply;
|
|
2296
|
-
let payload;
|
|
2297
|
-
if (
|
|
2298
|
-
reply !== undefined
|
|
2299
|
-
&& coordinated.result.state !== ZLinkSpotCreateState.Existing
|
|
2300
|
-
) {
|
|
2301
|
-
const message = encodeFrameworkPayloadMessage(
|
|
2302
|
-
reply,
|
|
2303
|
-
this.options.registration.messageSerializers
|
|
2304
|
-
);
|
|
2305
|
-
try {
|
|
2306
|
-
payload = {
|
|
2307
|
-
packetName: 'ZLinkFrameworkUserSpotReply',
|
|
2308
|
-
contentType: 'application/octet-stream',
|
|
2309
|
-
payload: Buffer.from(message.data())
|
|
2310
|
-
};
|
|
2311
|
-
} finally {
|
|
2312
|
-
message.close();
|
|
2313
2300
|
}
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
);
|
|
2338
|
-
}
|
|
2339
|
-
return await actorPlacement.handleRemoteCreate(
|
|
2340
|
-
record,
|
|
2341
|
-
async (requestPayload, authority, createSignal) => {
|
|
2342
|
-
const request = decodeFrameworkCreationPayload(
|
|
2343
|
-
requestPayload,
|
|
2344
|
-
this.options.registration.messageSerializers
|
|
2301
|
+
return {
|
|
2302
|
+
terminalResult: RequestResult.Ok,
|
|
2303
|
+
failureCode: 0,
|
|
2304
|
+
tail: {
|
|
2305
|
+
kind: 'userSpotCreate' as const,
|
|
2306
|
+
createResult:
|
|
2307
|
+
coordinated.result.state === ZLinkSpotCreateState.Existing
|
|
2308
|
+
? ('existing' as const)
|
|
2309
|
+
: coordinated.result.state === ZLinkSpotCreateState.Created
|
|
2310
|
+
? ('created' as const)
|
|
2311
|
+
: ('rejected' as const),
|
|
2312
|
+
spotId: String(coordinated.spot.spotId),
|
|
2313
|
+
objectGeneration: coordinated.spot.objectGeneration
|
|
2314
|
+
},
|
|
2315
|
+
...(payload === undefined ? {} : { payload })
|
|
2316
|
+
};
|
|
2317
|
+
},
|
|
2318
|
+
createActor: async (record, signal) => {
|
|
2319
|
+
const actorPlacement = this.actorPlacement;
|
|
2320
|
+
const actors = this.actorManager;
|
|
2321
|
+
if (actorPlacement === undefined || actors === undefined) {
|
|
2322
|
+
throw new ZLinkConfigurationException(
|
|
2323
|
+
'Actor placement target runtime is not initialized.'
|
|
2345
2324
|
);
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2325
|
+
}
|
|
2326
|
+
return await actorPlacement.handleRemoteCreate(
|
|
2327
|
+
record,
|
|
2328
|
+
async (requestPayload, authority, createSignal) => {
|
|
2329
|
+
const request = decodeFrameworkCreationPayload(
|
|
2330
|
+
requestPayload,
|
|
2331
|
+
this.options.registration.messageSerializers
|
|
2351
2332
|
);
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2333
|
+
const entrySpotId = this.spotNodeRuntime?.meshNodeDescriptor(meshName)?.entrySpotId;
|
|
2334
|
+
if (entrySpotId === undefined) {
|
|
2335
|
+
throw new ZLinkConfigurationException(
|
|
2336
|
+
`Remote Actor creation requires the '${meshName}' MeshNode Entry Spot descriptor.`
|
|
2337
|
+
);
|
|
2338
|
+
}
|
|
2339
|
+
const entrySpot = node.entrySpot().status();
|
|
2340
|
+
const nativeActorRef = node.restoreActorAuthority?.(
|
|
2341
|
+
record.actorId,
|
|
2342
|
+
record.stableType,
|
|
2343
|
+
authority.objectGeneration,
|
|
2344
|
+
authority.authorityOwnerGeneration,
|
|
2345
|
+
String(entrySpot.routingId),
|
|
2346
|
+
entrySpot.lifecycleGeneration,
|
|
2347
|
+
1n
|
|
2366
2348
|
);
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2349
|
+
if (nativeActorRef === undefined) {
|
|
2350
|
+
throw new ZLinkConfigurationException(
|
|
2351
|
+
'Remote Actor creation requires native authority restoration support.'
|
|
2352
|
+
);
|
|
2353
|
+
}
|
|
2354
|
+
const local = await actors.createReservedActorResult(
|
|
2355
|
+
record.actorId,
|
|
2356
|
+
record.stableType,
|
|
2357
|
+
request,
|
|
2358
|
+
createSignal,
|
|
2359
|
+
nativeActorRef
|
|
2360
|
+
);
|
|
2361
|
+
if (local.status === 'failed') {
|
|
2362
|
+
return { result: 'failed' as const, error: local.error };
|
|
2363
|
+
}
|
|
2364
|
+
if (local.status === 'rejected') {
|
|
2365
|
+
let reply: Buffer | undefined;
|
|
2366
|
+
if (local.reply !== undefined) {
|
|
2367
|
+
const encoded = encodeFrameworkPayloadMessage(
|
|
2368
|
+
local.reply,
|
|
2369
|
+
this.options.registration.messageSerializers
|
|
2370
|
+
);
|
|
2371
|
+
try {
|
|
2372
|
+
reply = Buffer.from(encoded.data());
|
|
2373
|
+
} finally {
|
|
2374
|
+
encoded.close();
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
return {
|
|
2378
|
+
result: 'rejected' as const,
|
|
2379
|
+
...(reply === undefined ? {} : { reply })
|
|
2380
|
+
};
|
|
2381
|
+
}
|
|
2382
|
+
if (
|
|
2383
|
+
local.actorRef.objectGeneration !== authority.objectGeneration ||
|
|
2384
|
+
String(local.actorRef.nodeRid) !== record.reservation.targetNodeRid
|
|
2385
|
+
) {
|
|
2386
|
+
throw createInternalFrameworkException(
|
|
2387
|
+
ZLinkFrameworkInternalErrorKind.ActorCreateFailed,
|
|
2388
|
+
`Actor '${record.actorId}' native authority does not match its placement reservation.`
|
|
2389
|
+
);
|
|
2390
|
+
}
|
|
2379
2391
|
let reply: Buffer | undefined;
|
|
2380
2392
|
if (local.reply !== undefined) {
|
|
2381
2393
|
const encoded = encodeFrameworkPayloadMessage(
|
|
@@ -2389,85 +2401,56 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2389
2401
|
}
|
|
2390
2402
|
}
|
|
2391
2403
|
return {
|
|
2392
|
-
result: '
|
|
2393
|
-
|
|
2404
|
+
result: 'created' as const,
|
|
2405
|
+
actor: {
|
|
2406
|
+
...local.actorRef,
|
|
2407
|
+
meshName
|
|
2408
|
+
},
|
|
2409
|
+
entrySpotId,
|
|
2410
|
+
entrySpotGeneration: entrySpot.lifecycleGeneration,
|
|
2411
|
+
...(reply === undefined ? {} : { reply }),
|
|
2412
|
+
onPublished: () =>
|
|
2413
|
+
actors.adoptCreatedAuthority(
|
|
2414
|
+
record.actorId,
|
|
2415
|
+
authority.authorityOwnerGeneration,
|
|
2416
|
+
authority.ownerLeaseGeneration
|
|
2417
|
+
)
|
|
2394
2418
|
};
|
|
2395
|
-
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
local.reply,
|
|
2409
|
-
this.options.registration.messageSerializers
|
|
2410
|
-
);
|
|
2411
|
-
try {
|
|
2412
|
-
reply = Buffer.from(encoded.data());
|
|
2413
|
-
} finally {
|
|
2414
|
-
encoded.close();
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2419
|
+
},
|
|
2420
|
+
signal
|
|
2421
|
+
);
|
|
2422
|
+
},
|
|
2423
|
+
close: async (record, signal) => {
|
|
2424
|
+
if (!local.hasActiveSpot(record.target.spotId as never)) {
|
|
2425
|
+
throw createInternalFrameworkException(
|
|
2426
|
+
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
2427
|
+
`User Spot '${record.target.spotId}' is not materialized on its authority owner.`,
|
|
2428
|
+
true
|
|
2429
|
+
);
|
|
2430
|
+
}
|
|
2431
|
+
if (!local.canCloseUserSpot(meshName, record.target.spotId as never)) {
|
|
2417
2432
|
return {
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
entrySpotGeneration: entrySpot.lifecycleGeneration,
|
|
2425
|
-
...(reply === undefined ? {} : { reply }),
|
|
2426
|
-
onPublished: () => actors.adoptCreatedAuthority(
|
|
2427
|
-
record.actorId,
|
|
2428
|
-
authority.authorityOwnerGeneration,
|
|
2429
|
-
authority.ownerLeaseGeneration
|
|
2430
|
-
)
|
|
2433
|
+
terminalResult: RequestResult.Ok,
|
|
2434
|
+
failureCode: 0,
|
|
2435
|
+
tail: {
|
|
2436
|
+
kind: 'userSpotClose' as const,
|
|
2437
|
+
closed: false
|
|
2438
|
+
}
|
|
2431
2439
|
};
|
|
2432
|
-
}
|
|
2433
|
-
signal
|
|
2434
|
-
);
|
|
2435
|
-
},
|
|
2436
|
-
close: async (record, signal) => {
|
|
2437
|
-
if (!local.hasActiveSpot(record.target.spotId as never)) {
|
|
2438
|
-
throw createInternalFrameworkException(
|
|
2439
|
-
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
2440
|
-
`User Spot '${record.target.spotId}' is not materialized on its authority owner.`,
|
|
2441
|
-
true
|
|
2442
|
-
);
|
|
2443
|
-
}
|
|
2444
|
-
if (!local.canCloseUserSpot(meshName, record.target.spotId as never)) {
|
|
2440
|
+
}
|
|
2445
2441
|
return {
|
|
2446
2442
|
terminalResult: RequestResult.Ok,
|
|
2447
2443
|
failureCode: 0,
|
|
2448
2444
|
tail: {
|
|
2449
2445
|
kind: 'userSpotClose' as const,
|
|
2450
|
-
closed:
|
|
2446
|
+
closed: await coordinator.handleRemoteClose(
|
|
2447
|
+
record,
|
|
2448
|
+
(spot, closeSignal) => local.close(spot.meshName, spot.spotId, closeSignal),
|
|
2449
|
+
signal
|
|
2450
|
+
)
|
|
2451
2451
|
}
|
|
2452
2452
|
};
|
|
2453
2453
|
}
|
|
2454
|
-
return {
|
|
2455
|
-
terminalResult: RequestResult.Ok,
|
|
2456
|
-
failureCode: 0,
|
|
2457
|
-
tail: {
|
|
2458
|
-
kind: 'userSpotClose' as const,
|
|
2459
|
-
closed: await coordinator.handleRemoteClose(
|
|
2460
|
-
record,
|
|
2461
|
-
(spot, closeSignal) => local.close(
|
|
2462
|
-
spot.meshName,
|
|
2463
|
-
spot.spotId,
|
|
2464
|
-
closeSignal
|
|
2465
|
-
),
|
|
2466
|
-
signal
|
|
2467
|
-
)
|
|
2468
|
-
}
|
|
2469
|
-
};
|
|
2470
|
-
}
|
|
2471
2454
|
});
|
|
2472
2455
|
}
|
|
2473
2456
|
};
|
|
@@ -2505,8 +2488,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2505
2488
|
private actorRuntimeOptionsFactory(): ZLinkActorRuntimeOptionsFactory {
|
|
2506
2489
|
return new ZLinkActorRuntimeOptionsFactory({
|
|
2507
2490
|
registration: this.options.registration,
|
|
2508
|
-
messageFlow: () =>
|
|
2509
|
-
this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink).flow,
|
|
2491
|
+
messageFlow: () => this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink).flow,
|
|
2510
2492
|
routeTransport: this.routeTransport,
|
|
2511
2493
|
streamBindingRuntime: this.streamBindingRuntime,
|
|
2512
2494
|
providerResolver: this.options.providerResolver,
|
|
@@ -2518,16 +2500,18 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2518
2500
|
meshNode: (meshName) => this.spotNodeRuntime?.meshNode(meshName),
|
|
2519
2501
|
meshCompletions: (meshName) => this.spotNodeRuntime?.meshCompletionTable(meshName),
|
|
2520
2502
|
notifyEntrySpotActorCreated: (nodeRid, actor, createRequest, signal) =>
|
|
2521
|
-
this.spotNodeRuntime?.notifyEntrySpotActorCreated(nodeRid, actor, createRequest, signal)
|
|
2522
|
-
|
|
2503
|
+
this.spotNodeRuntime?.notifyEntrySpotActorCreated(nodeRid, actor, createRequest, signal) ??
|
|
2504
|
+
Promise.resolve(undefined),
|
|
2523
2505
|
locationLifecycle: () => this.locationOwner.currentLifecycle,
|
|
2524
2506
|
primaryMeshName: () => this.meshRouters.primaryMeshName(),
|
|
2525
2507
|
actorMeshName: (actorType) => this.meshRouters.actorMeshName(actorType),
|
|
2526
2508
|
createLocationSpotRouteResolver: () => this.createLocationSpotRouteResolver(),
|
|
2527
2509
|
createActorLocationResolver: () => this.createActorLocationResolver(),
|
|
2528
2510
|
forgetDestroyedActorRef: (actorId) => this.destroyedActorRefs.delete(actorId),
|
|
2529
|
-
rememberDestroyedActorRef: (actorId, actorRef) =>
|
|
2530
|
-
|
|
2511
|
+
rememberDestroyedActorRef: (actorId, actorRef) =>
|
|
2512
|
+
this.destroyedActorRefs.set(actorId, actorRef),
|
|
2513
|
+
invalidateActorRoute: (actorId) =>
|
|
2514
|
+
this.actorClientLocationResolver?.invalidateActorRoute(actorId),
|
|
2531
2515
|
publishActorAuthority: async (actorType, actorRef, ownerNodeGeneration, signal) => {
|
|
2532
2516
|
const store = this.locationOwner.currentStores?.locationStore;
|
|
2533
2517
|
if (store === undefined) return;
|
|
@@ -2544,22 +2528,32 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2544
2528
|
`Actor '${actorRef.actorId}' authority requires its RouteMesh Entry Spot.`
|
|
2545
2529
|
);
|
|
2546
2530
|
}
|
|
2547
|
-
await publishInitialActorAuthority(
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2531
|
+
await publishInitialActorAuthority(
|
|
2532
|
+
store,
|
|
2533
|
+
{
|
|
2534
|
+
actorType,
|
|
2535
|
+
actor: actorRef,
|
|
2536
|
+
meshName,
|
|
2537
|
+
ownerNodeGeneration,
|
|
2538
|
+
owner,
|
|
2539
|
+
spotId: entrySpotId,
|
|
2540
|
+
spotGeneration: ownerNodeGeneration,
|
|
2541
|
+
spotKind: ZLinkSpotKind.Entry
|
|
2542
|
+
},
|
|
2543
|
+
signal
|
|
2544
|
+
);
|
|
2557
2545
|
this.actorClientLocationResolver?.invalidateActorRoute(actorRef.actorId);
|
|
2558
2546
|
},
|
|
2559
2547
|
reportPostCommitError: (error) =>
|
|
2560
|
-
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException(
|
|
2548
|
+
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException(
|
|
2549
|
+
'post-commit actor binding',
|
|
2550
|
+
error
|
|
2551
|
+
),
|
|
2561
2552
|
reportBoundSessionSendError: (error) =>
|
|
2562
|
-
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException(
|
|
2553
|
+
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException(
|
|
2554
|
+
'bound session one-way submit',
|
|
2555
|
+
error
|
|
2556
|
+
),
|
|
2563
2557
|
actorHandoff: this.actorHandoff,
|
|
2564
2558
|
actorTransferRuntime: this.actorTransferRuntime,
|
|
2565
2559
|
actorJoinRelocation: this.serviceRelocation,
|
|
@@ -2592,7 +2586,7 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2592
2586
|
spotManager: () => this.spotManager,
|
|
2593
2587
|
oneWayFailureSink: (error) =>
|
|
2594
2588
|
this.runtimeOrPreStartErrorSink.reportRuntimeTaskException('channel one-way submit', error)
|
|
2595
|
-
|
|
2589
|
+
}).create();
|
|
2596
2590
|
}
|
|
2597
2591
|
|
|
2598
2592
|
private createSpotNodeRuntimeOptions(
|
|
@@ -2648,10 +2642,20 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2648
2642
|
});
|
|
2649
2643
|
},
|
|
2650
2644
|
meshRecordDispatcher: (meshName: string, owner: ReadyRecord, record: ReceiveRecord) =>
|
|
2651
|
-
this.dispatchMeshRecord(
|
|
2645
|
+
this.dispatchMeshRecord(
|
|
2646
|
+
meshName,
|
|
2647
|
+
owner,
|
|
2648
|
+
record,
|
|
2649
|
+
this.executionState?.abortController.signal
|
|
2650
|
+
),
|
|
2652
2651
|
instanceActivationConcurrencyProvider: (meshName: string) => {
|
|
2653
|
-
return
|
|
2654
|
-
|
|
2652
|
+
return (
|
|
2653
|
+
this.spotManager?.instanceActivationConcurrency(meshName) ?? {
|
|
2654
|
+
active: 0,
|
|
2655
|
+
limit:
|
|
2656
|
+
this.options.registration.spotNodes.get(meshName)?.activationConcurrencyLimit ?? 128
|
|
2657
|
+
}
|
|
2658
|
+
);
|
|
2655
2659
|
}
|
|
2656
2660
|
};
|
|
2657
2661
|
}
|
|
@@ -2664,7 +2668,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2664
2668
|
): Promise<void> {
|
|
2665
2669
|
if (record.operationKind === OperationKind.ActorJoin) {
|
|
2666
2670
|
if (this.spotManager === undefined) {
|
|
2667
|
-
throw new ZLinkConfigurationException(
|
|
2671
|
+
throw new ZLinkConfigurationException(
|
|
2672
|
+
'MeshNode Actor join dispatch requires the Spot manager.'
|
|
2673
|
+
);
|
|
2668
2674
|
}
|
|
2669
2675
|
return this.spotManager.dispatchMeshActorJoin(meshName, owner, record);
|
|
2670
2676
|
}
|
|
@@ -2679,12 +2685,12 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2679
2685
|
kind: ZLinkFrameworkInternalErrorKind,
|
|
2680
2686
|
message: string
|
|
2681
2687
|
): void => {
|
|
2682
|
-
const terminal =
|
|
2683
|
-
|
|
2684
|
-
|
|
2688
|
+
const terminal =
|
|
2689
|
+
kind === ZLinkFrameworkInternalErrorKind.ActorGenerationStale
|
|
2690
|
+
? { terminalResult: RequestResult.InvalidState, failureCode: 0 }
|
|
2691
|
+
: internalFrameworkWireReply(createInternalFrameworkException(kind, message));
|
|
2685
2692
|
if (
|
|
2686
|
-
record.replyFailure?.(terminal.terminalResult, terminal.failureCode)
|
|
2687
|
-
!== SubmitResult.Ok
|
|
2693
|
+
record.replyFailure?.(terminal.terminalResult, terminal.failureCode) !== SubmitResult.Ok
|
|
2688
2694
|
) {
|
|
2689
2695
|
throw new ZLinkConfigurationException(
|
|
2690
2696
|
`MeshNode Actor binding target '${binding.actor.actorId}' failure acknowledgement failed.`
|
|
@@ -2701,10 +2707,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2701
2707
|
const state = this.actorManager?.getState(binding.actor.actorId);
|
|
2702
2708
|
const nativeActorRef = state?.nativeActorRef;
|
|
2703
2709
|
if (
|
|
2704
|
-
state === undefined
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2710
|
+
state === undefined ||
|
|
2711
|
+
nativeActorRef === undefined ||
|
|
2712
|
+
nativeActorRef.actorId !== binding.actor.actorId ||
|
|
2713
|
+
!routingIdsEqual(nativeActorRef.nodeRid, binding.actor.nodeRid)
|
|
2708
2714
|
) {
|
|
2709
2715
|
replyBindingFailure(
|
|
2710
2716
|
ZLinkFrameworkInternalErrorKind.ActorLocationStale,
|
|
@@ -2719,18 +2725,17 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2719
2725
|
);
|
|
2720
2726
|
return;
|
|
2721
2727
|
}
|
|
2722
|
-
const node =
|
|
2723
|
-
? this.spotNodeRuntime?.meshNode(meshName)
|
|
2724
|
-
: undefined;
|
|
2728
|
+
const node =
|
|
2729
|
+
state.meshName === meshName ? this.spotNodeRuntime?.meshNode(meshName) : undefined;
|
|
2725
2730
|
const localStatus = node?.status();
|
|
2726
2731
|
// ownsLocation tracks local cleanup responsibility, not Actor authority.
|
|
2727
2732
|
// A relocation target can exact-read committed authority without owning that cleanup.
|
|
2728
2733
|
if (
|
|
2729
|
-
localStatus === undefined
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
+
localStatus === undefined ||
|
|
2735
|
+
!routingIdsEqual(localStatus.routingId, binding.actor.nodeRid) ||
|
|
2736
|
+
localStatus.lifecycleGeneration !== binding.actorNodeGeneration ||
|
|
2737
|
+
state.locationGeneration !== binding.authorityOwnerGeneration ||
|
|
2738
|
+
state.isMoving
|
|
2734
2739
|
) {
|
|
2735
2740
|
replyBindingFailure(
|
|
2736
2741
|
ZLinkFrameworkInternalErrorKind.ActorLocationStale,
|
|
@@ -2738,10 +2743,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2738
2743
|
);
|
|
2739
2744
|
return;
|
|
2740
2745
|
}
|
|
2741
|
-
const sessionOwnerIsLocal =
|
|
2742
|
-
localStatus.routingId,
|
|
2743
|
-
binding.
|
|
2744
|
-
) && localStatus.lifecycleGeneration === binding.sessionOwnerNodeGeneration;
|
|
2746
|
+
const sessionOwnerIsLocal =
|
|
2747
|
+
routingIdsEqual(localStatus.routingId, binding.sessionNodeRid) &&
|
|
2748
|
+
localStatus.lifecycleGeneration === binding.sessionOwnerNodeGeneration;
|
|
2745
2749
|
if (binding.transition === 'tombstone') {
|
|
2746
2750
|
const actorRef: ActorRef = {
|
|
2747
2751
|
actorId: binding.actor.actorId,
|
|
@@ -2794,17 +2798,22 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2794
2798
|
switch (record.kind) {
|
|
2795
2799
|
case ReceiveKind.TransferControl:
|
|
2796
2800
|
if (record.kindData?.kind !== 'transferControl') {
|
|
2797
|
-
throw new ZLinkConfigurationException(
|
|
2801
|
+
throw new ZLinkConfigurationException(
|
|
2802
|
+
'MeshNode transfer control record has no typed control payload.'
|
|
2803
|
+
);
|
|
2798
2804
|
}
|
|
2799
2805
|
return this.actorTransferAuthorityRuntime.handle(meshName, record.kindData, signal);
|
|
2800
2806
|
case ReceiveKind.ChannelSend:
|
|
2801
2807
|
case ReceiveKind.ChannelRequest: {
|
|
2802
2808
|
const channelRuntime = this.channelRuntime;
|
|
2803
2809
|
if (channelRuntime === undefined) {
|
|
2804
|
-
throw new ZLinkConfigurationException(
|
|
2810
|
+
throw new ZLinkConfigurationException(
|
|
2811
|
+
'MeshNode channel dispatch requires the channel runtime.'
|
|
2812
|
+
);
|
|
2805
2813
|
}
|
|
2806
2814
|
return this.admission.run(meshName, 'RouteMesh channel dispatch', () =>
|
|
2807
|
-
channelRuntime.dispatchMeshChannel(meshName, record, signal)
|
|
2815
|
+
channelRuntime.dispatchMeshChannel(meshName, record, signal)
|
|
2816
|
+
);
|
|
2808
2817
|
}
|
|
2809
2818
|
case ReceiveKind.NodeSend:
|
|
2810
2819
|
case ReceiveKind.NodeRequest: {
|
|
@@ -2816,11 +2825,11 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2816
2825
|
const terminal = decodeRemoteActorSourceLeaveTerminal(record.parts[0]!.data());
|
|
2817
2826
|
if (terminal !== undefined) {
|
|
2818
2827
|
if (
|
|
2819
|
-
await this.spotManager?.completeFormalSourceLeaveTerminal(
|
|
2828
|
+
(await this.spotManager?.completeFormalSourceLeaveTerminal(
|
|
2820
2829
|
terminal.actorId,
|
|
2821
2830
|
terminal.transferId,
|
|
2822
2831
|
terminal.succeeded
|
|
2823
|
-
) !== true
|
|
2832
|
+
)) !== true
|
|
2824
2833
|
) {
|
|
2825
2834
|
throw new ZLinkConfigurationException(
|
|
2826
2835
|
`Actor '${terminal.actorId}' has no matching formal transfer terminal gate.`
|
|
@@ -2836,7 +2845,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2836
2845
|
}
|
|
2837
2846
|
const channelRuntime = this.channelRuntime;
|
|
2838
2847
|
if (channelRuntime === undefined) {
|
|
2839
|
-
throw new ZLinkConfigurationException(
|
|
2848
|
+
throw new ZLinkConfigurationException(
|
|
2849
|
+
'MeshNode node-direct dispatch requires the channel runtime.'
|
|
2850
|
+
);
|
|
2840
2851
|
}
|
|
2841
2852
|
return await channelRuntime.dispatchMeshRoute(meshName, record, signal);
|
|
2842
2853
|
});
|
|
@@ -2845,7 +2856,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2845
2856
|
case ReceiveKind.SpotRequest:
|
|
2846
2857
|
case ReceiveKind.SpotMulticast:
|
|
2847
2858
|
return this.admission.run(meshName, 'RouteMesh Spot dispatch', () =>
|
|
2848
|
-
this.dispatchMeshSpotRecord(meshName, owner, record)
|
|
2859
|
+
this.dispatchMeshSpotRecord(meshName, owner, record)
|
|
2860
|
+
);
|
|
2849
2861
|
case ReceiveKind.InstanceSpotActivation:
|
|
2850
2862
|
if (this.spotManager === undefined) {
|
|
2851
2863
|
throw new ZLinkConfigurationException(
|
|
@@ -2853,19 +2865,25 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2853
2865
|
);
|
|
2854
2866
|
}
|
|
2855
2867
|
return this.admission.run(meshName, 'RouteMesh Instance Spot dispatch', () =>
|
|
2856
|
-
this.spotManager!.dispatchMeshInstance(meshName, owner, record)
|
|
2868
|
+
this.spotManager!.dispatchMeshInstance(meshName, owner, record)
|
|
2869
|
+
);
|
|
2857
2870
|
case ReceiveKind.SpotControl:
|
|
2858
2871
|
if (this.spotManager === undefined) {
|
|
2859
|
-
throw new ZLinkConfigurationException(
|
|
2872
|
+
throw new ZLinkConfigurationException(
|
|
2873
|
+
'MeshNode Spot control dispatch requires the Spot manager.'
|
|
2874
|
+
);
|
|
2860
2875
|
}
|
|
2861
2876
|
return this.spotManager.dispatchMeshSpotControl(meshName, owner, record);
|
|
2862
2877
|
case ReceiveKind.ActorSend:
|
|
2863
2878
|
case ReceiveKind.ActorRequest:
|
|
2864
2879
|
if (this.spotManager === undefined) {
|
|
2865
|
-
throw new ZLinkConfigurationException(
|
|
2880
|
+
throw new ZLinkConfigurationException(
|
|
2881
|
+
'MeshNode Actor dispatch requires the Spot manager.'
|
|
2882
|
+
);
|
|
2866
2883
|
}
|
|
2867
2884
|
return this.admission.run(meshName, 'RouteMesh Actor dispatch', () =>
|
|
2868
|
-
this.spotManager!.dispatchMeshActor(meshName, owner, record)
|
|
2885
|
+
this.spotManager!.dispatchMeshActor(meshName, owner, record)
|
|
2886
|
+
);
|
|
2869
2887
|
case ReceiveKind.SendReady:
|
|
2870
2888
|
return Promise.resolve();
|
|
2871
2889
|
default:
|
|
@@ -2892,11 +2910,13 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2892
2910
|
const ownedParts: RuntimeMessage[] = [];
|
|
2893
2911
|
try {
|
|
2894
2912
|
for (const part of parts) {
|
|
2895
|
-
ownedParts.push(
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2913
|
+
ownedParts.push(
|
|
2914
|
+
RuntimeMessage.from(
|
|
2915
|
+
typeof (part as { data?: unknown }).data === 'function'
|
|
2916
|
+
? (part as { data(): Buffer }).data()
|
|
2917
|
+
: part
|
|
2918
|
+
)
|
|
2919
|
+
);
|
|
2900
2920
|
}
|
|
2901
2921
|
} catch (error) {
|
|
2902
2922
|
for (const part of ownedParts) part.close();
|
|
@@ -2906,12 +2926,11 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2906
2926
|
try {
|
|
2907
2927
|
state.taskRunner.runDetached('mesh-node-local-route-dispatch', async () => {
|
|
2908
2928
|
try {
|
|
2909
|
-
const permit = await this.applicationJobQueue.acquire(
|
|
2910
|
-
state.abortController.signal
|
|
2911
|
-
);
|
|
2929
|
+
const permit = await this.applicationJobQueue.acquire(state.abortController.signal);
|
|
2912
2930
|
permit.markApplicationQueued();
|
|
2913
2931
|
await runWithApplicationJobPermit(permit, () =>
|
|
2914
|
-
channelRuntime.dispatchLocalMeshRoute(meshName, sourceNodeRid, ownedParts)
|
|
2932
|
+
channelRuntime.dispatchLocalMeshRoute(meshName, sourceNodeRid, ownedParts)
|
|
2933
|
+
);
|
|
2915
2934
|
} finally {
|
|
2916
2935
|
for (const part of ownedParts) part.close();
|
|
2917
2936
|
claim.close();
|
|
@@ -2932,10 +2951,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2932
2951
|
): Promise<void> {
|
|
2933
2952
|
const envelope = decodeChannelEnvelope(record.parts, undefined, this.flowCreationEnabled());
|
|
2934
2953
|
if (envelope.packetName === ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET) {
|
|
2935
|
-
const payload = decodeChannelPayload(
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
);
|
|
2954
|
+
const payload = decodeChannelPayload(envelope, {
|
|
2955
|
+
serializers: this.options.registration.messageSerializers
|
|
2956
|
+
});
|
|
2939
2957
|
const context = {
|
|
2940
2958
|
meshName,
|
|
2941
2959
|
packetName: envelope.packetName,
|
|
@@ -2945,8 +2963,10 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2945
2963
|
correlationId: envelope.header.correlationId ?? undefined
|
|
2946
2964
|
};
|
|
2947
2965
|
try {
|
|
2948
|
-
const response = await this.boundSessionRelay.actorPackets
|
|
2949
|
-
|
|
2966
|
+
const response = await this.boundSessionRelay.actorPackets.receiveRemoteActorPacketRelay(
|
|
2967
|
+
payload,
|
|
2968
|
+
context
|
|
2969
|
+
);
|
|
2950
2970
|
if (record.kind === ReceiveKind.SpotRequest) {
|
|
2951
2971
|
record.reply(encodeChannelReplyParts(envelope.header, response));
|
|
2952
2972
|
}
|
|
@@ -2954,14 +2974,16 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2954
2974
|
if (record.kind !== ReceiveKind.SpotRequest) {
|
|
2955
2975
|
throw error;
|
|
2956
2976
|
}
|
|
2957
|
-
record.reply(
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2977
|
+
record.reply(
|
|
2978
|
+
encodeChannelErrorReplyParts(
|
|
2979
|
+
envelope.header,
|
|
2980
|
+
error instanceof Error ? error.message : String(error)
|
|
2981
|
+
)
|
|
2982
|
+
);
|
|
2961
2983
|
}
|
|
2962
2984
|
return;
|
|
2963
2985
|
}
|
|
2964
|
-
if (await this.spotNodeRuntime?.dispatchEntrySpotRecord(meshName, owner, record) === true) {
|
|
2986
|
+
if ((await this.spotNodeRuntime?.dispatchEntrySpotRecord(meshName, owner, record)) === true) {
|
|
2965
2987
|
return;
|
|
2966
2988
|
}
|
|
2967
2989
|
if (this.spotManager === undefined) {
|
|
@@ -2970,7 +2992,9 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2970
2992
|
await this.spotManager.dispatchMeshSpot(meshName, owner, record);
|
|
2971
2993
|
}
|
|
2972
2994
|
|
|
2973
|
-
private createDispatchErrorReporter(
|
|
2995
|
+
private createDispatchErrorReporter(
|
|
2996
|
+
errorSink: ZLinkDispatchErrorSink
|
|
2997
|
+
): ZLinkDispatchErrorReporter {
|
|
2974
2998
|
const existing = this.dispatchErrorReporters.get(errorSink);
|
|
2975
2999
|
if (existing !== undefined) {
|
|
2976
3000
|
return existing;
|
|
@@ -2995,7 +3019,8 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
2995
3019
|
return;
|
|
2996
3020
|
}
|
|
2997
3021
|
void callback().catch((error) =>
|
|
2998
|
-
this.preStartErrorSink.reportRuntimeTaskException(taskName, error)
|
|
3022
|
+
this.preStartErrorSink.reportRuntimeTaskException(taskName, error)
|
|
3023
|
+
);
|
|
2999
3024
|
}
|
|
3000
3025
|
};
|
|
3001
3026
|
}
|
|
@@ -3010,17 +3035,19 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
3010
3035
|
}
|
|
3011
3036
|
|
|
3012
3037
|
private flowCreationEnabled(): boolean {
|
|
3013
|
-
const mode =
|
|
3014
|
-
|
|
3015
|
-
|
|
3038
|
+
const mode =
|
|
3039
|
+
this.executionState === undefined
|
|
3040
|
+
? (this.options.registration.dispatch?.diagnostics.messageFlow ?? 'errors')
|
|
3041
|
+
: this.messageFlowModeCell.mode;
|
|
3016
3042
|
return mode !== 'off';
|
|
3017
3043
|
}
|
|
3018
3044
|
|
|
3019
3045
|
private runLifecycle<T>(operation: () => T): T {
|
|
3020
3046
|
const current = currentOrCreateFlow('Lifecycle', false);
|
|
3021
|
-
const flow =
|
|
3022
|
-
|
|
3023
|
-
|
|
3047
|
+
const flow =
|
|
3048
|
+
current?.flowOrigin === 'Lifecycle'
|
|
3049
|
+
? current
|
|
3050
|
+
: createInboundFlow(undefined, 'Lifecycle', this.flowCreationEnabled());
|
|
3024
3051
|
return runWithFlow(flow, operation);
|
|
3025
3052
|
}
|
|
3026
3053
|
|
|
@@ -3047,65 +3074,69 @@ export class ZLinkFrameworkRuntimeHost implements
|
|
|
3047
3074
|
(spotId) => this.spotManager?.resolveLocalSpotRoute(spotId)
|
|
3048
3075
|
);
|
|
3049
3076
|
const authority = this.locationOwner.currentStores?.locationStore;
|
|
3050
|
-
const resolver =
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3077
|
+
const resolver =
|
|
3078
|
+
authority === undefined
|
|
3079
|
+
? legacy
|
|
3080
|
+
: new ZLinkAuthoritySpotRouteResolver(
|
|
3081
|
+
authority,
|
|
3082
|
+
this.meshRouters.spotRouterChannelIdByMesh(),
|
|
3083
|
+
legacy,
|
|
3084
|
+
this.locationOwner.currentLeaseTracker,
|
|
3085
|
+
this.options.registration.locations.options.routeCacheMaxAgeMs,
|
|
3086
|
+
undefined,
|
|
3087
|
+
async (meshName, nodeRid, expectedLifecycleGeneration, signal) => {
|
|
3088
|
+
const descriptor = (
|
|
3089
|
+
await authority.listMeshNodes(meshName, undefined, signal)
|
|
3090
|
+
).items.find(
|
|
3091
|
+
(candidate) =>
|
|
3092
|
+
routingIdsEqual(candidate.rid, nodeRid) &&
|
|
3093
|
+
candidate.lifecycleGeneration === expectedLifecycleGeneration
|
|
3094
|
+
);
|
|
3095
|
+
return descriptor?.state;
|
|
3096
|
+
}
|
|
3097
|
+
);
|
|
3071
3098
|
this.cachedLocationSpotRouteResolver = resolver;
|
|
3072
3099
|
this.locationOwner.setSpotRouteInvalidator(
|
|
3073
|
-
resolver === undefined ? undefined : spotId => resolver.invalidate?.(spotId)
|
|
3100
|
+
resolver === undefined ? undefined : (spotId) => resolver.invalidate?.(spotId)
|
|
3074
3101
|
);
|
|
3075
3102
|
return resolver;
|
|
3076
3103
|
}
|
|
3077
3104
|
|
|
3078
3105
|
private createActorLocationResolver(): ZLinkStoreLocationResolvers | undefined {
|
|
3079
|
-
return this.locationOwner.createActorLocationResolver(
|
|
3080
|
-
this.meshRouters.spotLocationMeshNames()
|
|
3081
|
-
);
|
|
3106
|
+
return this.locationOwner.createActorLocationResolver(this.meshRouters.spotLocationMeshNames());
|
|
3082
3107
|
}
|
|
3083
|
-
|
|
3084
3108
|
}
|
|
3085
3109
|
|
|
3086
|
-
export function hasUnsupportedManualTopology(
|
|
3087
|
-
|
|
3088
|
-
)
|
|
3089
|
-
|
|
3090
|
-
|
|
3110
|
+
export function hasUnsupportedManualTopology(registration: ZLinkFrameworkRegistration): boolean {
|
|
3111
|
+
if (
|
|
3112
|
+
[...registration.routeChannelOptions.values()].some(
|
|
3113
|
+
(route) => (route.manualConnections?.length ?? 0) > 0
|
|
3114
|
+
)
|
|
3115
|
+
) {
|
|
3091
3116
|
return true;
|
|
3092
3117
|
}
|
|
3093
3118
|
|
|
3094
3119
|
for (const node of registration.spotNodes.values()) {
|
|
3095
|
-
if (
|
|
3096
|
-
|
|
3120
|
+
if (
|
|
3121
|
+
(node.router?.manualConnections?.length ?? 0) > 0 ||
|
|
3122
|
+
(node.router?.manualPeerConnections?.length ?? 0) > 0
|
|
3123
|
+
) {
|
|
3097
3124
|
return true;
|
|
3098
3125
|
}
|
|
3099
3126
|
}
|
|
3100
3127
|
|
|
3101
3128
|
for (const channel of registration.channels.values()) {
|
|
3102
|
-
if (
|
|
3103
|
-
|
|
3129
|
+
if (
|
|
3130
|
+
(channel.client?.manualConnections?.length ?? 0) > 0 ||
|
|
3131
|
+
(channel.subscriber?.manualConnections?.length ?? 0) > 0
|
|
3132
|
+
) {
|
|
3104
3133
|
return true;
|
|
3105
3134
|
}
|
|
3106
|
-
if (
|
|
3107
|
-
&&
|
|
3108
|
-
|
|
3135
|
+
if (
|
|
3136
|
+
channel.publisher !== undefined &&
|
|
3137
|
+
!registration.locations.useInMemoryStores &&
|
|
3138
|
+
registration.locations.storeInstance === undefined
|
|
3139
|
+
) {
|
|
3109
3140
|
return true;
|
|
3110
3141
|
}
|
|
3111
3142
|
}
|
|
@@ -3114,8 +3145,9 @@ export function hasUnsupportedManualTopology(
|
|
|
3114
3145
|
}
|
|
3115
3146
|
|
|
3116
3147
|
function hasConfiguredLocationStore(registration: ZLinkFrameworkRegistration): boolean {
|
|
3117
|
-
return
|
|
3118
|
-
|| registration.locations.storeInstance !== undefined
|
|
3148
|
+
return (
|
|
3149
|
+
registration.locations.useInMemoryStores || registration.locations.storeInstance !== undefined
|
|
3150
|
+
);
|
|
3119
3151
|
}
|
|
3120
3152
|
|
|
3121
3153
|
export function hasExactPeerReadiness(
|
|
@@ -3132,34 +3164,38 @@ export function hasExactPeerReadiness(
|
|
|
3132
3164
|
readonly state: number;
|
|
3133
3165
|
}[]
|
|
3134
3166
|
): boolean {
|
|
3135
|
-
const replacementDescriptors = descriptors.filter(
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3167
|
+
const replacementDescriptors = descriptors.filter(
|
|
3168
|
+
(descriptor) =>
|
|
3169
|
+
!(
|
|
3170
|
+
String(descriptor.rid) === String(local.routingId) &&
|
|
3171
|
+
descriptor.lifecycleGeneration === local.lifecycleGeneration
|
|
3172
|
+
) &&
|
|
3173
|
+
descriptor.state === ZLinkFrameworkRuntimeState.Serving &&
|
|
3174
|
+
local.applicationVersion !== undefined &&
|
|
3175
|
+
descriptor.applicationVersion === local.applicationVersion &&
|
|
3176
|
+
descriptor.objectRole === ZLinkObjectRole.Server &&
|
|
3177
|
+
(local.maintenanceWave === undefined || descriptor.maintenanceWave !== local.maintenanceWave)
|
|
3178
|
+
);
|
|
3179
|
+
return (
|
|
3180
|
+
replacementDescriptors.length > 0 &&
|
|
3181
|
+
replacementDescriptors.some((descriptor) =>
|
|
3182
|
+
peers.some(
|
|
3183
|
+
(peer) =>
|
|
3184
|
+
peer.routingId !== null &&
|
|
3185
|
+
String(peer.routingId) === String(descriptor.rid) &&
|
|
3186
|
+
peer.lifecycleGeneration === descriptor.lifecycleGeneration &&
|
|
3187
|
+
peer.state === 3
|
|
3188
|
+
)
|
|
3189
|
+
)
|
|
3190
|
+
);
|
|
3150
3191
|
}
|
|
3151
3192
|
|
|
3152
3193
|
export {
|
|
3153
3194
|
ZLinkActorTransferAuthorityRuntime,
|
|
3154
3195
|
transferIdString
|
|
3155
3196
|
} from './actor-transfer-authority-runtime';
|
|
3156
|
-
export {
|
|
3157
|
-
|
|
3158
|
-
ZLinkRouteMeshRuntimeCoordinator
|
|
3159
|
-
} from './route-mesh-runtime';
|
|
3160
|
-
export {
|
|
3161
|
-
ZLinkRelocationStateIncompatibleError
|
|
3162
|
-
} from './service-relocation-host-runtime';
|
|
3197
|
+
export { ZLinkRetiringRollbackError, ZLinkRouteMeshRuntimeCoordinator } from './route-mesh-runtime';
|
|
3198
|
+
export { ZLinkRelocationStateIncompatibleError } from './service-relocation-host-runtime';
|
|
3163
3199
|
export {
|
|
3164
3200
|
ZLinkHostSpotAddressTransport,
|
|
3165
3201
|
type ZLinkHostSpotAddressTransportOptions
|
|
@@ -3171,7 +3207,9 @@ export {
|
|
|
3171
3207
|
type ZLinkUserSpotCreationResult
|
|
3172
3208
|
} from './user-spot-creation-coordinator';
|
|
3173
3209
|
|
|
3174
|
-
async function waitForForcedSessionNotification(
|
|
3210
|
+
async function waitForForcedSessionNotification(
|
|
3211
|
+
operation: Promise<void> | undefined
|
|
3212
|
+
): Promise<void> {
|
|
3175
3213
|
if (operation === undefined) return;
|
|
3176
3214
|
let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
|
|
3177
3215
|
const timeout = new Promise<void>((resolve) => {
|
|
@@ -3200,7 +3238,7 @@ async function awaitWithDrainSignal(
|
|
|
3200
3238
|
signal.removeEventListener('abort', onAbort);
|
|
3201
3239
|
resolve();
|
|
3202
3240
|
},
|
|
3203
|
-
error => {
|
|
3241
|
+
(error) => {
|
|
3204
3242
|
signal.removeEventListener('abort', onAbort);
|
|
3205
3243
|
reject(error);
|
|
3206
3244
|
}
|
|
@@ -3217,11 +3255,13 @@ class ZLinkDrainingStatePublishError extends Error {
|
|
|
3217
3255
|
|
|
3218
3256
|
function resolveBackendAdapterFactory(internalOptions: unknown): ZLinkBackendAdapterFactory {
|
|
3219
3257
|
if (
|
|
3220
|
-
typeof internalOptions === 'object'
|
|
3221
|
-
|
|
3222
|
-
|
|
3258
|
+
typeof internalOptions === 'object' &&
|
|
3259
|
+
internalOptions !== null &&
|
|
3260
|
+
'backendAdapterFactory' in internalOptions
|
|
3223
3261
|
) {
|
|
3224
|
-
const factory = (
|
|
3262
|
+
const factory = (
|
|
3263
|
+
internalOptions as { readonly backendAdapterFactory?: ZLinkBackendAdapterFactory }
|
|
3264
|
+
).backendAdapterFactory;
|
|
3225
3265
|
if (factory !== undefined) {
|
|
3226
3266
|
return factory;
|
|
3227
3267
|
}
|
|
@@ -3229,7 +3269,9 @@ function resolveBackendAdapterFactory(internalOptions: unknown): ZLinkBackendAda
|
|
|
3229
3269
|
return new ZLinkNodeBackendAdapterFactory();
|
|
3230
3270
|
}
|
|
3231
3271
|
|
|
3232
|
-
function resolveStreamPayloadCodec(
|
|
3272
|
+
function resolveStreamPayloadCodec(
|
|
3273
|
+
registration: ZLinkFrameworkRegistration
|
|
3274
|
+
): ZLinkStreamPayloadCodec | undefined {
|
|
3233
3275
|
const codec = registration.codecs.streamCodecs.values().next().value;
|
|
3234
3276
|
if (isStreamPayloadCodec(codec)) {
|
|
3235
3277
|
return codec;
|
|
@@ -3239,13 +3281,20 @@ function resolveStreamPayloadCodec(registration: ZLinkFrameworkRegistration): ZL
|
|
|
3239
3281
|
|
|
3240
3282
|
function runtimeStateMetricName(state: ZLinkFrameworkRuntimeState): string {
|
|
3241
3283
|
switch (state) {
|
|
3242
|
-
case ZLinkFrameworkRuntimeState.Preparing:
|
|
3243
|
-
|
|
3244
|
-
case ZLinkFrameworkRuntimeState.
|
|
3245
|
-
|
|
3246
|
-
case ZLinkFrameworkRuntimeState.
|
|
3247
|
-
|
|
3248
|
-
case ZLinkFrameworkRuntimeState.
|
|
3284
|
+
case ZLinkFrameworkRuntimeState.Preparing:
|
|
3285
|
+
return 'preparing';
|
|
3286
|
+
case ZLinkFrameworkRuntimeState.Serving:
|
|
3287
|
+
return 'serving';
|
|
3288
|
+
case ZLinkFrameworkRuntimeState.Relocating:
|
|
3289
|
+
return 'relocating';
|
|
3290
|
+
case ZLinkFrameworkRuntimeState.Relocated:
|
|
3291
|
+
return 'relocated';
|
|
3292
|
+
case ZLinkFrameworkRuntimeState.Draining:
|
|
3293
|
+
return 'draining';
|
|
3294
|
+
case ZLinkFrameworkRuntimeState.Stopped:
|
|
3295
|
+
return 'stopped';
|
|
3296
|
+
case ZLinkFrameworkRuntimeState.Error:
|
|
3297
|
+
return 'error';
|
|
3249
3298
|
}
|
|
3250
3299
|
}
|
|
3251
3300
|
|
|
@@ -3257,32 +3306,48 @@ function relocationModeMetricName(mode: ZLinkFrameworkRelocationMode): string {
|
|
|
3257
3306
|
|
|
3258
3307
|
function relocationReasonMetricName(reason: ZLinkFrameworkRelocationReason): string {
|
|
3259
3308
|
switch (reason) {
|
|
3260
|
-
case ZLinkFrameworkRelocationReason.None:
|
|
3261
|
-
|
|
3262
|
-
case ZLinkFrameworkRelocationReason.
|
|
3263
|
-
|
|
3264
|
-
case ZLinkFrameworkRelocationReason.
|
|
3265
|
-
|
|
3266
|
-
case ZLinkFrameworkRelocationReason.
|
|
3267
|
-
|
|
3268
|
-
case ZLinkFrameworkRelocationReason.
|
|
3269
|
-
|
|
3270
|
-
case ZLinkFrameworkRelocationReason.
|
|
3309
|
+
case ZLinkFrameworkRelocationReason.None:
|
|
3310
|
+
return 'none';
|
|
3311
|
+
case ZLinkFrameworkRelocationReason.TargetUnavailable:
|
|
3312
|
+
return 'target_unavailable';
|
|
3313
|
+
case ZLinkFrameworkRelocationReason.StoreUnavailable:
|
|
3314
|
+
return 'store_unavailable';
|
|
3315
|
+
case ZLinkFrameworkRelocationReason.RelocationDisabled:
|
|
3316
|
+
return 'relocation_disabled';
|
|
3317
|
+
case ZLinkFrameworkRelocationReason.StateIncompatible:
|
|
3318
|
+
return 'state_incompatible';
|
|
3319
|
+
case ZLinkFrameworkRelocationReason.DeadlineExceeded:
|
|
3320
|
+
return 'deadline_exceeded';
|
|
3321
|
+
case ZLinkFrameworkRelocationReason.RelocationFailed:
|
|
3322
|
+
return 'relocation_failed';
|
|
3323
|
+
case ZLinkFrameworkRelocationReason.RuntimeNotReady:
|
|
3324
|
+
return 'runtime_not_ready';
|
|
3325
|
+
case ZLinkFrameworkRelocationReason.ManualTopologyUnsupported:
|
|
3326
|
+
return 'manual_topology_unsupported';
|
|
3327
|
+
case ZLinkFrameworkRelocationReason.ShutdownRequested:
|
|
3328
|
+
return 'shutdown_requested';
|
|
3329
|
+
case ZLinkFrameworkRelocationReason.OperationInProgress:
|
|
3330
|
+
return 'operation_in_progress';
|
|
3271
3331
|
}
|
|
3272
3332
|
}
|
|
3273
3333
|
|
|
3274
3334
|
function terminationReasonMetricName(reason: ZLinkFrameworkTerminationReason): string {
|
|
3275
3335
|
switch (reason) {
|
|
3276
|
-
case ZLinkFrameworkTerminationReason.None:
|
|
3277
|
-
|
|
3278
|
-
case ZLinkFrameworkTerminationReason.
|
|
3336
|
+
case ZLinkFrameworkTerminationReason.None:
|
|
3337
|
+
return 'none';
|
|
3338
|
+
case ZLinkFrameworkTerminationReason.DeadlineExceeded:
|
|
3339
|
+
return 'deadline_exceeded';
|
|
3340
|
+
case ZLinkFrameworkTerminationReason.TeardownFailed:
|
|
3341
|
+
return 'teardown_failed';
|
|
3279
3342
|
}
|
|
3280
3343
|
}
|
|
3281
3344
|
|
|
3282
3345
|
function isStreamPayloadCodec(codec: unknown): codec is ZLinkStreamPayloadCodec {
|
|
3283
|
-
return
|
|
3284
|
-
|
|
3285
|
-
|
|
3346
|
+
return (
|
|
3347
|
+
typeof codec === 'object' &&
|
|
3348
|
+
codec !== null &&
|
|
3349
|
+
typeof (codec as { encode?: unknown }).encode === 'function'
|
|
3350
|
+
);
|
|
3286
3351
|
}
|
|
3287
3352
|
|
|
3288
3353
|
function selectLocationPlacementDescriptor(
|
|
@@ -3313,7 +3378,7 @@ async function selectReadyLocationPlacementDescriptor(
|
|
|
3313
3378
|
for (;;) {
|
|
3314
3379
|
const localStatus = node?.status();
|
|
3315
3380
|
const selected = selectLocationPlacementDescriptor(
|
|
3316
|
-
eligible.filter(descriptor => isPlacementTargetReady(node, localStatus, descriptor))
|
|
3381
|
+
eligible.filter((descriptor) => isPlacementTargetReady(node, localStatus, descriptor))
|
|
3317
3382
|
);
|
|
3318
3383
|
if (selected !== undefined) return selected;
|
|
3319
3384
|
try {
|
|
@@ -3330,9 +3395,11 @@ function isPlacementTargetReady(
|
|
|
3330
3395
|
descriptor: ZLinkMeshNodeDescriptor
|
|
3331
3396
|
): boolean {
|
|
3332
3397
|
if (node === undefined) return true;
|
|
3333
|
-
if (
|
|
3334
|
-
|
|
3335
|
-
|
|
3398
|
+
if (
|
|
3399
|
+
localStatus !== undefined &&
|
|
3400
|
+
String(localStatus.routingId) === String(descriptor.rid) &&
|
|
3401
|
+
localStatus.lifecycleGeneration === descriptor.lifecycleGeneration
|
|
3402
|
+
) {
|
|
3336
3403
|
return true;
|
|
3337
3404
|
}
|
|
3338
3405
|
return node.isPeerRouteReady?.(descriptor.rid, descriptor.lifecycleGeneration) ?? true;
|
|
@@ -3371,10 +3438,14 @@ function randomBigIntBelow(exclusiveUpperBound: bigint): bigint {
|
|
|
3371
3438
|
|
|
3372
3439
|
function relocationReason(reason: string): ZLinkFrameworkRelocationReason {
|
|
3373
3440
|
switch (reason) {
|
|
3374
|
-
case 'deadline_exceeded':
|
|
3375
|
-
|
|
3376
|
-
case '
|
|
3377
|
-
|
|
3441
|
+
case 'deadline_exceeded':
|
|
3442
|
+
return ZLinkFrameworkRelocationReason.DeadlineExceeded;
|
|
3443
|
+
case 'store_unavailable':
|
|
3444
|
+
return ZLinkFrameworkRelocationReason.StoreUnavailable;
|
|
3445
|
+
case 'target_unavailable':
|
|
3446
|
+
return ZLinkFrameworkRelocationReason.TargetUnavailable;
|
|
3447
|
+
default:
|
|
3448
|
+
return ZLinkFrameworkRelocationReason.RelocationFailed;
|
|
3378
3449
|
}
|
|
3379
3450
|
}
|
|
3380
3451
|
|
|
@@ -3385,7 +3456,7 @@ function rewriteAuthorityPayloadForOwner(
|
|
|
3385
3456
|
const applicationPayload = serviceRelocationAuthorityApplicationPayload(payload);
|
|
3386
3457
|
const rewritten = isActorAuthorityPayload(applicationPayload)
|
|
3387
3458
|
? rewriteActorAuthorityOwner(applicationPayload, owner)
|
|
3388
|
-
: rewriteServiceAuthorityOwner(applicationPayload, owner) ?? applicationPayload;
|
|
3459
|
+
: (rewriteServiceAuthorityOwner(applicationPayload, owner) ?? applicationPayload);
|
|
3389
3460
|
return replaceServiceRelocationAuthorityApplicationPayload(payload, rewritten);
|
|
3390
3461
|
}
|
|
3391
3462
|
|
|
@@ -3397,21 +3468,25 @@ function validateRelocationOptions(
|
|
|
3397
3468
|
throw new TypeError('Relocation mode is required.');
|
|
3398
3469
|
}
|
|
3399
3470
|
const mode = options.mode as number;
|
|
3400
|
-
if (
|
|
3401
|
-
|
|
3471
|
+
if (
|
|
3472
|
+
mode !== ZLinkFrameworkRelocationMode.PlannedMaintenance &&
|
|
3473
|
+
mode !== ZLinkFrameworkRelocationMode.RollingUpdate
|
|
3474
|
+
) {
|
|
3402
3475
|
throw new TypeError('Relocation mode is required.');
|
|
3403
3476
|
}
|
|
3404
3477
|
if (options.mode === ZLinkFrameworkRelocationMode.PlannedMaintenance) {
|
|
3405
3478
|
if (options.targetApplicationVersion !== undefined) {
|
|
3406
|
-
throw new TypeError(
|
|
3407
|
-
'PlannedMaintenance relocation cannot define targetApplicationVersion.');
|
|
3479
|
+
throw new TypeError('PlannedMaintenance relocation cannot define targetApplicationVersion.');
|
|
3408
3480
|
}
|
|
3409
3481
|
return sourceApplicationVersion;
|
|
3410
3482
|
}
|
|
3411
|
-
if (
|
|
3412
|
-
|
|
3483
|
+
if (
|
|
3484
|
+
typeof options.targetApplicationVersion !== 'bigint' ||
|
|
3485
|
+
options.targetApplicationVersion <= sourceApplicationVersion
|
|
3486
|
+
) {
|
|
3413
3487
|
throw new TypeError(
|
|
3414
|
-
'RollingUpdate relocation requires a targetApplicationVersion greater than the source version.'
|
|
3488
|
+
'RollingUpdate relocation requires a targetApplicationVersion greater than the source version.'
|
|
3489
|
+
);
|
|
3415
3490
|
}
|
|
3416
3491
|
return options.targetApplicationVersion;
|
|
3417
3492
|
}
|
|
@@ -3429,10 +3504,7 @@ function blockedRelocation(
|
|
|
3429
3504
|
};
|
|
3430
3505
|
}
|
|
3431
3506
|
|
|
3432
|
-
function waitForRuntimeOperation<T>(
|
|
3433
|
-
operation: Promise<T>,
|
|
3434
|
-
signal?: AbortSignal
|
|
3435
|
-
): Promise<T> {
|
|
3507
|
+
function waitForRuntimeOperation<T>(operation: Promise<T>, signal?: AbortSignal): Promise<T> {
|
|
3436
3508
|
if (signal === undefined) return operation;
|
|
3437
3509
|
signal.throwIfAborted();
|
|
3438
3510
|
return new Promise((resolve, reject) => {
|