@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
|
@@ -46,10 +46,7 @@ import { encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
|
|
|
46
46
|
import type { ZLinkLocationLifecycle } from '../locations';
|
|
47
47
|
import { wrapFrameworkPayloadMessage } from '../messaging/payload-codec';
|
|
48
48
|
import type { DefaultZLinkSpotManager } from '../spots';
|
|
49
|
-
import type {
|
|
50
|
-
ZLinkSpotRouteResolver,
|
|
51
|
-
ZLinkSpotRouteTarget
|
|
52
|
-
} from '../spots/spot-routing-internal';
|
|
49
|
+
import type { ZLinkSpotRouteResolver, ZLinkSpotRouteTarget } from '../spots/spot-routing-internal';
|
|
53
50
|
import type {
|
|
54
51
|
ZLinkActorHandoffPacket,
|
|
55
52
|
ZLinkActorHandoffResult,
|
|
@@ -103,17 +100,19 @@ export function committedActorOwnerFence(
|
|
|
103
100
|
targetActorRef: ActorRef,
|
|
104
101
|
authority: ZLinkCommittedActorAuthority
|
|
105
102
|
): ZLinkActorMessageFollowOwnerFence {
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
if (
|
|
104
|
+
targetActorRef.actorId !== actorId ||
|
|
105
|
+
targetActorRef.objectGeneration <= 0n ||
|
|
106
|
+
authority.objectGeneration !== targetActorRef.objectGeneration ||
|
|
107
|
+
authority.allocation.state !== 'active' ||
|
|
108
|
+
authority.allocation.objectKind !== 'actor' ||
|
|
109
|
+
authority.allocation.descriptor.meshName !== targetActorRef.meshName ||
|
|
110
|
+
!routingIdsEqual(authority.allocation.descriptor.rid, targetActorRef.nodeRid) ||
|
|
111
|
+
authority.ownerId.length === 0 ||
|
|
112
|
+
authority.ownerLeaseGeneration <= 0n ||
|
|
113
|
+
authority.allocation.descriptorLifecycleGeneration <= 0n ||
|
|
114
|
+
authority.authorityOwnerGeneration <= 0n
|
|
115
|
+
) {
|
|
117
116
|
throw new Error(
|
|
118
117
|
`Actor '${actorId}' handoff target does not match the committed authority snapshot.`
|
|
119
118
|
);
|
|
@@ -128,10 +127,7 @@ export function committedActorOwnerFence(
|
|
|
128
127
|
});
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
function requireSourceObjectGeneration(
|
|
132
|
-
actorId: string,
|
|
133
|
-
state: ZLinkActorRuntimeState
|
|
134
|
-
): bigint {
|
|
130
|
+
function requireSourceObjectGeneration(actorId: string, state: ZLinkActorRuntimeState): bigint {
|
|
135
131
|
const generation = state.nativeActorRef?.generation;
|
|
136
132
|
if (generation === undefined || generation <= 0n) {
|
|
137
133
|
throw new Error(`Actor '${actorId}' handoff requires a positive source ObjectGeneration.`);
|
|
@@ -144,7 +140,7 @@ function createHandoffReplayGate(): {
|
|
|
144
140
|
open(): void;
|
|
145
141
|
} {
|
|
146
142
|
let open!: () => void;
|
|
147
|
-
const start = new Promise<void>(resolve => {
|
|
143
|
+
const start = new Promise<void>((resolve) => {
|
|
148
144
|
open = resolve;
|
|
149
145
|
});
|
|
150
146
|
return { start, open };
|
|
@@ -199,11 +195,8 @@ export interface ZLinkActorTransferRuntimeOptions {
|
|
|
199
195
|
readonly spotRouteResolver?: () => ZLinkSpotRouteResolver | undefined;
|
|
200
196
|
readonly actorHandoff: ZLinkActorHandoffCoordinator;
|
|
201
197
|
readonly actorTransferRegistry: ZLinkActorTransferRegistry;
|
|
202
|
-
readonly authorityStore: () =>
|
|
203
|
-
ZLinkAuthorityStore
|
|
204
|
-
& ZLinkObjectCreationStore
|
|
205
|
-
& ZLinkOwnerLeaseStore
|
|
206
|
-
) | undefined;
|
|
198
|
+
readonly authorityStore: () =>
|
|
199
|
+
(ZLinkAuthorityStore & ZLinkObjectCreationStore & ZLinkOwnerLeaseStore) | undefined;
|
|
207
200
|
readonly currentOwner: () => ZLinkLocationOwnerToken | undefined;
|
|
208
201
|
readonly relocationStore: () => ZLinkRelocationStore | undefined;
|
|
209
202
|
/** Live admitted peers of a mesh; used to stop retries against a gone session owner. */
|
|
@@ -224,21 +217,26 @@ export interface ZLinkActorTransferRuntimeOptions {
|
|
|
224
217
|
|
|
225
218
|
export class ZLinkActorTransferRuntime {
|
|
226
219
|
private readonly sourceDepartureTasks = new Map<string, Promise<void>>();
|
|
227
|
-
private readonly coreSourceLeaves = new Map<
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
220
|
+
private readonly coreSourceLeaves = new Map<
|
|
221
|
+
string,
|
|
222
|
+
{
|
|
223
|
+
readonly promise: Promise<void>;
|
|
224
|
+
readonly resolve: () => void;
|
|
225
|
+
readonly reject: (error: unknown) => void;
|
|
226
|
+
readonly submitted: Promise<void>;
|
|
227
|
+
readonly resolveSubmitted: () => void;
|
|
228
|
+
readonly rejectSubmitted: (error: unknown) => void;
|
|
229
|
+
notifySubmitted?: () => Promise<void>;
|
|
230
|
+
}
|
|
231
|
+
>();
|
|
232
|
+
private readonly activeDeferredJoinTerminals = new Map<
|
|
233
|
+
string,
|
|
234
|
+
Promise<ZLinkDeferredJoinAcceptedRoot>
|
|
235
|
+
>();
|
|
236
|
+
private readonly deferredJoinTerminals = new BoundedReplayMap<
|
|
237
|
+
string,
|
|
238
|
+
ZLinkDeferredJoinAcceptedRoot
|
|
239
|
+
>(DEFERRED_JOIN_TERMINAL_CAPACITY);
|
|
242
240
|
|
|
243
241
|
constructor(private readonly options: ZLinkActorTransferRuntimeOptions) {}
|
|
244
242
|
|
|
@@ -276,14 +274,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
276
274
|
throw new Error(`Actor '${actorId}' same-node Join has no local Spot manager.`);
|
|
277
275
|
}
|
|
278
276
|
const admitted = this.options.actorHandoff.admitDeferredPrefix(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
actorId,
|
|
284
|
-
drain
|
|
285
|
-
),
|
|
286
|
-
this.options.prepareApplicationJob
|
|
277
|
+
actorId,
|
|
278
|
+
operationId,
|
|
279
|
+
(drain) => manager.admitRoutedActorPacketPrefix(target.spotId, actorId, drain),
|
|
280
|
+
this.options.prepareApplicationJob
|
|
287
281
|
);
|
|
288
282
|
void this.observeHandoffReplay(admitted.terminal);
|
|
289
283
|
}
|
|
@@ -293,11 +287,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
293
287
|
_state: ZLinkActorRuntimeState,
|
|
294
288
|
operationId: string
|
|
295
289
|
): Promise<void> {
|
|
296
|
-
const admitted = this.admitDeferredSourcePrefix(
|
|
297
|
-
actor,
|
|
298
|
-
_state,
|
|
299
|
-
operationId
|
|
300
|
-
);
|
|
290
|
+
const admitted = this.admitDeferredSourcePrefix(actor, _state, operationId);
|
|
301
291
|
void this.observeHandoffReplay(admitted.terminal);
|
|
302
292
|
}
|
|
303
293
|
|
|
@@ -377,7 +367,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
377
367
|
);
|
|
378
368
|
this.activeDeferredJoinTerminals.set(terminalKey, completion);
|
|
379
369
|
void completion.then(
|
|
380
|
-
completed => {
|
|
370
|
+
(completed) => {
|
|
381
371
|
this.deferredJoinTerminals.remember(terminalKey, completed);
|
|
382
372
|
if (this.activeDeferredJoinTerminals.get(terminalKey) === completion) {
|
|
383
373
|
this.activeDeferredJoinTerminals.delete(terminalKey);
|
|
@@ -398,15 +388,17 @@ export class ZLinkActorTransferRuntime {
|
|
|
398
388
|
actorRef: ActorRef,
|
|
399
389
|
submitMailbox: <T>(operation: () => Promise<T>) => Promise<T>
|
|
400
390
|
): Promise<ZLinkDeferredJoinAcceptedRoot> {
|
|
401
|
-
const targetActorRef = this.options
|
|
402
|
-
|
|
403
|
-
?.nativeActorRef;
|
|
404
|
-
const currentActorRef =
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
391
|
+
const targetActorRef = this.options
|
|
392
|
+
.actorManager()
|
|
393
|
+
?.getState(actor.context.actorId)?.nativeActorRef;
|
|
394
|
+
const currentActorRef =
|
|
395
|
+
targetActorRef === undefined
|
|
396
|
+
? actorRef
|
|
397
|
+
: toFrameworkActorRef(targetActorRef, actor.context.meshName);
|
|
398
|
+
let current =
|
|
399
|
+
root.cursor === 'prepared'
|
|
400
|
+
? await this.requireDeferredJoinJournal().markCommitted(root, currentActorRef)
|
|
401
|
+
: root;
|
|
410
402
|
if (current.cursor === 'delivered') return current;
|
|
411
403
|
let lastError: unknown;
|
|
412
404
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
@@ -421,13 +413,12 @@ export class ZLinkActorTransferRuntime {
|
|
|
421
413
|
} catch (error) {
|
|
422
414
|
lastError = error;
|
|
423
415
|
if (attempt < 2) {
|
|
424
|
-
await new Promise<void>(resolve => {
|
|
416
|
+
await new Promise<void>((resolve) => {
|
|
425
417
|
const timer = setTimeout(resolve, 10 << attempt);
|
|
426
418
|
timer.unref();
|
|
427
419
|
});
|
|
428
|
-
current =
|
|
429
|
-
currentActorRef.actorId
|
|
430
|
-
) ?? current;
|
|
420
|
+
current =
|
|
421
|
+
(await this.requireDeferredJoinJournal().recover(currentActorRef.actorId)) ?? current;
|
|
431
422
|
}
|
|
432
423
|
}
|
|
433
424
|
}
|
|
@@ -482,7 +473,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
482
473
|
state: ZLinkActorRuntimeState,
|
|
483
474
|
deferredOperationId?: string
|
|
484
475
|
): Promise<void> {
|
|
485
|
-
if (
|
|
476
|
+
if (
|
|
477
|
+
deferredOperationId !== undefined &&
|
|
478
|
+
this.options.actorHandoff.isProvisional(actor.context.actorId)
|
|
479
|
+
) {
|
|
486
480
|
this.promoteDeferredActorHandoff(actor, state, deferredOperationId);
|
|
487
481
|
}
|
|
488
482
|
state.beginMove();
|
|
@@ -508,11 +502,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
508
502
|
if (deferredOperationId === undefined) {
|
|
509
503
|
this.options.actorHandoff.cancel(actor.context.actorId);
|
|
510
504
|
} else {
|
|
511
|
-
const admitted = this.admitDeferredSourcePrefix(
|
|
512
|
-
actor,
|
|
513
|
-
state,
|
|
514
|
-
deferredOperationId
|
|
515
|
-
);
|
|
505
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state, deferredOperationId);
|
|
516
506
|
void this.observeHandoffReplay(admitted.terminal);
|
|
517
507
|
}
|
|
518
508
|
state.endMove();
|
|
@@ -564,10 +554,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
564
554
|
return { terminal: Promise.resolve() };
|
|
565
555
|
}
|
|
566
556
|
return this.options.actorHandoff.admitCanceledPrefix(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
557
|
+
actor.context.actorId,
|
|
558
|
+
queue,
|
|
559
|
+
this.options.prepareApplicationJob,
|
|
560
|
+
replayStart
|
|
571
561
|
);
|
|
572
562
|
}
|
|
573
563
|
|
|
@@ -615,11 +605,8 @@ export class ZLinkActorTransferRuntime {
|
|
|
615
605
|
if (sourceSpotId === undefined || manager === undefined) {
|
|
616
606
|
return undefined;
|
|
617
607
|
}
|
|
618
|
-
return drain =>
|
|
619
|
-
sourceSpotId,
|
|
620
|
-
actor.context.actorId,
|
|
621
|
-
drain
|
|
622
|
-
);
|
|
608
|
+
return (drain) =>
|
|
609
|
+
manager.admitRoutedActorPacketPrefix(sourceSpotId, actor.context.actorId, drain);
|
|
623
610
|
}
|
|
624
611
|
|
|
625
612
|
async prepareSource(
|
|
@@ -631,25 +618,21 @@ export class ZLinkActorTransferRuntime {
|
|
|
631
618
|
relocation?: ServiceWireOperationId
|
|
632
619
|
) {
|
|
633
620
|
await this.beginSourceActorMove(actor, state, deferredOperationId);
|
|
634
|
-
const relocationMetric =
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
621
|
+
const relocationMetric =
|
|
622
|
+
state.meshName === undefined
|
|
623
|
+
? undefined
|
|
624
|
+
: this.options.metrics?.startRelocation(
|
|
625
|
+
state.meshName,
|
|
626
|
+
'actor',
|
|
627
|
+
this.options.actorTransferRegistry.policy(state.actorType)
|
|
628
|
+
);
|
|
641
629
|
const sourceSpotId = state.spotId;
|
|
642
630
|
let sourceLeaveStarted = false;
|
|
643
631
|
let sealId: string | undefined;
|
|
644
632
|
try {
|
|
645
633
|
if (state.remoteBoundSessionTarget !== undefined) {
|
|
646
634
|
sealId = randomUUID();
|
|
647
|
-
const sealedTarget = await this.sealBoundSessionRoute(
|
|
648
|
-
actor,
|
|
649
|
-
state,
|
|
650
|
-
signal,
|
|
651
|
-
relocation
|
|
652
|
-
);
|
|
635
|
+
const sealedTarget = await this.sealBoundSessionRoute(actor, state, signal, relocation);
|
|
653
636
|
state.setRemoteBoundSessionTarget(sealedTarget);
|
|
654
637
|
this.options.actorHandoff.sealConnectionBoundIngress(actor.context.actorId);
|
|
655
638
|
}
|
|
@@ -666,16 +649,17 @@ export class ZLinkActorTransferRuntime {
|
|
|
666
649
|
sourceLeaveStarted = true;
|
|
667
650
|
await this.prepareSourceActorLeave(actor, sourceSpotId, signal);
|
|
668
651
|
}
|
|
669
|
-
const coreSourceLeave =
|
|
670
|
-
|
|
671
|
-
|
|
652
|
+
const coreSourceLeave =
|
|
653
|
+
lifecycleAuthority === 'core'
|
|
654
|
+
? this.beginCoreSourceLeave(actor.context.actorId)
|
|
655
|
+
: undefined;
|
|
672
656
|
const sourceLeaveCompletion = coreSourceLeave?.completion;
|
|
673
|
-
const handoffBacklog =
|
|
674
|
-
|
|
675
|
-
|
|
657
|
+
const handoffBacklog =
|
|
658
|
+
lifecycleAuthority === 'core'
|
|
659
|
+
? this.options.actorHandoff.snapshotCoreBacklog(actor.context.actorId)
|
|
660
|
+
: this.options.actorHandoff.snapshot(actor.context.actorId);
|
|
676
661
|
let phase: 'prepared' | 'committed' | 'rolledBack' = 'prepared';
|
|
677
|
-
let committedTargetOwnerFence:
|
|
678
|
-
ZLinkActorMessageFollowOwnerFence | undefined;
|
|
662
|
+
let committedTargetOwnerFence: ZLinkActorMessageFollowOwnerFence | undefined;
|
|
679
663
|
return {
|
|
680
664
|
...transfer,
|
|
681
665
|
handoffBacklog,
|
|
@@ -684,9 +668,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
684
668
|
onSourceLeaveSubmitted: (notify: () => Promise<void>) => {
|
|
685
669
|
const pending = this.coreSourceLeaves.get(actor.context.actorId);
|
|
686
670
|
if (pending === undefined) {
|
|
687
|
-
throw new Error(
|
|
688
|
-
`Actor '${actor.context.actorId}' has no pending Core source leave.`
|
|
689
|
-
);
|
|
671
|
+
throw new Error(`Actor '${actor.context.actorId}' has no pending Core source leave.`);
|
|
690
672
|
}
|
|
691
673
|
pending.notifySubmitted = notify;
|
|
692
674
|
},
|
|
@@ -696,10 +678,12 @@ export class ZLinkActorTransferRuntime {
|
|
|
696
678
|
observeSignal?: AbortSignal
|
|
697
679
|
) => {
|
|
698
680
|
const authority = this.options.authorityStore();
|
|
699
|
-
if (
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
681
|
+
if (
|
|
682
|
+
authority === undefined ||
|
|
683
|
+
target.targetOwnerId === undefined ||
|
|
684
|
+
target.ownerLeaseGeneration === undefined ||
|
|
685
|
+
target.targetNodeGeneration === undefined
|
|
686
|
+
) {
|
|
703
687
|
throw new Error(
|
|
704
688
|
`Actor '${actor.context.actorId}' relocation target has no complete authority fence.`
|
|
705
689
|
);
|
|
@@ -709,12 +693,12 @@ export class ZLinkActorTransferRuntime {
|
|
|
709
693
|
observeSignal
|
|
710
694
|
);
|
|
711
695
|
if (
|
|
712
|
-
committed.kind !== 'snapshot'
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
696
|
+
committed.kind !== 'snapshot' ||
|
|
697
|
+
committed.ownerId !== target.targetOwnerId ||
|
|
698
|
+
committed.ownerLeaseGeneration !== target.ownerLeaseGeneration ||
|
|
699
|
+
committed.allocation.descriptorLifecycleGeneration !== target.targetNodeGeneration ||
|
|
700
|
+
!routingIdsEqual(committed.allocation.descriptor.rid, target.targetNodeRid) ||
|
|
701
|
+
committed.objectGeneration !== targetActorRef.objectGeneration
|
|
718
702
|
) {
|
|
719
703
|
throw new Error(
|
|
720
704
|
`Actor '${actor.context.actorId}' relocation target authority was not committed exactly.`
|
|
@@ -761,7 +745,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
761
745
|
// callback, then release the old location and registry entry.
|
|
762
746
|
void sourceLeaveCompletion.then(
|
|
763
747
|
() => this.scheduleSourceDeparture(actor, sourceSpotId, true),
|
|
764
|
-
error => {
|
|
748
|
+
(error) => {
|
|
765
749
|
this.options.reportPostCommitError?.(error);
|
|
766
750
|
this.scheduleSourceDeparture(actor, sourceSpotId, true);
|
|
767
751
|
}
|
|
@@ -778,12 +762,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
778
762
|
this.coreSourceLeaves.delete(actor.context.actorId);
|
|
779
763
|
const replayGate = createHandoffReplayGate();
|
|
780
764
|
try {
|
|
781
|
-
await this.cancelSourceActorMove(
|
|
782
|
-
actor,
|
|
783
|
-
state,
|
|
784
|
-
deferredOperationId,
|
|
785
|
-
replayGate.start
|
|
786
|
-
);
|
|
765
|
+
await this.cancelSourceActorMove(actor, state, deferredOperationId, replayGate.start);
|
|
787
766
|
await this.restoreSourceActor(actor, sourceSpotId);
|
|
788
767
|
if (sealId !== undefined) {
|
|
789
768
|
await this.observeBoundSessionSealAbort(actor, state);
|
|
@@ -797,18 +776,16 @@ export class ZLinkActorTransferRuntime {
|
|
|
797
776
|
relocationMetric?.complete('failed');
|
|
798
777
|
const replayGate = createHandoffReplayGate();
|
|
799
778
|
try {
|
|
800
|
-
await this.cancelSourceActorMove(
|
|
801
|
-
actor,
|
|
802
|
-
state,
|
|
803
|
-
deferredOperationId,
|
|
804
|
-
replayGate.start
|
|
805
|
-
);
|
|
779
|
+
await this.cancelSourceActorMove(actor, state, deferredOperationId, replayGate.start);
|
|
806
780
|
if (sourceLeaveStarted) await this.restoreSourceActor(actor, sourceSpotId);
|
|
807
781
|
if (sealId !== undefined) {
|
|
808
782
|
await this.observeBoundSessionSealAbort(actor, state);
|
|
809
783
|
}
|
|
810
784
|
} catch (rollbackError) {
|
|
811
|
-
throw new AggregateError(
|
|
785
|
+
throw new AggregateError(
|
|
786
|
+
[error, rollbackError],
|
|
787
|
+
'Actor source leave and rollback both failed.'
|
|
788
|
+
);
|
|
812
789
|
} finally {
|
|
813
790
|
replayGate.open();
|
|
814
791
|
}
|
|
@@ -867,7 +844,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
867
844
|
handoffBacklog,
|
|
868
845
|
takeRelocationRelay: () =>
|
|
869
846
|
this.options.actorHandoff.takeRelocationRelay(actor.context.actorId),
|
|
870
|
-
setReplayResults: results => {
|
|
847
|
+
setReplayResults: (results) => {
|
|
871
848
|
if (terminal === 'prepared') replayResults = [...results];
|
|
872
849
|
},
|
|
873
850
|
commit: async (target, targetActorRef, targetOwnerFence) => {
|
|
@@ -881,7 +858,8 @@ export class ZLinkActorTransferRuntime {
|
|
|
881
858
|
targetOwnerFence
|
|
882
859
|
);
|
|
883
860
|
if (manageMembership && state.spotId !== undefined) {
|
|
884
|
-
await this.options
|
|
861
|
+
await this.options
|
|
862
|
+
.spotManager()
|
|
885
863
|
?.commitActorLeaveAfterTransfer(state.spotId, actor.context.actorId);
|
|
886
864
|
}
|
|
887
865
|
state.endMove();
|
|
@@ -894,19 +872,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
894
872
|
const replayGate = createHandoffReplayGate();
|
|
895
873
|
try {
|
|
896
874
|
if (manageMembership) {
|
|
897
|
-
await this.cancelSourceActorMove(
|
|
898
|
-
actor,
|
|
899
|
-
state,
|
|
900
|
-
undefined,
|
|
901
|
-
replayGate.start
|
|
902
|
-
);
|
|
875
|
+
await this.cancelSourceActorMove(actor, state, undefined, replayGate.start);
|
|
903
876
|
} else {
|
|
904
877
|
try {
|
|
905
|
-
const admitted = this.admitCanceledSourcePrefix(
|
|
906
|
-
actor,
|
|
907
|
-
state,
|
|
908
|
-
replayGate.start
|
|
909
|
-
);
|
|
878
|
+
const admitted = this.admitCanceledSourcePrefix(actor, state, replayGate.start);
|
|
910
879
|
void this.observeHandoffReplay(admitted.terminal);
|
|
911
880
|
} finally {
|
|
912
881
|
state.endMove();
|
|
@@ -926,21 +895,12 @@ export class ZLinkActorTransferRuntime {
|
|
|
926
895
|
try {
|
|
927
896
|
if (manageMembership) {
|
|
928
897
|
try {
|
|
929
|
-
await this.cancelSourceActorMove(
|
|
930
|
-
actor,
|
|
931
|
-
state,
|
|
932
|
-
undefined,
|
|
933
|
-
replayGate.start
|
|
934
|
-
);
|
|
898
|
+
await this.cancelSourceActorMove(actor, state, undefined, replayGate.start);
|
|
935
899
|
sourceRestored = true;
|
|
936
900
|
} catch {}
|
|
937
901
|
} else {
|
|
938
902
|
try {
|
|
939
|
-
const admitted = this.admitCanceledSourcePrefix(
|
|
940
|
-
actor,
|
|
941
|
-
state,
|
|
942
|
-
replayGate.start
|
|
943
|
-
);
|
|
903
|
+
const admitted = this.admitCanceledSourcePrefix(actor, state, replayGate.start);
|
|
944
904
|
void this.observeHandoffReplay(admitted.terminal);
|
|
945
905
|
sourceRestored = true;
|
|
946
906
|
} catch {
|
|
@@ -1043,91 +1003,92 @@ export class ZLinkActorTransferRuntime {
|
|
|
1043
1003
|
const target = state.remoteBoundSessionTarget;
|
|
1044
1004
|
const actorRef = state.nativeActorRef;
|
|
1045
1005
|
if (
|
|
1046
|
-
target === undefined ||
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1006
|
+
target === undefined ||
|
|
1007
|
+
actorRef === undefined ||
|
|
1008
|
+
target.bindingGeneration === undefined ||
|
|
1009
|
+
target.bindingGeneration <= 0n ||
|
|
1010
|
+
state.locationGeneration === undefined ||
|
|
1011
|
+
state.locationGeneration < 0n ||
|
|
1012
|
+
state.ownerLeaseGeneration === undefined ||
|
|
1013
|
+
state.ownerLeaseGeneration <= 0n
|
|
1050
1014
|
) {
|
|
1051
|
-
throw new Error(
|
|
1015
|
+
throw new Error(
|
|
1016
|
+
`Actor '${actor.context.actorId}' Session route cannot be sealed without its exact source fence.`
|
|
1017
|
+
);
|
|
1052
1018
|
}
|
|
1053
1019
|
const serviceWire = this.options.sessionRelocationWire?.();
|
|
1054
1020
|
const authorityStore = this.options.authorityStore();
|
|
1055
1021
|
const descriptors = this.options.liveDescriptors;
|
|
1056
1022
|
if (
|
|
1057
|
-
relocation === undefined
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1023
|
+
relocation === undefined ||
|
|
1024
|
+
serviceWire === undefined ||
|
|
1025
|
+
authorityStore === undefined ||
|
|
1026
|
+
descriptors === undefined ||
|
|
1027
|
+
target.sessionRid === undefined
|
|
1062
1028
|
) {
|
|
1063
1029
|
throw new Error(
|
|
1064
1030
|
`Actor '${actor.context.actorId}' Session relocation requires the command 42/43 service-wire path.`
|
|
1065
1031
|
);
|
|
1066
1032
|
}
|
|
1067
1033
|
const [authority, live] = await Promise.all([
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
),
|
|
1072
|
-
descriptors(target.routerChannelId, signal)
|
|
1073
|
-
]);
|
|
1034
|
+
authorityStore.readAuthority(encodeAuthorityKey('actor', actor.context.actorId), signal),
|
|
1035
|
+
descriptors(target.routerChannelId, signal)
|
|
1036
|
+
]);
|
|
1074
1037
|
const local = this.options.primaryMeshNode().status();
|
|
1075
|
-
const sessionOwner = live.find(value =>
|
|
1076
|
-
String(value.rid) === String(target.targetNodeRid)
|
|
1077
|
-
);
|
|
1038
|
+
const sessionOwner = live.find((value) => String(value.rid) === String(target.targetNodeRid));
|
|
1078
1039
|
if (
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1040
|
+
authority.kind !== 'snapshot' ||
|
|
1041
|
+
sessionOwner === undefined ||
|
|
1042
|
+
String(local.routingId) !== String(actorRef.nodeRid) ||
|
|
1043
|
+
authority.objectGeneration !== actorRef.generation ||
|
|
1044
|
+
authority.authorityOwnerGeneration !== state.locationGeneration ||
|
|
1045
|
+
authority.ownerLeaseGeneration !== state.ownerLeaseGeneration ||
|
|
1046
|
+
String(authority.allocation.descriptor.rid) !== String(actorRef.nodeRid) ||
|
|
1047
|
+
authority.allocation.descriptorLifecycleGeneration !== local.lifecycleGeneration ||
|
|
1048
|
+
(target.sessionNodeRid !== undefined &&
|
|
1049
|
+
String(target.sessionNodeRid) !== String(target.targetNodeRid))
|
|
1089
1050
|
) {
|
|
1090
1051
|
throw new Error(
|
|
1091
1052
|
`Actor '${actor.context.actorId}' Session route service-wire source fence is stale.`
|
|
1092
1053
|
);
|
|
1093
1054
|
}
|
|
1094
1055
|
const coordinator = {
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1056
|
+
ownerId: authority.ownerId,
|
|
1057
|
+
leaseGeneration: authority.ownerLeaseGeneration,
|
|
1058
|
+
nodeRid: String(local.routingId),
|
|
1059
|
+
nodeGeneration: local.lifecycleGeneration,
|
|
1060
|
+
expectedAuthorityStoreVersion: authority.storeVersion.value
|
|
1061
|
+
};
|
|
1101
1062
|
const session = {
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1063
|
+
sessionOwnerNodeRid: String(target.targetNodeRid),
|
|
1064
|
+
sessionOwnerNodeGeneration: sessionOwner.lifecycleGeneration,
|
|
1065
|
+
sessionOwnerId: sessionOwner.ownerId,
|
|
1066
|
+
sessionOwnerLeaseGeneration: sessionOwner.leaseGeneration,
|
|
1067
|
+
sessionRid: String(target.sessionRid),
|
|
1068
|
+
bindingGeneration: target.bindingGeneration
|
|
1069
|
+
};
|
|
1109
1070
|
const request: ServiceSessionRelocationSeal = {
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1071
|
+
relocation,
|
|
1072
|
+
coordinator,
|
|
1073
|
+
senderRole: 'source',
|
|
1074
|
+
actor: {
|
|
1113
1075
|
actor: {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
nodeRid: String(actorRef.nodeRid)
|
|
1118
|
-
},
|
|
1119
|
-
targetNodeGeneration: local.lifecycleGeneration,
|
|
1120
|
-
authorityOwnerGeneration: authority.authorityOwnerGeneration,
|
|
1121
|
-
ownerLeaseGeneration: authority.ownerLeaseGeneration
|
|
1076
|
+
actorId: actor.context.actorId,
|
|
1077
|
+
generation: actorRef.generation,
|
|
1078
|
+
nodeRid: String(actorRef.nodeRid)
|
|
1122
1079
|
},
|
|
1123
|
-
|
|
1124
|
-
|
|
1080
|
+
targetNodeGeneration: local.lifecycleGeneration,
|
|
1081
|
+
authorityOwnerGeneration: authority.authorityOwnerGeneration,
|
|
1082
|
+
ownerLeaseGeneration: authority.ownerLeaseGeneration
|
|
1083
|
+
},
|
|
1084
|
+
session
|
|
1085
|
+
};
|
|
1125
1086
|
await serviceWire.requestSessionRelocationSeal(
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1087
|
+
target.routerChannelId,
|
|
1088
|
+
target.targetNodeRid,
|
|
1089
|
+
request,
|
|
1090
|
+
signal
|
|
1091
|
+
);
|
|
1131
1092
|
return {
|
|
1132
1093
|
...target,
|
|
1133
1094
|
previousAuthorityOwnerGeneration: authority.authorityOwnerGeneration,
|
|
@@ -1142,14 +1103,23 @@ export class ZLinkActorTransferRuntime {
|
|
|
1142
1103
|
state: ZLinkActorRuntimeState,
|
|
1143
1104
|
targetOverride?: ZLinkRemoteBoundSessionTarget
|
|
1144
1105
|
): Promise<void> {
|
|
1145
|
-
const target =
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1106
|
+
const target =
|
|
1107
|
+
targetOverride ??
|
|
1108
|
+
preferredRemoteBoundSessionTarget(
|
|
1109
|
+
state.remoteBoundSessionTarget,
|
|
1110
|
+
state.boundSessionTransferTarget
|
|
1111
|
+
);
|
|
1149
1112
|
const actorRef = state.nativeActorRef;
|
|
1150
|
-
if (
|
|
1151
|
-
target
|
|
1152
|
-
|
|
1113
|
+
if (
|
|
1114
|
+
target === undefined ||
|
|
1115
|
+
actorRef === undefined ||
|
|
1116
|
+
target.bindingGeneration === undefined ||
|
|
1117
|
+
target.previousAuthorityOwnerGeneration === undefined ||
|
|
1118
|
+
target.previousOwnerLeaseGeneration === undefined
|
|
1119
|
+
) {
|
|
1120
|
+
throw new Error(
|
|
1121
|
+
`Actor '${actor.context.actorId}' Session route seal cannot be released without its exact fence.`
|
|
1122
|
+
);
|
|
1153
1123
|
}
|
|
1154
1124
|
const serviceFence = target.serviceWireRelocation;
|
|
1155
1125
|
const serviceWire = this.options.sessionRelocationWire?.();
|
|
@@ -1179,10 +1149,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
1179
1149
|
);
|
|
1180
1150
|
}
|
|
1181
1151
|
await serviceWire.sendSessionRelocationRoute(
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1152
|
+
target.routerChannelId,
|
|
1153
|
+
target.targetNodeRid,
|
|
1154
|
+
route,
|
|
1155
|
+
this.options.shutdownSignal?.()
|
|
1186
1156
|
);
|
|
1187
1157
|
}
|
|
1188
1158
|
|
|
@@ -1236,8 +1206,9 @@ export class ZLinkActorTransferRuntime {
|
|
|
1236
1206
|
releaseLocation: boolean
|
|
1237
1207
|
): void {
|
|
1238
1208
|
if (this.sourceDepartureTasks.has(actor.context.actorId)) return;
|
|
1239
|
-
const task = this.finishSourceDeparture(actor, sourceSpotId, releaseLocation)
|
|
1240
|
-
|
|
1209
|
+
const task = this.finishSourceDeparture(actor, sourceSpotId, releaseLocation).finally(() =>
|
|
1210
|
+
this.sourceDepartureTasks.delete(actor.context.actorId)
|
|
1211
|
+
);
|
|
1241
1212
|
this.sourceDepartureTasks.set(actor.context.actorId, task);
|
|
1242
1213
|
}
|
|
1243
1214
|
|
|
@@ -1250,15 +1221,16 @@ export class ZLinkActorTransferRuntime {
|
|
|
1250
1221
|
while (this.options.shutdownSignal?.()?.aborted !== true) {
|
|
1251
1222
|
try {
|
|
1252
1223
|
if (sourceSpotId !== undefined) {
|
|
1253
|
-
await this.options
|
|
1224
|
+
await this.options
|
|
1225
|
+
.spotManager()
|
|
1226
|
+
?.commitActorLeaveAfterTransfer(sourceSpotId, actor.context.actorId);
|
|
1254
1227
|
}
|
|
1255
1228
|
if (releaseLocation) {
|
|
1256
1229
|
const state = this.options.actorManager()?.getState(actor.context.actorId);
|
|
1257
1230
|
if (state?.actorType !== undefined && state.ownsLocation) {
|
|
1258
|
-
await this.options
|
|
1259
|
-
|
|
1260
|
-
actor.context.actorId
|
|
1261
|
-
);
|
|
1231
|
+
await this.options
|
|
1232
|
+
.locationLifecycle()
|
|
1233
|
+
?.releaseActor(state.actorType, actor.context.actorId);
|
|
1262
1234
|
state.markLocationReleased();
|
|
1263
1235
|
}
|
|
1264
1236
|
// Message Follow owns the bounded stale route after the native leave.
|
|
@@ -1271,7 +1243,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
1271
1243
|
return;
|
|
1272
1244
|
} catch (error) {
|
|
1273
1245
|
this.options.reportPostCommitError?.(error);
|
|
1274
|
-
if (!await retry.wait(this.options.shutdownSignal?.())) return;
|
|
1246
|
+
if (!(await retry.wait(this.options.shutdownSignal?.()))) return;
|
|
1275
1247
|
}
|
|
1276
1248
|
}
|
|
1277
1249
|
}
|
|
@@ -1284,18 +1256,21 @@ export class ZLinkActorTransferRuntime {
|
|
|
1284
1256
|
actorCreateRequest?: Message,
|
|
1285
1257
|
signal?: AbortSignal
|
|
1286
1258
|
): Promise<{ readonly actor: ZLinkActor; readonly actorRef: ZLinkBackendActorRef }> {
|
|
1287
|
-
const actorManager = this.requireActorManager(
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1259
|
+
const actorManager = this.requireActorManager(
|
|
1260
|
+
'Routed actor join requires ZLINK_ACTOR_MANAGER.'
|
|
1261
|
+
);
|
|
1262
|
+
const actor =
|
|
1263
|
+
actorRef === undefined
|
|
1264
|
+
? await actorManager.getOrCreateActor(actorId, actorType, signal)
|
|
1265
|
+
: await actorManager.getOrCreateWithNativeRef(
|
|
1266
|
+
actorId,
|
|
1267
|
+
actorType,
|
|
1268
|
+
actorRef as unknown as ZLinkBackendActorRef,
|
|
1269
|
+
actorCreateRequest === undefined
|
|
1270
|
+
? undefined
|
|
1271
|
+
: wrapFrameworkPayloadMessage(actorCreateRequest, this.options.messageSerializers),
|
|
1272
|
+
signal
|
|
1273
|
+
);
|
|
1299
1274
|
const state = actorManager.getState(actorId);
|
|
1300
1275
|
if (state === undefined) {
|
|
1301
1276
|
throw new Error(`Actor '${actorId}' state was not created.`);
|
|
@@ -1317,7 +1292,9 @@ export class ZLinkActorTransferRuntime {
|
|
|
1317
1292
|
remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget,
|
|
1318
1293
|
signal?: AbortSignal
|
|
1319
1294
|
): Promise<{ readonly actor: ZLinkActor; readonly actorRef: ZLinkBackendActorRef }> {
|
|
1320
|
-
const actorManager = this.requireActorManager(
|
|
1295
|
+
const actorManager = this.requireActorManager(
|
|
1296
|
+
'Routed actor transfer requires ZLINK_ACTOR_MANAGER.'
|
|
1297
|
+
);
|
|
1321
1298
|
const materialized = await actorManager.materializeTransferredActor(
|
|
1322
1299
|
actorId,
|
|
1323
1300
|
actorType,
|
|
@@ -1333,10 +1310,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
1333
1310
|
state.setBoundSessionTransferTarget(remoteBoundSessionTarget);
|
|
1334
1311
|
if (remoteBoundSessionTarget !== undefined) {
|
|
1335
1312
|
state.setRemoteBoundSessionTarget(
|
|
1336
|
-
mergeRemoteBoundSessionTarget(
|
|
1337
|
-
remoteBoundSessionTarget,
|
|
1338
|
-
state.remoteBoundSessionTarget
|
|
1339
|
-
)
|
|
1313
|
+
mergeRemoteBoundSessionTarget(remoteBoundSessionTarget, state.remoteBoundSessionTarget)
|
|
1340
1314
|
);
|
|
1341
1315
|
}
|
|
1342
1316
|
if (remoteBoundSessionTarget?.bindingGeneration !== undefined) {
|
|
@@ -1364,19 +1338,20 @@ export class ZLinkActorTransferRuntime {
|
|
|
1364
1338
|
const state = this.options.actorManager()?.getState(actor.context.actorId);
|
|
1365
1339
|
const actorType = state?.actorType;
|
|
1366
1340
|
const local = this.options.primaryMeshNode().status();
|
|
1367
|
-
const targetActorRef =
|
|
1368
|
-
|
|
1369
|
-
|
|
1341
|
+
const targetActorRef =
|
|
1342
|
+
state?.nativeActorRef === undefined
|
|
1343
|
+
? undefined
|
|
1344
|
+
: toFrameworkActorRef(state.nativeActorRef, actor.context.meshName);
|
|
1370
1345
|
if (
|
|
1371
|
-
store === undefined
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1346
|
+
store === undefined ||
|
|
1347
|
+
owner === undefined ||
|
|
1348
|
+
state === undefined ||
|
|
1349
|
+
actorType === undefined ||
|
|
1350
|
+
targetActorRef === undefined ||
|
|
1351
|
+
local.lifecycleGeneration <= 0n ||
|
|
1352
|
+
spotGeneration <= 0n ||
|
|
1353
|
+
membershipEpoch <= 0n ||
|
|
1354
|
+
!Number.isSafeInteger(deadlineUnixMs)
|
|
1380
1355
|
) {
|
|
1381
1356
|
throw new Error(
|
|
1382
1357
|
`Actor '${actor.context.actorId}' target authority commit has an incomplete materialization fence.`
|
|
@@ -1385,18 +1360,20 @@ export class ZLinkActorTransferRuntime {
|
|
|
1385
1360
|
const key = encodeAuthorityKey('actor', actor.context.actorId);
|
|
1386
1361
|
const expected = await store.readAuthority(key, signal);
|
|
1387
1362
|
if (expected.kind !== 'snapshot') {
|
|
1388
|
-
throw new Error(
|
|
1363
|
+
throw new Error(
|
|
1364
|
+
`Actor '${actor.context.actorId}' source authority is missing at the target.`
|
|
1365
|
+
);
|
|
1389
1366
|
}
|
|
1390
1367
|
const exactTarget = (value: ZLinkAuthoritySnapshot): boolean =>
|
|
1391
|
-
value.allocation.state === 'active'
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1368
|
+
value.allocation.state === 'active' &&
|
|
1369
|
+
value.allocation.objectKind === 'actor' &&
|
|
1370
|
+
value.allocation.stableType === actorType &&
|
|
1371
|
+
value.objectGeneration === targetActorRef.objectGeneration &&
|
|
1372
|
+
value.ownerId === owner.ownerId &&
|
|
1373
|
+
value.ownerLeaseGeneration === owner.leaseGeneration &&
|
|
1374
|
+
value.allocation.descriptor.meshName === actor.context.meshName &&
|
|
1375
|
+
routingIdsEqual(value.allocation.descriptor.rid, local.routingId) &&
|
|
1376
|
+
value.allocation.descriptorLifecycleGeneration === local.lifecycleGeneration;
|
|
1400
1377
|
const adopt = (value: ZLinkAuthoritySnapshot): ZLinkAuthoritySnapshot => {
|
|
1401
1378
|
state.setLocationGeneration(value.authorityOwnerGeneration);
|
|
1402
1379
|
state.setOwnerLeaseGeneration(value.ownerLeaseGeneration);
|
|
@@ -1406,42 +1383,47 @@ export class ZLinkActorTransferRuntime {
|
|
|
1406
1383
|
};
|
|
1407
1384
|
if (exactTarget(expected)) return adopt(expected);
|
|
1408
1385
|
if (
|
|
1409
|
-
expected.allocation.state !== 'active'
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1386
|
+
expected.allocation.state !== 'active' ||
|
|
1387
|
+
expected.allocation.objectKind !== 'actor' ||
|
|
1388
|
+
expected.allocation.stableType !== actorType ||
|
|
1389
|
+
expected.objectGeneration !== sourceActorRef.objectGeneration ||
|
|
1390
|
+
expected.allocation.descriptor.meshName !== sourceActorRef.meshName ||
|
|
1391
|
+
!routingIdsEqual(expected.allocation.descriptor.rid, sourceActorRef.nodeRid)
|
|
1415
1392
|
) {
|
|
1416
1393
|
throw new Error(
|
|
1417
1394
|
`Actor '${actor.context.actorId}' relocation source authority is stale at the target.`
|
|
1418
1395
|
);
|
|
1419
1396
|
}
|
|
1420
|
-
const membershipMutation = Buffer.from(
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1397
|
+
const membershipMutation = Buffer.from(
|
|
1398
|
+
JSON.stringify({
|
|
1399
|
+
actorId: actor.context.actorId,
|
|
1400
|
+
actorGeneration: targetActorRef.objectGeneration.toString(),
|
|
1401
|
+
spotId: String(spotId),
|
|
1402
|
+
spotGeneration: spotGeneration.toString(),
|
|
1403
|
+
membershipEpoch: membershipEpoch.toString()
|
|
1404
|
+
}),
|
|
1405
|
+
'utf8'
|
|
1406
|
+
);
|
|
1427
1407
|
const request = {
|
|
1428
1408
|
aggregateId: { value: transferId } as ZLinkAggregateId,
|
|
1429
1409
|
aggregateGeneration: local.lifecycleGeneration,
|
|
1430
|
-
participants: [
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1410
|
+
participants: [
|
|
1411
|
+
{
|
|
1412
|
+
authorityKey: key,
|
|
1413
|
+
expectedStoreVersion: expected.storeVersion,
|
|
1414
|
+
ownerTransition: 'newOwner' as const,
|
|
1415
|
+
authorityPayload: rewriteActorAuthorityRoute(
|
|
1416
|
+
expected.payload,
|
|
1417
|
+
targetActorRef,
|
|
1418
|
+
String(spotId),
|
|
1419
|
+
spotGeneration,
|
|
1420
|
+
ZLinkSpotKind.User,
|
|
1421
|
+
local.lifecycleGeneration,
|
|
1422
|
+
owner
|
|
1423
|
+
),
|
|
1424
|
+
membershipMutation
|
|
1425
|
+
}
|
|
1426
|
+
],
|
|
1445
1427
|
inventoryDigest: createHash('sha256').update(membershipMutation).digest(),
|
|
1446
1428
|
targetDescriptor: {
|
|
1447
1429
|
meshName: actor.context.meshName,
|
|
@@ -1463,11 +1445,13 @@ export class ZLinkActorTransferRuntime {
|
|
|
1463
1445
|
if (prepared?.kind === 'prepared' || prepared?.kind === 'alreadyPrepared') break;
|
|
1464
1446
|
const observed = await this.readActorAuthorityForRelocation(store, key, signal);
|
|
1465
1447
|
if (observed !== undefined && exactTarget(observed)) return adopt(observed);
|
|
1466
|
-
if (
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1448
|
+
if (
|
|
1449
|
+
prepared !== undefined ||
|
|
1450
|
+
(observed !== undefined && !sameSourceActorAuthority(observed, expected))
|
|
1451
|
+
) {
|
|
1452
|
+
throw new Error(`Actor '${actor.context.actorId}' target authority prepare was rejected.`, {
|
|
1453
|
+
cause: firstError
|
|
1454
|
+
});
|
|
1471
1455
|
}
|
|
1472
1456
|
await waitForActorAuthorityRetry(deadlineAtMs, signal, firstError);
|
|
1473
1457
|
}
|
|
@@ -1482,9 +1466,9 @@ export class ZLinkActorTransferRuntime {
|
|
|
1482
1466
|
const observed = await this.readActorAuthorityForRelocation(store, key, signal);
|
|
1483
1467
|
if (observed !== undefined && exactTarget(observed)) return adopt(observed);
|
|
1484
1468
|
if (
|
|
1485
|
-
committed?.kind === 'stale'
|
|
1486
|
-
|
|
1487
|
-
|
|
1469
|
+
committed?.kind === 'stale' ||
|
|
1470
|
+
committed?.kind === 'generationExhausted' ||
|
|
1471
|
+
(observed !== undefined && !sameSourceActorAuthority(observed, expected))
|
|
1488
1472
|
) {
|
|
1489
1473
|
throw new Error(
|
|
1490
1474
|
`Actor '${actor.context.actorId}' target authority commit did not converge.`,
|
|
@@ -1532,17 +1516,19 @@ export class ZLinkActorTransferRuntime {
|
|
|
1532
1516
|
const actorRef = state?.nativeActorRef;
|
|
1533
1517
|
const binding = state?.boundSessionTransferTarget;
|
|
1534
1518
|
if (
|
|
1535
|
-
actorRef !== undefined
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1519
|
+
actorRef !== undefined &&
|
|
1520
|
+
binding?.sessionNodeRid !== undefined &&
|
|
1521
|
+
binding.sessionRid !== undefined &&
|
|
1522
|
+
binding.bindingGeneration !== undefined
|
|
1539
1523
|
) {
|
|
1540
|
-
this.options
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1524
|
+
this.options
|
|
1525
|
+
.primaryMeshNode()
|
|
1526
|
+
.restoreActorSessionBinding?.(
|
|
1527
|
+
actorRef,
|
|
1528
|
+
binding.sessionNodeRid,
|
|
1529
|
+
binding.sessionRid,
|
|
1530
|
+
binding.bindingGeneration
|
|
1531
|
+
);
|
|
1546
1532
|
}
|
|
1547
1533
|
}
|
|
1548
1534
|
|
|
@@ -1552,9 +1538,8 @@ export class ZLinkActorTransferRuntime {
|
|
|
1552
1538
|
const targetActorRef = {
|
|
1553
1539
|
actorId: actorRef.actorId,
|
|
1554
1540
|
nodeRid: node.status().routingId,
|
|
1555
|
-
generation:
|
|
1556
|
-
? localActorRef.generation
|
|
1557
|
-
: actorRef.objectGeneration
|
|
1541
|
+
generation:
|
|
1542
|
+
localActorRef.generation > 0n ? localActorRef.generation : actorRef.objectGeneration
|
|
1558
1543
|
};
|
|
1559
1544
|
this.options.actorManager()?.getState(actor.context.actorId)?.setNativeActorRef(targetActorRef);
|
|
1560
1545
|
}
|
|
@@ -1579,35 +1564,39 @@ export class ZLinkActorTransferRuntime {
|
|
|
1579
1564
|
const spotGeneration = joinedLocation?.spotGeneration ?? location.spotGeneration;
|
|
1580
1565
|
const membershipEpoch = joinedLocation?.membershipEpoch ?? location.membershipEpoch;
|
|
1581
1566
|
if (spotGeneration <= 0n || membershipEpoch <= 0n) {
|
|
1582
|
-
throw new Error(
|
|
1567
|
+
throw new Error(
|
|
1568
|
+
`Actor '${actor.context.actorId}' committed target location has invalid lifecycle generations.`
|
|
1569
|
+
);
|
|
1583
1570
|
}
|
|
1584
1571
|
// RoutingId is an opaque byte value, so the committed target is compared by
|
|
1585
1572
|
// value. Reference equality would reject a matching SPOT read back from the
|
|
1586
1573
|
// Core lookup.
|
|
1587
1574
|
if (
|
|
1588
|
-
joinedLocation === undefined
|
|
1589
|
-
|
|
1590
|
-
location.spotId ===
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
!== encodeRoutingIdStorageHex(spotId)
|
|
1594
|
-
)
|
|
1575
|
+
joinedLocation === undefined &&
|
|
1576
|
+
(location.spotId === null ||
|
|
1577
|
+
location.spotId === undefined ||
|
|
1578
|
+
encodeRoutingIdStorageHex(location.spotId as RoutingId) !==
|
|
1579
|
+
encodeRoutingIdStorageHex(spotId))
|
|
1595
1580
|
) {
|
|
1596
|
-
throw new Error(
|
|
1581
|
+
throw new Error(
|
|
1582
|
+
`Actor '${actor.context.actorId}' Core location does not match the committed target SPOT.`
|
|
1583
|
+
);
|
|
1597
1584
|
}
|
|
1598
1585
|
const deadline = performance.now() + 5_000;
|
|
1599
1586
|
const ownerNodeGeneration = node.status().lifecycleGeneration;
|
|
1600
1587
|
if (ownerNodeGeneration <= 0n) {
|
|
1601
|
-
throw new Error(
|
|
1588
|
+
throw new Error(
|
|
1589
|
+
`Actor '${actor.context.actorId}' owner MeshNode has no valid lifecycle generation.`
|
|
1590
|
+
);
|
|
1602
1591
|
}
|
|
1603
|
-
const authority = await this.options
|
|
1604
|
-
|
|
1605
|
-
|
|
1592
|
+
const authority = await this.options
|
|
1593
|
+
.authorityStore()
|
|
1594
|
+
?.readAuthority(encodeAuthorityKey('actor', actor.context.actorId));
|
|
1606
1595
|
if (
|
|
1607
|
-
authority?.kind === 'snapshot'
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1596
|
+
authority?.kind === 'snapshot' &&
|
|
1597
|
+
authority.allocation.state === 'active' &&
|
|
1598
|
+
String(authority.allocation.descriptor.rid) === String(node.status().routingId) &&
|
|
1599
|
+
authority.allocation.descriptorLifecycleGeneration === ownerNodeGeneration
|
|
1611
1600
|
) {
|
|
1612
1601
|
state.setLocationGeneration(authority.authorityOwnerGeneration);
|
|
1613
1602
|
state.setOwnerLeaseGeneration(authority.ownerLeaseGeneration);
|
|
@@ -1620,10 +1609,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
1620
1609
|
claim = await lifecycle.takeoverActorJoinedSpot(
|
|
1621
1610
|
actorType,
|
|
1622
1611
|
actor.context.actorId,
|
|
1623
|
-
toFrameworkActorRef(
|
|
1624
|
-
state.nativeActorRef ?? location.actor as never,
|
|
1625
|
-
spotMeshName
|
|
1626
|
-
),
|
|
1612
|
+
toFrameworkActorRef(state.nativeActorRef ?? (location.actor as never), spotMeshName),
|
|
1627
1613
|
spotMeshName,
|
|
1628
1614
|
spotId,
|
|
1629
1615
|
spotGeneration,
|
|
@@ -1659,9 +1645,9 @@ export class ZLinkActorTransferRuntime {
|
|
|
1659
1645
|
const target = await this.options.spotRouteResolver?.()?.resolve(spotId);
|
|
1660
1646
|
if (target === undefined || target.spotKind === 'entry') return;
|
|
1661
1647
|
if (
|
|
1662
|
-
!routingIdsEqual(target.spotId, spotId)
|
|
1663
|
-
|
|
1664
|
-
|
|
1648
|
+
!routingIdsEqual(target.spotId, spotId) ||
|
|
1649
|
+
!routingIdsEqual(target.targetNodeRid, node.status().routingId) ||
|
|
1650
|
+
target.targetSpotGeneration !== spotGeneration
|
|
1665
1651
|
) {
|
|
1666
1652
|
throw new Error('Committed native Actor target does not match its Ready Spot route.');
|
|
1667
1653
|
}
|
|
@@ -1674,7 +1660,9 @@ export class ZLinkActorTransferRuntime {
|
|
|
1674
1660
|
spotMeshName: string
|
|
1675
1661
|
): Promise<ZLinkNativeActorJoinSnapshot> {
|
|
1676
1662
|
const state = this.options.actorManager()?.getState(actor.context.actorId);
|
|
1677
|
-
const previousLocation = this.options
|
|
1663
|
+
const previousLocation = this.options
|
|
1664
|
+
.locationLifecycle()
|
|
1665
|
+
?.actorLocationSnapshot(actor.context.actorId);
|
|
1678
1666
|
const snapshot = {
|
|
1679
1667
|
spotId: state?.spotId,
|
|
1680
1668
|
spot: state?.spot,
|
|
@@ -1727,12 +1715,14 @@ export class ZLinkActorTransferRuntime {
|
|
|
1727
1715
|
if (state?.ownsLocation !== true || actorType === undefined || lifecycle === undefined) return;
|
|
1728
1716
|
if (snapshot.spotId === undefined) {
|
|
1729
1717
|
if (
|
|
1730
|
-
snapshot.locationSpotId === undefined
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1718
|
+
snapshot.locationSpotId === undefined ||
|
|
1719
|
+
snapshot.spotGeneration === undefined ||
|
|
1720
|
+
snapshot.membershipEpoch === undefined ||
|
|
1721
|
+
snapshot.ownerNodeGeneration === undefined
|
|
1734
1722
|
) {
|
|
1735
|
-
throw new Error(
|
|
1723
|
+
throw new Error(
|
|
1724
|
+
`Actor '${actor.context.actorId}' cannot restore its Entry SPOT location without its exact generation fields.`
|
|
1725
|
+
);
|
|
1736
1726
|
}
|
|
1737
1727
|
await lifecycle.notifyActorLeftSpot(
|
|
1738
1728
|
actorType,
|
|
@@ -1745,15 +1735,19 @@ export class ZLinkActorTransferRuntime {
|
|
|
1745
1735
|
return;
|
|
1746
1736
|
}
|
|
1747
1737
|
if (snapshot.actorRef === undefined) {
|
|
1748
|
-
throw new Error(
|
|
1738
|
+
throw new Error(
|
|
1739
|
+
`Actor '${actor.context.actorId}' cannot restore its previous SPOT location without a native ref.`
|
|
1740
|
+
);
|
|
1749
1741
|
}
|
|
1750
1742
|
if (
|
|
1751
|
-
snapshot.spotMeshName === undefined
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1743
|
+
snapshot.spotMeshName === undefined ||
|
|
1744
|
+
snapshot.spotGeneration === undefined ||
|
|
1745
|
+
snapshot.membershipEpoch === undefined ||
|
|
1746
|
+
snapshot.ownerNodeGeneration === undefined
|
|
1755
1747
|
) {
|
|
1756
|
-
throw new Error(
|
|
1748
|
+
throw new Error(
|
|
1749
|
+
`Actor '${actor.context.actorId}' cannot restore its previous SPOT location without its exact generation fields.`
|
|
1750
|
+
);
|
|
1757
1751
|
}
|
|
1758
1752
|
const restored = await lifecycle.takeoverActorJoinedSpot(
|
|
1759
1753
|
actorType,
|
|
@@ -1767,10 +1761,13 @@ export class ZLinkActorTransferRuntime {
|
|
|
1767
1761
|
async () => state.clearAfterDestroy()
|
|
1768
1762
|
);
|
|
1769
1763
|
if (restored.status === 'conflict') {
|
|
1770
|
-
throw new Error(
|
|
1764
|
+
throw new Error(
|
|
1765
|
+
`Actor '${actor.context.actorId}' previous SPOT location could not be restored.`
|
|
1766
|
+
);
|
|
1771
1767
|
}
|
|
1772
1768
|
if (restored.generation !== undefined) state.setLocationGeneration(restored.generation);
|
|
1773
|
-
if (restored.claimed !== undefined)
|
|
1769
|
+
if (restored.claimed !== undefined)
|
|
1770
|
+
state.setOwnerLeaseGeneration(restored.claimed.leaseGeneration);
|
|
1774
1771
|
}
|
|
1775
1772
|
|
|
1776
1773
|
async rollbackRoutedActor(actor: ZLinkActor, signal?: AbortSignal): Promise<void> {
|
|
@@ -1825,35 +1822,33 @@ export class ZLinkActorTransferRuntime {
|
|
|
1825
1822
|
return;
|
|
1826
1823
|
}
|
|
1827
1824
|
const serviceFence = target.serviceWireRelocation;
|
|
1828
|
-
const serviceWire =
|
|
1829
|
-
? undefined
|
|
1830
|
-
: this.options.sessionRelocationWire?.();
|
|
1825
|
+
const serviceWire =
|
|
1826
|
+
serviceFence === undefined ? undefined : this.options.sessionRelocationWire?.();
|
|
1831
1827
|
if (serviceFence === undefined) {
|
|
1832
1828
|
throw new Error(`Actor '${actorId}' command 44 has no service-wire relocation fence.`);
|
|
1833
1829
|
}
|
|
1834
1830
|
{
|
|
1835
1831
|
if (
|
|
1836
|
-
target.bindingGeneration === undefined
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1832
|
+
target.bindingGeneration === undefined ||
|
|
1833
|
+
target.previousAuthorityOwnerGeneration === undefined ||
|
|
1834
|
+
target.bindingGeneration <= 0n ||
|
|
1835
|
+
target.previousAuthorityOwnerGeneration < 0n ||
|
|
1836
|
+
ownershipGeneration <= target.previousAuthorityOwnerGeneration
|
|
1841
1837
|
) {
|
|
1842
1838
|
throw new Error(`Actor '${actorId}' command 44 Session route fence is incomplete.`);
|
|
1843
1839
|
}
|
|
1844
1840
|
if (serviceWire === undefined) {
|
|
1845
1841
|
throw new Error(`Actor '${actorId}' command 44 service-wire bridge is unavailable.`);
|
|
1846
1842
|
}
|
|
1847
|
-
const authority = await this.options
|
|
1848
|
-
|
|
1849
|
-
this.options.shutdownSignal?.()
|
|
1850
|
-
);
|
|
1843
|
+
const authority = await this.options
|
|
1844
|
+
.authorityStore()
|
|
1845
|
+
?.readAuthority(encodeAuthorityKey('actor', actorId), this.options.shutdownSignal?.());
|
|
1851
1846
|
if (
|
|
1852
|
-
authority?.kind !== 'snapshot'
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1847
|
+
authority?.kind !== 'snapshot' ||
|
|
1848
|
+
authority.objectGeneration !== actorRef.generation ||
|
|
1849
|
+
authority.authorityOwnerGeneration !== ownershipGeneration ||
|
|
1850
|
+
authority.ownerLeaseGeneration !== targetOwnerLeaseGeneration ||
|
|
1851
|
+
String(authority.allocation.descriptor.rid) !== String(actorRef.nodeRid)
|
|
1857
1852
|
) {
|
|
1858
1853
|
throw new Error(`Actor '${actorId}' command 44 target authority fence is stale.`);
|
|
1859
1854
|
}
|
|
@@ -1891,8 +1886,10 @@ function relocationDebug(marker: string, detail: Record<string, unknown>): void
|
|
|
1891
1886
|
}
|
|
1892
1887
|
|
|
1893
1888
|
function deferredJoinTerminalKey(root: ZLinkDeferredJoinAcceptedRoot): string {
|
|
1894
|
-
return
|
|
1895
|
-
|
|
1889
|
+
return (
|
|
1890
|
+
`${root.actor.actorId}:${root.actor.objectGeneration.toString()}:` +
|
|
1891
|
+
operationIdentityKey(root.operationId)
|
|
1892
|
+
);
|
|
1896
1893
|
}
|
|
1897
1894
|
|
|
1898
1895
|
function waitForOperation<T>(operation: Promise<T>, signal?: AbortSignal): Promise<T> {
|
|
@@ -1902,11 +1899,11 @@ function waitForOperation<T>(operation: Promise<T>, signal?: AbortSignal): Promi
|
|
|
1902
1899
|
const abort = () => reject(signal.reason);
|
|
1903
1900
|
signal.addEventListener('abort', abort, { once: true });
|
|
1904
1901
|
operation.then(
|
|
1905
|
-
value => {
|
|
1902
|
+
(value) => {
|
|
1906
1903
|
signal.removeEventListener('abort', abort);
|
|
1907
1904
|
resolve(value);
|
|
1908
1905
|
},
|
|
1909
|
-
error => {
|
|
1906
|
+
(error) => {
|
|
1910
1907
|
signal.removeEventListener('abort', abort);
|
|
1911
1908
|
reject(error);
|
|
1912
1909
|
}
|
|
@@ -1918,21 +1915,20 @@ function sameSourceActorAuthority(
|
|
|
1918
1915
|
current: ZLinkAuthoritySnapshot,
|
|
1919
1916
|
expected: ZLinkAuthoritySnapshot
|
|
1920
1917
|
): boolean {
|
|
1921
|
-
return
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
&&
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
=== expected.allocation.descriptorLifecycleGeneration;
|
|
1918
|
+
return (
|
|
1919
|
+
current.storeVersion.value === expected.storeVersion.value &&
|
|
1920
|
+
current.objectGeneration === expected.objectGeneration &&
|
|
1921
|
+
current.authorityOwnerGeneration === expected.authorityOwnerGeneration &&
|
|
1922
|
+
current.ownerId === expected.ownerId &&
|
|
1923
|
+
current.ownerLeaseGeneration === expected.ownerLeaseGeneration &&
|
|
1924
|
+
current.allocation.state === expected.allocation.state &&
|
|
1925
|
+
current.allocation.objectKind === expected.allocation.objectKind &&
|
|
1926
|
+
current.allocation.stableType === expected.allocation.stableType &&
|
|
1927
|
+
current.allocation.descriptor.meshName === expected.allocation.descriptor.meshName &&
|
|
1928
|
+
routingIdsEqual(current.allocation.descriptor.rid, expected.allocation.descriptor.rid) &&
|
|
1929
|
+
current.allocation.descriptorLifecycleGeneration ===
|
|
1930
|
+
expected.allocation.descriptorLifecycleGeneration
|
|
1931
|
+
);
|
|
1936
1932
|
}
|
|
1937
1933
|
|
|
1938
1934
|
async function waitForActorAuthorityRetry(
|