@zlink-systems/framework 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/CoreTypes.d.ts +6 -0
- package/dist/contracts/Common/CoreTypes.js +7 -0
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/index.js +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
- package/dist/contracts/Configuration/InternalDefaults.js +9 -1
- package/dist/contracts/Configuration/Registration.d.ts +13 -2
- package/dist/contracts/Configuration/Registration.js +58 -36
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
- package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
- package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
- package/dist/contracts/Handlers/JsonContract.js +10 -4
- package/dist/contracts/Locations/Authority.d.ts +1 -1
- package/dist/contracts/Locations/Authority.js +3 -2
- package/dist/contracts/Locations/Options.js +1 -1
- package/dist/contracts/Locations/Stores.d.ts +12 -0
- package/dist/contracts/Locations/Stores.js +9 -0
- package/dist/contracts/Spots/Contracts.d.ts +1 -1
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +15 -1
- package/dist/nest-integration.d.ts +4 -2
- package/dist/nest-integration.js +14 -4
- package/dist/runtime/abort.d.ts +1 -0
- package/dist/runtime/abort.js +8 -5
- package/dist/runtime/activation-admission.d.ts +1 -2
- package/dist/runtime/activation-admission.js +2 -6
- package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
- package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
- package/dist/runtime/actors/actor-client.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +42 -143
- package/dist/runtime/actors/actor-context.d.ts +3 -5
- package/dist/runtime/actors/actor-context.js +13 -11
- package/dist/runtime/actors/actor-handoff.d.ts +4 -4
- package/dist/runtime/actors/actor-handoff.js +8 -8
- package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
- package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
- package/dist/runtime/actors/actor-local-native-join.js +83 -105
- package/dist/runtime/actors/actor-native-lookup.js +2 -8
- package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
- package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
- package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
- package/dist/runtime/actors/actor-remote-joiner.js +5 -9
- package/dist/runtime/actors/actor-remote-wire.js +5 -3
- package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
- package/dist/runtime/actors/actor-request-deadline.js +31 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
- package/dist/runtime/actors/deferred-join-completion.js +1 -0
- package/dist/runtime/actors/index.d.ts +9 -7
- package/dist/runtime/actors/index.js +87 -69
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
- package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
- package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
- package/dist/runtime/admission.d.ts +2 -0
- package/dist/runtime/admission.js +7 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
- package/dist/runtime/backend/contracts/index.d.ts +6 -23
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +1 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -6
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.js +40 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +3 -2
- package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/runtime-values.d.ts +4 -1
- package/dist/runtime/backend/runtime-values.js +2 -0
- package/dist/runtime/channels/channel-clients.d.ts +20 -8
- package/dist/runtime/channels/channel-clients.js +68 -52
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.js +47 -29
- package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
- package/dist/runtime/channels/channel-outbound-operations.js +9 -10
- package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
- package/dist/runtime/channels/channel-receive-loops.js +27 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
- package/dist/runtime/channels/channel-runtime-manager.js +5 -2
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
- package/dist/runtime/channels/channel-socket-registry.js +248 -174
- package/dist/runtime/channels/channel-transports.d.ts +11 -17
- package/dist/runtime/channels/channel-transports.js +68 -47
- package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/client-server-location-runtime.js +10 -11
- package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
- package/dist/runtime/channels/client-server-service-wire.js +32 -11
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
- package/dist/runtime/channels/fanout-location-runtime.js +130 -72
- package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
- package/dist/runtime/channels/spot-direct-envelope.js +4 -3
- package/dist/runtime/channels/spot-node-route-transport.js +3 -2
- package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
- package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
- package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
- package/dist/runtime/diagnostics/flow-context.js +16 -2
- package/dist/runtime/diagnostics/index.d.ts +4 -2
- package/dist/runtime/diagnostics/index.js +14 -4
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
- package/dist/runtime/diagnostics/message-flow.js +10 -19
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
- package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
- package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
- package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
- package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
- package/dist/runtime/disposal.d.ts +5 -0
- package/dist/runtime/disposal.js +22 -0
- package/dist/runtime/execution/index.d.ts +12 -9
- package/dist/runtime/execution/index.js +58 -14
- package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
- package/dist/runtime/execution/serial-execution-queue.js +54 -15
- package/dist/runtime/execution/state-lane.d.ts +8 -1
- package/dist/runtime/execution/state-lane.js +118 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
- package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
- package/dist/runtime/foundation/event-loop-resources.js +6 -119
- package/dist/runtime/foundation/operation-identity.d.ts +2 -0
- package/dist/runtime/foundation/operation-identity.js +9 -5
- package/dist/runtime/foundation/operation-registry.d.ts +5 -7
- package/dist/runtime/foundation/operation-registry.js +34 -44
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +62 -83
- package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
- package/dist/runtime/foundation/runtime-state-projections.js +8 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +22 -3
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
- package/dist/runtime/foundation/service-liveness-registry.js +2 -1
- package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
- package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
- package/dist/runtime/foundation/service-metadata-codec.js +3 -3
- package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
- package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
- package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
- package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +10 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
- package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
- package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
- package/dist/runtime/foundation/service-topology-registry.js +17 -32
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
- package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
- package/dist/runtime/foundation/service-wire-codec.js +10 -8
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
- package/dist/runtime/framework-errors-internal.d.ts +2 -1
- package/dist/runtime/framework-errors-internal.js +343 -122
- package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
- package/dist/runtime/handlers/handler-instance-scope.js +61 -74
- package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
- package/dist/runtime/host/actor-packet-relay.js +48 -91
- package/dist/runtime/host/actor-placement-coordinator.js +7 -5
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
- package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
- package/dist/runtime/host/actor-transfer-runtime.js +143 -176
- package/dist/runtime/host/application-job-queue.js +16 -33
- package/dist/runtime/host/bound-session-relay.js +1 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
- package/dist/runtime/host/index.d.ts +14 -13
- package/dist/runtime/host/index.js +190 -157
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
- package/dist/runtime/host/instance-activation-authority.js +17 -45
- package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
- package/dist/runtime/host/location-runtime-owner.js +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
- package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
- package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
- package/dist/runtime/host/remote-bound-session-relay.js +7 -20
- package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
- package/dist/runtime/host/route-mesh-runtime.js +171 -252
- package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
- package/dist/runtime/host/runtime-shutdown.js +18 -21
- package/dist/runtime/host/service-relocation-control.js +6 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
- package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
- package/dist/runtime/host/spot-address-transport.d.ts +2 -3
- package/dist/runtime/host/spot-address-transport.js +34 -136
- package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
- package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
- package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
- package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
- package/dist/runtime/locations/authority-key-codec.js +4 -3
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
- package/dist/runtime/locations/creation-operation-id.js +6 -4
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
- package/dist/runtime/locations/in-memory-authority-store.js +31 -15
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +17 -14
- package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
- package/dist/runtime/locations/key-codec.js +3 -2
- package/dist/runtime/locations/lease-tracker.d.ts +3 -5
- package/dist/runtime/locations/lease-tracker.js +7 -11
- package/dist/runtime/locations/lifecycle.d.ts +4 -9
- package/dist/runtime/locations/lifecycle.js +2 -31
- package/dist/runtime/locations/location-store-failure.d.ts +2 -0
- package/dist/runtime/locations/location-store-failure.js +7 -0
- package/dist/runtime/locations/location-store-pages.d.ts +3 -0
- package/dist/runtime/locations/location-store-pages.js +13 -0
- package/dist/runtime/locations/location-store-repository.d.ts +5 -7
- package/dist/runtime/locations/location-store-repository.js +303 -332
- package/dist/runtime/locations/relocation-blob.js +18 -5
- package/dist/runtime/locations/resolvers.d.ts +5 -5
- package/dist/runtime/locations/resolvers.js +37 -28
- package/dist/runtime/locations/runtime.d.ts +5 -4
- package/dist/runtime/locations/runtime.js +123 -92
- package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
- package/dist/runtime/locations/spot-location-claims.js +42 -1
- package/dist/runtime/messaging/payload-codec.js +26 -20
- package/dist/runtime/messaging/submission-result.d.ts +3 -0
- package/dist/runtime/messaging/submission-result.js +48 -0
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
- package/dist/runtime/spots/index.d.ts +14 -20
- package/dist/runtime/spots/index.js +302 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
- package/dist/runtime/spots/spot-activation-registry.js +14 -50
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +2 -2
- package/dist/runtime/spots/spot-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-activation.js +49 -32
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
- package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
- package/dist/runtime/spots/spot-actor-membership.js +22 -45
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
- package/dist/runtime/spots/spot-context.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +9 -20
- package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
- package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
- package/dist/runtime/spots/spot-manager-public.js +5 -4
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
- package/dist/runtime/spots/spot-outbound.d.ts +4 -3
- package/dist/runtime/spots/spot-outbound.js +9 -8
- package/dist/runtime/spots/spot-remote-codec.js +5 -3
- package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
- package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
- package/dist/runtime/spots/spot-route-replies.js +3 -1
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
- package/dist/runtime/spots/spot-serial-executor.js +2 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
- package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +11 -1
- package/dist/runtime/streams/index.d.ts +14 -15
- package/dist/runtime/streams/index.js +20 -21
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +17 -8
- package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
- package/dist/runtime/streams/protocol.d.ts +6 -33
- package/dist/runtime/streams/protocol.js +38 -110
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
- package/dist/runtime/streams/session-actor-coordinator.js +12 -4
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +5 -4
- package/dist/runtime/streams/session-context.d.ts +6 -6
- package/dist/runtime/streams/session-context.js +22 -4
- package/dist/runtime/streams/session-requests.js +2 -1
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
- package/dist/runtime/streams/stream-frame-factory.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
- package/dist/runtime/streams/stream-session-runtime.js +25 -33
- package/dist/runtime/workers/index.d.ts +2 -2
- package/dist/runtime/workers/index.js +5 -4
- package/package.json +3 -3
- package/src/contracts/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Configuration/InternalDefaults.ts +12 -0
- package/src/contracts/Configuration/Registration.ts +92 -48
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Handlers/JsonContract.ts +14 -4
- package/src/contracts/Locations/Authority.ts +7 -3
- package/src/contracts/Locations/Options.ts +1 -1
- package/src/contracts/Locations/Stores.ts +14 -0
- package/src/contracts/Spots/Contracts.ts +1 -1
- package/src/internal.ts +14 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +2 -8
- package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
- package/src/runtime/actors/actor-client.ts +77 -204
- package/src/runtime/actors/actor-context.ts +39 -33
- package/src/runtime/actors/actor-handoff.ts +24 -22
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +172 -174
- package/src/runtime/actors/actor-native-lookup.ts +2 -9
- package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
- package/src/runtime/actors/actor-remote-joiner.ts +9 -11
- package/src/runtime/actors/actor-remote-wire.ts +5 -3
- package/src/runtime/actors/actor-request-deadline.ts +49 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- package/src/runtime/actors/actor-runtime-state.ts +85 -247
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +10 -6
- package/src/runtime/actors/index.ts +100 -79
- package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
- package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
- package/src/runtime/admission.ts +8 -1
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +13 -29
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-support.ts +23 -6
- package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +41 -20
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +3 -2
- package/src/runtime/backend/raw-binding-port.ts +1 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +132 -85
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +58 -29
- package/src/runtime/channels/channel-outbound-operations.ts +10 -23
- package/src/runtime/channels/channel-receive-loops.ts +39 -7
- package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
- package/src/runtime/channels/channel-runtime-manager.ts +6 -2
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +301 -192
- package/src/runtime/channels/channel-transports.ts +161 -112
- package/src/runtime/channels/client-server-location-runtime.ts +17 -17
- package/src/runtime/channels/client-server-service-wire.ts +40 -12
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
- package/src/runtime/channels/fanout-location-runtime.ts +172 -91
- package/src/runtime/channels/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +5 -2
- package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
- package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
- package/src/runtime/diagnostics/flow-context.ts +16 -2
- package/src/runtime/diagnostics/index.ts +27 -17
- package/src/runtime/diagnostics/message-flow.ts +15 -25
- package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
- package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
- package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
- package/src/runtime/disposal.ts +19 -0
- package/src/runtime/execution/index.ts +60 -20
- package/src/runtime/execution/serial-execution-queue.ts +131 -18
- package/src/runtime/execution/state-lane.ts +142 -4
- package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
- package/src/runtime/foundation/event-loop-resources.ts +5 -122
- package/src/runtime/foundation/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +110 -111
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
- package/src/runtime/foundation/service-discovery-registry.ts +32 -3
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
- package/src/runtime/foundation/service-liveness-registry.ts +2 -1
- package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
- package/src/runtime/foundation/service-metadata-codec.ts +2 -2
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
- package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
- package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
- package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
- package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
- package/src/runtime/foundation/service-topology-registry.ts +23 -32
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
- package/src/runtime/foundation/service-wire-codec.ts +15 -8
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
- package/src/runtime/framework-errors-internal.ts +380 -134
- package/src/runtime/handlers/handler-instance-scope.ts +68 -95
- package/src/runtime/host/actor-packet-relay.ts +57 -147
- package/src/runtime/host/actor-placement-coordinator.ts +8 -5
- package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
- package/src/runtime/host/actor-transfer-runtime.ts +180 -260
- package/src/runtime/host/application-job-queue.ts +28 -34
- package/src/runtime/host/bound-session-relay.ts +1 -2
- package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
- package/src/runtime/host/index.ts +327 -296
- package/src/runtime/host/instance-activation-authority.ts +89 -109
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
- package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
- package/src/runtime/host/remote-bound-session-relay.ts +8 -41
- package/src/runtime/host/route-mesh-runtime.ts +228 -271
- package/src/runtime/host/runtime-shutdown.ts +17 -21
- package/src/runtime/host/service-relocation-control.ts +14 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
- package/src/runtime/host/spot-address-transport.ts +73 -195
- package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
- package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
- package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
- package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
- package/src/runtime/locations/authority-key-codec.ts +7 -3
- package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
- package/src/runtime/locations/creation-operation-id.ts +6 -3
- package/src/runtime/locations/domain-store-contract.ts +12 -3
- package/src/runtime/locations/in-memory-authority-store.ts +44 -15
- package/src/runtime/locations/in-memory-location-store.ts +50 -39
- package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +13 -43
- package/src/runtime/locations/location-store-failure.ts +4 -0
- package/src/runtime/locations/location-store-pages.ts +18 -0
- package/src/runtime/locations/location-store-repository.ts +450 -478
- package/src/runtime/locations/relocation-blob.ts +17 -6
- package/src/runtime/locations/resolvers.ts +75 -49
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +58 -1
- package/src/runtime/messaging/payload-codec.ts +35 -24
- package/src/runtime/messaging/submission-result.ts +57 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
- package/src/runtime/spots/index.ts +433 -229
- package/src/runtime/spots/spot-activation-registry.ts +30 -69
- package/src/runtime/spots/spot-activation-state.ts +2 -2
- package/src/runtime/spots/spot-activation.ts +67 -37
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
- package/src/runtime/spots/spot-actor-membership.ts +40 -72
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
- package/src/runtime/spots/spot-context.ts +3 -3
- package/src/runtime/spots/spot-entry-activation.ts +13 -30
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +21 -17
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
- package/src/runtime/spots/spot-outbound.ts +45 -23
- package/src/runtime/spots/spot-remote-codec.ts +7 -3
- package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
- package/src/runtime/spots/spot-route-replies.ts +6 -4
- package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +5 -27
- package/src/runtime/spots/spot-serial-executor.ts +2 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
- package/src/runtime/streams/bound-session-service.ts +21 -1
- package/src/runtime/streams/index.ts +76 -64
- package/src/runtime/streams/managed-stream.ts +29 -10
- package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
- package/src/runtime/streams/protocol.ts +34 -88
- package/src/runtime/streams/session-actor-coordinator.ts +17 -5
- package/src/runtime/streams/session-calls.ts +6 -5
- package/src/runtime/streams/session-context.ts +54 -10
- package/src/runtime/streams/session-requests.ts +2 -1
- package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
- package/src/runtime/streams/stream-frame-factory.ts +2 -3
- package/src/runtime/streams/stream-session-runtime.ts +57 -59
- package/src/runtime/workers/index.ts +13 -12
- package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
- package/dist/runtime/actors/post-commit-actor-location.js +0 -72
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
- package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
- package/src/runtime/actors/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -5,36 +5,50 @@ exports.decodeQueuedHandoffPacket = decodeQueuedHandoffPacket;
|
|
|
5
5
|
exports.createServiceRelocationId = createServiceRelocationId;
|
|
6
6
|
exports.relocationFailedFailureCode = relocationFailedFailureCode;
|
|
7
7
|
exports.encodeHandoffQueuedMessages = encodeHandoffQueuedMessages;
|
|
8
|
+
const stream_wire_1 = require("@zlink-systems/stream-wire");
|
|
8
9
|
const node_crypto_1 = require("node:crypto");
|
|
9
|
-
const runtime_values_1 = require("../backend/runtime-values");
|
|
10
10
|
const contracts_1 = require("../../contracts");
|
|
11
11
|
const Options_1 = require("../../contracts/Locations/Options");
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
12
|
+
const Stores_1 = require("../../contracts/Locations/Stores");
|
|
13
|
+
const actor_authority_publication_1 = require("../actors/actor-authority-publication");
|
|
14
|
+
const actor_handoff_1 = require("../actors/actor-handoff");
|
|
15
|
+
const actor_remote_wire_1 = require("../actors/actor-remote-wire");
|
|
16
|
+
const actor_runtime_state_1 = require("../actors/actor-runtime-state");
|
|
17
|
+
const runtime_values_1 = require("../backend/runtime-values");
|
|
18
|
+
const diagnostics_1 = require("../diagnostics");
|
|
19
|
+
const runtime_metrics_1 = require("../diagnostics/runtime-metrics");
|
|
20
|
+
const state_lane_1 = require("../execution/state-lane");
|
|
21
|
+
const actor_join_recovery_codec_1 = require("../foundation/actor-join-recovery-codec");
|
|
22
|
+
const operation_identity_1 = require("../foundation/operation-identity");
|
|
23
|
+
const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
|
|
20
24
|
const service_maintenance_runtime_1 = require("../foundation/service-maintenance-runtime");
|
|
21
|
-
const service_relocation_object_owner_1 = require("../foundation/service-relocation-object-owner");
|
|
22
25
|
const service_relocation_aggregate_committer_1 = require("../foundation/service-relocation-aggregate-committer");
|
|
26
|
+
const service_relocation_coordinator_1 = require("../foundation/service-relocation-coordinator");
|
|
27
|
+
const service_relocation_object_owner_1 = require("../foundation/service-relocation-object-owner");
|
|
28
|
+
const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
|
|
29
|
+
const service_runtime_contracts_1 = require("../foundation/service-runtime-contracts");
|
|
30
|
+
const service_stateful_wire_codec_1 = require("../foundation/service-stateful-wire-codec");
|
|
31
|
+
const service_wire_constants_generated_1 = require("../foundation/service-wire-constants.generated");
|
|
32
|
+
const service_wire_m6a_codec_1 = require("../foundation/service-wire-m6a-codec");
|
|
33
|
+
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
34
|
+
const authority_key_codec_1 = require("../locations/authority-key-codec");
|
|
35
|
+
const location_store_failure_1 = require("../locations/location-store-failure");
|
|
36
|
+
const routing_id_1 = require("../routing-id");
|
|
23
37
|
const spot_provider_1 = require("../spots/spot-provider");
|
|
24
|
-
const actor_runtime_state_1 = require("../actors/actor-runtime-state");
|
|
25
|
-
const actor_handoff_1 = require("../actors/actor-handoff");
|
|
26
38
|
const spot_remote_codec_1 = require("../spots/spot-remote-codec");
|
|
27
|
-
const actor_authority_publication_1 = require("../actors/actor-authority-publication");
|
|
28
|
-
const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
|
|
29
39
|
const actor_transfer_runtime_1 = require("./actor-transfer-runtime");
|
|
30
|
-
const authority_key_codec_1 = require("../locations/authority-key-codec");
|
|
31
|
-
const service_relocation_control_1 = require("./service-relocation-control");
|
|
32
|
-
const service_stateful_wire_codec_1 = require("../foundation/service-stateful-wire-codec");
|
|
33
|
-
const service_wire_constants_generated_1 = require("../foundation/service-wire-constants.generated");
|
|
34
40
|
const bounded_replay_map_1 = require("./bounded-replay-map");
|
|
41
|
+
const relocation_direct_transfer_1 = require("./relocation-direct-transfer");
|
|
35
42
|
const relocation_integrity_fault_gate_1 = require("./relocation-integrity-fault-gate");
|
|
36
|
-
const
|
|
37
|
-
const
|
|
43
|
+
const relocation_state_adapter_1 = require("./relocation-state-adapter");
|
|
44
|
+
const service_relocation_control_1 = require("./service-relocation-control");
|
|
45
|
+
const RELOCATION_ATTEMPT_TIMEOUT_MS = 250;
|
|
46
|
+
const RELOCATION_AUTHORITY_RETRY_DELAY_MS = 25;
|
|
47
|
+
const RELOCATION_MAX_SEND_ATTEMPTS = 120;
|
|
48
|
+
const RELOCATION_AUTHORITY_POLL_INTERVAL_MS = 10;
|
|
49
|
+
const RELOCATION_RESEND_DELAY_MS = 250;
|
|
50
|
+
const RELOCATION_ABORTABLE_OPERATION_TIMEOUT_MS = 24 * 60 * 60 * 1000;
|
|
51
|
+
const RELOCATION_OPERATION_TIMEOUT_MS = 30_000;
|
|
38
52
|
class ZLinkRelocationStateIncompatibleError extends Error {
|
|
39
53
|
constructor(message) {
|
|
40
54
|
super(message);
|
|
@@ -68,8 +82,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
68
82
|
* Terminal restore failures (assembly/checksum/factory/restore error): the
|
|
69
83
|
* target already sent relocationFailed (command 53) once. An exact-identity
|
|
70
84
|
* Prepare resend replays the stored response rather than retrying the
|
|
71
|
-
* restore
|
|
72
|
-
* key supersedes the stale entry (spec 28 §3, §9).
|
|
85
|
+
* restore. A different exact identity never changes this entry (spec 28 §4.3).
|
|
73
86
|
*/
|
|
74
87
|
targetReadyFailures = new Map();
|
|
75
88
|
/**
|
|
@@ -109,8 +122,13 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
109
122
|
}
|
|
110
123
|
this.reserveExactRelocationId(input.relocationId);
|
|
111
124
|
let resolveReady;
|
|
112
|
-
const ready = new Promise((resolve) => {
|
|
113
|
-
resolveReady =
|
|
125
|
+
const ready = new Promise((resolve, reject) => {
|
|
126
|
+
resolveReady = (failure) => {
|
|
127
|
+
if (failure === undefined)
|
|
128
|
+
resolve();
|
|
129
|
+
else
|
|
130
|
+
reject(failure.cause);
|
|
131
|
+
};
|
|
114
132
|
});
|
|
115
133
|
this.sourceActorJoinProfiles.set(input.relocationId, {
|
|
116
134
|
actor: input.actor,
|
|
@@ -121,8 +139,8 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
121
139
|
targetNodeRid: input.target.targetNodeRid,
|
|
122
140
|
relocationContentType: this.actorRegistration(input.state.meshName ?? input.meshName, input.state.actorType ?? '')
|
|
123
141
|
.relocation.kind === 'snapshot'
|
|
124
|
-
?
|
|
125
|
-
:
|
|
142
|
+
? actor_join_recovery_codec_1.SNAPSHOT_RELOCATION_CONTENT_TYPE
|
|
143
|
+
: actor_join_recovery_codec_1.RECREATE_RELOCATION_CONTENT_TYPE,
|
|
126
144
|
completionOperationId: input.completionOperationId,
|
|
127
145
|
canonicalRecovery: input.canonicalRecovery,
|
|
128
146
|
ready,
|
|
@@ -141,8 +159,14 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
141
159
|
resolveReady();
|
|
142
160
|
}
|
|
143
161
|
catch (error) {
|
|
144
|
-
|
|
145
|
-
|
|
162
|
+
if (error instanceof service_relocation_coordinator_1.ServiceRelocationPostCommitError) {
|
|
163
|
+
resolveReady(error);
|
|
164
|
+
this.completeActorJoinSourceCleanup(input.state.actorId);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.sourceActorJoinProfiles.delete(input.relocationId);
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
146
170
|
}
|
|
147
171
|
return {
|
|
148
172
|
actorRef: {
|
|
@@ -157,20 +181,11 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
157
181
|
async dispose() {
|
|
158
182
|
this.disposed = true;
|
|
159
183
|
const errors = [];
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
await stage.finalize;
|
|
166
|
-
}
|
|
167
|
-
else if (stage.phase === 'ready') {
|
|
168
|
-
await this.abortTargetStage(stage);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
errors.push(error);
|
|
173
|
-
}
|
|
184
|
+
try {
|
|
185
|
+
await this.drainTargetAttempts();
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
errors.push(error);
|
|
174
189
|
}
|
|
175
190
|
this.targetStages.clear();
|
|
176
191
|
this.terminalTargets.clear();
|
|
@@ -213,22 +228,67 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
213
228
|
if (errors.length > 1)
|
|
214
229
|
throw new AggregateError(errors, 'Relocation runtime stop failed.');
|
|
215
230
|
}
|
|
231
|
+
/** Host shutdown waits for the existing attempt terminal before releasing its lease. */
|
|
232
|
+
async drainTargetAttempts() {
|
|
233
|
+
const results = await Promise.allSettled([...this.targetStages.entries()].map(([stagingId, stage]) => {
|
|
234
|
+
if (stage.fallback !== undefined)
|
|
235
|
+
clearTimeout(stage.fallback);
|
|
236
|
+
return stage.lane.finally(() => {
|
|
237
|
+
if (stage.phase === 'failed')
|
|
238
|
+
return stage.finalize;
|
|
239
|
+
if (this.targetStageSealed(stage)) {
|
|
240
|
+
const terminal = this.discardTargetStage(stagingId, stage);
|
|
241
|
+
stage.finalize = terminal;
|
|
242
|
+
return terminal;
|
|
243
|
+
}
|
|
244
|
+
return this.beginTargetFinalize(stage.offer.reservation.prepared.plan.targetDescriptor.meshName, stagingId, stage);
|
|
245
|
+
});
|
|
246
|
+
}));
|
|
247
|
+
const errors = results.flatMap((result) => result.status === 'rejected' ? [result.reason] : []);
|
|
248
|
+
if (errors.length === 1)
|
|
249
|
+
throw errors[0];
|
|
250
|
+
if (errors.length > 1)
|
|
251
|
+
throw new AggregateError(errors, 'Relocation target drain failed.');
|
|
252
|
+
}
|
|
253
|
+
/** Spec 28 §4.4: the target owner alone orders shutdown seal and verified cutover. */
|
|
254
|
+
targetStageSealed(stage) {
|
|
255
|
+
return (!stage.cutoverReceived && (this.disposed || this.options.targetAdmissionSealed?.() === true));
|
|
256
|
+
}
|
|
216
257
|
completeActorJoinSourceCleanup(actorId) {
|
|
217
258
|
for (const [relocationId, profile] of this.sourceActorJoinProfiles) {
|
|
218
259
|
if (profile.state.actorId !== actorId)
|
|
219
260
|
continue;
|
|
220
261
|
this.sourceActorJoinProfiles.delete(relocationId);
|
|
221
262
|
this.terminalActorJoinSourceLeaves.remember(relocationId, actorId);
|
|
222
|
-
void profile
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
263
|
+
void this.finalizeActorJoinSource(profile);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async finalizeActorJoinSource(profile) {
|
|
267
|
+
const failures = [];
|
|
268
|
+
try {
|
|
269
|
+
await profile.ready;
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
failures.push(error);
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
await this.options.actorTransfer.completeRelocationSourceLeave(profile.actor, profile.sourceSpotId);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
failures.push(error);
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
await this.options
|
|
282
|
+
.actorManager()
|
|
283
|
+
?.completeRelocationSource(profile.state.actorId, profile.sourceActorRef);
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
failures.push(error);
|
|
287
|
+
}
|
|
288
|
+
if (failures.length > 0) {
|
|
289
|
+
console.error('[zlink.runtime.relocation.source_cleanup_failed]', failures.length === 1
|
|
290
|
+
? failures[0]
|
|
291
|
+
: new AggregateError(failures, 'Actor source retirement failed.'));
|
|
232
292
|
}
|
|
233
293
|
}
|
|
234
294
|
async relocateMesh(meshName, targetApplicationVersion, signal, stopStartingSignal) {
|
|
@@ -305,13 +365,18 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
305
365
|
ready: () => true,
|
|
306
366
|
relocate: (relocationSignal) => {
|
|
307
367
|
const run = unit.relocate(relocationSignal);
|
|
368
|
+
if ((0, state_lane_1.isStructuralGuardEnabled)()) {
|
|
369
|
+
(0, state_lane_1.trackDiagnosticCompletion)(run, `relocation ${unit.id}`);
|
|
370
|
+
}
|
|
308
371
|
started.push(run);
|
|
309
372
|
return run;
|
|
310
373
|
}
|
|
311
374
|
});
|
|
312
375
|
}
|
|
313
376
|
const operationSignal = signal ?? new AbortController().signal;
|
|
314
|
-
const deadlineMs = signal === undefined
|
|
377
|
+
const deadlineMs = signal === undefined
|
|
378
|
+
? RELOCATION_OPERATION_TIMEOUT_MS
|
|
379
|
+
: RELOCATION_ABORTABLE_OPERATION_TIMEOUT_MS;
|
|
315
380
|
let failure;
|
|
316
381
|
try {
|
|
317
382
|
const result = await raceAbort(maintenance.start('retire', deadlineMs, stopStartingSignal, operationSignal), operationSignal);
|
|
@@ -400,41 +465,50 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
400
465
|
}
|
|
401
466
|
const operationKey = relocationStagingId(request);
|
|
402
467
|
const fingerprint = stringifyWire(request);
|
|
468
|
+
const readyFailure = this.targetReadyFailures.get(operationKey);
|
|
469
|
+
const readyPending = this.targetReadyResponses.get(operationKey);
|
|
470
|
+
let operation = this.targetPrepareOperations.get(operationKey);
|
|
471
|
+
const acceptedFingerprint = readyFailure?.fingerprint ??
|
|
472
|
+
readyPending?.fingerprint ??
|
|
473
|
+
operation?.fingerprint ??
|
|
474
|
+
this.targetAssemblies.get(operationKey)?.fingerprint ??
|
|
475
|
+
this.targetStages.get(operationKey)?.offer.prepareFingerprint ??
|
|
476
|
+
this.terminalTargets.get(operationKey);
|
|
477
|
+
if (request.sourceNodeRid !== String(record.sourceNodeRid))
|
|
478
|
+
return true;
|
|
479
|
+
if (acceptedFingerprint !== undefined && acceptedFingerprint !== fingerprint) {
|
|
480
|
+
if (!samePrepareIdentity(acceptedFingerprint, request))
|
|
481
|
+
return true;
|
|
482
|
+
this.replyPrepare(record, relocationFailed(request, service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.relocationDataLost));
|
|
483
|
+
return true;
|
|
484
|
+
}
|
|
403
485
|
// A restore that failed outright is terminal: the source observes the
|
|
404
486
|
// same explicit relocationFailed on every identical Prepare resend
|
|
405
|
-
// rather than a silent stall.
|
|
406
|
-
// same RelocationId+attempt key supersedes the stale failure — the
|
|
407
|
-
// newer attempt wins (spec 28 §3).
|
|
408
|
-
const readyFailure = this.targetReadyFailures.get(operationKey);
|
|
487
|
+
// rather than a silent stall.
|
|
409
488
|
if (readyFailure !== undefined) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return true;
|
|
413
|
-
}
|
|
414
|
-
this.targetReadyFailures.delete(operationKey);
|
|
489
|
+
this.replyPrepare(record, readyFailure.response);
|
|
490
|
+
return true;
|
|
415
491
|
}
|
|
416
492
|
// Spec 28: an exact-identity Restore resend against staging that
|
|
417
493
|
// already restored successfully reuses that staging — it re-submits
|
|
418
494
|
// READY rather than restarting the restore.
|
|
419
|
-
const readyPending = this.targetReadyResponses.get(operationKey);
|
|
420
495
|
if (readyPending !== undefined) {
|
|
421
|
-
if (readyPending.fingerprint !== fingerprint) {
|
|
422
|
-
throw new Error(`Relocation '${operationKey}' repeated Prepare with different bytes.`);
|
|
423
|
-
}
|
|
424
496
|
this.submitTargetReady(meshName, operationKey, record, readyPending.response);
|
|
425
497
|
return true;
|
|
426
498
|
}
|
|
427
|
-
let operation = this.targetPrepareOperations.get(operationKey);
|
|
428
|
-
if (operation !== undefined && operation.fingerprint !== fingerprint) {
|
|
429
|
-
throw new Error(`Relocation '${operationKey}' repeated Prepare with different bytes.`);
|
|
430
|
-
}
|
|
431
499
|
if (operation === undefined) {
|
|
432
500
|
// The prepare turn must not block the ordered dispatch lane: the
|
|
433
501
|
// payload chunks that complete this operation arrive as later records
|
|
434
502
|
// on the same connection. Register the assembly synchronously, then
|
|
435
503
|
// finish the restore and the Ready reply asynchronously.
|
|
436
|
-
|
|
437
|
-
|
|
504
|
+
let promise;
|
|
505
|
+
try {
|
|
506
|
+
this.registerTargetAssembly(operationKey, request, String(record.sourceNodeRid));
|
|
507
|
+
promise = this.handlePrepareControl(meshName, operationKey, request, record.sourceNodeRid, signal);
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
promise = Promise.reject(error);
|
|
511
|
+
}
|
|
438
512
|
operation = { fingerprint, promise };
|
|
439
513
|
this.targetPrepareOperations.set(operationKey, operation);
|
|
440
514
|
void promise
|
|
@@ -462,7 +536,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
462
536
|
// restore or staging): this is terminal. Send relocationFailed
|
|
463
537
|
// (command 53) once and remember it so an identical Prepare resend
|
|
464
538
|
// replays the same response instead of retrying the restore.
|
|
465
|
-
const failed = relocationFailed(request, relocationFailedFailureCode(error
|
|
539
|
+
const failed = relocationFailed(request, relocationFailedFailureCode(error));
|
|
466
540
|
this.targetReadyFailures.set(operationKey, {
|
|
467
541
|
fingerprint: stringifyWire(request),
|
|
468
542
|
response: failed
|
|
@@ -543,7 +617,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
543
617
|
String(sourceNodeRid) !== pending.authenticatedSourceNodeRid ||
|
|
544
618
|
request.senderRole !== 'source' ||
|
|
545
619
|
!sameCoordinator(request.coordinator, pending.prepare.coordinator) ||
|
|
546
|
-
|
|
620
|
+
!sameRelocationObject(request.object, pending.prepare.object)) {
|
|
547
621
|
// Spec 28 §4.3 — a chunk with a different exact identity is never
|
|
548
622
|
// attached to an in-progress assembly; it is discarded.
|
|
549
623
|
console.warn('[zlink.runtime.relocation.stale_state_chunk]', operationKey);
|
|
@@ -562,12 +636,6 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
562
636
|
registerTargetAssembly(operationKey, request, authenticatedSourceNodeRid) {
|
|
563
637
|
const existing = this.targetAssemblies.get(operationKey);
|
|
564
638
|
if (existing !== undefined) {
|
|
565
|
-
if (existing.fingerprint !== stringifyWire(request)) {
|
|
566
|
-
// Same exact identity with a different declared length or checksum is
|
|
567
|
-
// an explicit conflict failure; the existing assembly is neither
|
|
568
|
-
// reused nor overwritten (spec 28 §4.3).
|
|
569
|
-
throw existing.assembly.fail(`Relocation '${operationKey}' repeated Prepare with a conflicting manifest.`);
|
|
570
|
-
}
|
|
571
639
|
return existing;
|
|
572
640
|
}
|
|
573
641
|
const pending = {
|
|
@@ -578,12 +646,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
578
646
|
};
|
|
579
647
|
this.targetAssemblies.set(operationKey, pending);
|
|
580
648
|
if (this.relocationIntegrityFaultGate()?.consumeIdentityConflict() === true) {
|
|
581
|
-
|
|
582
|
-
// conflict branch so existing staging is neither reused nor overwritten.
|
|
583
|
-
return this.registerTargetAssembly(operationKey, {
|
|
584
|
-
...request,
|
|
585
|
-
payloadChecksumCrc32c: request.payloadChecksumCrc32c ^ 1
|
|
586
|
-
}, authenticatedSourceNodeRid);
|
|
649
|
+
throw new ServiceRelocationDataLostError(pending.assembly.fail(`Relocation '${operationKey}' repeated Prepare with a conflicting manifest.`).message);
|
|
587
650
|
}
|
|
588
651
|
return pending;
|
|
589
652
|
}
|
|
@@ -710,7 +773,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
710
773
|
return;
|
|
711
774
|
}
|
|
712
775
|
if (this.pendingSessionRelocations.get(key) === pending) {
|
|
713
|
-
pending.retryTimer = setTimeout(() => void send(),
|
|
776
|
+
pending.retryTimer = setTimeout(() => void send(), RELOCATION_RESEND_DELAY_MS);
|
|
714
777
|
}
|
|
715
778
|
}
|
|
716
779
|
catch (error) {
|
|
@@ -848,7 +911,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
848
911
|
}
|
|
849
912
|
}
|
|
850
913
|
async relocateSpotAggregate(meshName, activation, kind, actorStates, target, targetApplicationVersion, signal) {
|
|
851
|
-
await activation.serial.
|
|
914
|
+
await activation.serial.executeControlLifecycleOperation(() => this.relocateSpotAggregateCore(meshName, activation, kind, actorStates, target, targetApplicationVersion, signal));
|
|
852
915
|
}
|
|
853
916
|
async relocateSpotAggregateCore(meshName, activation, kind, actorStates, target, targetApplicationVersion, signal) {
|
|
854
917
|
const store = this.requireLocationStore();
|
|
@@ -915,34 +978,64 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
915
978
|
},
|
|
916
979
|
captureApplicationState: (captureSignal) => this.captureApplication(spotRegistration.relocation, activation.spot, captureSignal),
|
|
917
980
|
commitSeal: async () => {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
981
|
+
const failures = [];
|
|
982
|
+
try {
|
|
983
|
+
if (!spotSealCommitted) {
|
|
984
|
+
if (spotCapture === undefined || !(await activation.commitRelocation(spotCapture))) {
|
|
985
|
+
throw new Error(`Spot '${String(activation.spotId)}' relocation seal became stale.`);
|
|
986
|
+
}
|
|
987
|
+
spotSealCommitted = true;
|
|
988
|
+
}
|
|
989
|
+
if (spotMessageFollowSeal !== undefined) {
|
|
990
|
+
await this.commitSpotMessageFollow(meshName, spotMessageFollowSeal, spotKey, activation, target);
|
|
921
991
|
}
|
|
922
|
-
spotSealCommitted = true;
|
|
923
992
|
}
|
|
924
|
-
|
|
925
|
-
|
|
993
|
+
catch (error) {
|
|
994
|
+
failures.push(error);
|
|
926
995
|
}
|
|
927
996
|
for (const session of sessions) {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
997
|
+
try {
|
|
998
|
+
const committedAuthority = await requireAuthority(this.requireLocationStore(), (0, authority_key_codec_1.encodeAuthorityKey)('actor', session.state.actorId));
|
|
999
|
+
const targetActorRef = {
|
|
1000
|
+
actorId: session.state.actorId,
|
|
1001
|
+
objectGeneration: actorAuthorities.get(session.state.actorId).objectGeneration,
|
|
1002
|
+
meshName,
|
|
1003
|
+
nodeRid: target.rid
|
|
1004
|
+
};
|
|
1005
|
+
await session.prepared.commit({
|
|
1006
|
+
routerChannelId: meshName,
|
|
1007
|
+
targetNodeRid: target.rid,
|
|
1008
|
+
spotId: activation.spotId,
|
|
1009
|
+
spotKind: kind === 'user_spot' ? contracts_1.ZLinkSpotKind.User : contracts_1.ZLinkSpotKind.Instance,
|
|
1010
|
+
authorityOwnerGeneration: committedAuthority.authorityOwnerGeneration
|
|
1011
|
+
}, targetActorRef, (0, actor_transfer_runtime_1.committedActorOwnerFence)(session.state.actorId, targetActorRef, committedAuthority));
|
|
1012
|
+
}
|
|
1013
|
+
catch (error) {
|
|
1014
|
+
failures.push(error);
|
|
1015
|
+
}
|
|
1016
|
+
try {
|
|
1017
|
+
activation.commitActorDeparture(session.state.actorId);
|
|
1018
|
+
}
|
|
1019
|
+
catch (error) {
|
|
1020
|
+
failures.push(error);
|
|
1021
|
+
}
|
|
1022
|
+
try {
|
|
1023
|
+
await this.requireActorManager().completeRelocationSource(session.state.actorId);
|
|
1024
|
+
}
|
|
1025
|
+
catch (error) {
|
|
1026
|
+
failures.push(error);
|
|
1027
|
+
}
|
|
944
1028
|
}
|
|
945
|
-
|
|
1029
|
+
try {
|
|
1030
|
+
await this.requireSpotManager().completeRelocationSource(activation);
|
|
1031
|
+
}
|
|
1032
|
+
catch (error) {
|
|
1033
|
+
failures.push(error);
|
|
1034
|
+
}
|
|
1035
|
+
if (failures.length > 0)
|
|
1036
|
+
throw failures.length === 1
|
|
1037
|
+
? failures[0]
|
|
1038
|
+
: new AggregateError(failures, 'Spot source retirement failed.');
|
|
946
1039
|
},
|
|
947
1040
|
abortSeal: async () => {
|
|
948
1041
|
const failures = [];
|
|
@@ -1029,7 +1122,9 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1029
1122
|
async relocateStandaloneActor(meshName, state, target, targetApplicationVersion, signal, targetMembership, aggregateIdOverride, retainSourceForActorJoin = false,
|
|
1030
1123
|
/** Target's advertised relocation state chunk cap (Actor Join only; spec 15 §4.2). */
|
|
1031
1124
|
advertisedReceiveChunkLimitBytes) {
|
|
1032
|
-
|
|
1125
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1126
|
+
(0, diagnostics_1.relocationDebug)('standalone_actor.begin', { actorId: state.actorId });
|
|
1127
|
+
}
|
|
1033
1128
|
const authority = await requireAuthority(this.requireLocationStore(), (0, authority_key_codec_1.encodeAuthorityKey)('actor', state.actorId), signal);
|
|
1034
1129
|
target ??= await this.selectTarget(meshName, String(this.requireMeshNode(meshName).status().routingId), targetApplicationVersion, [
|
|
1035
1130
|
{
|
|
@@ -1062,14 +1157,20 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1062
1157
|
};
|
|
1063
1158
|
let outcome = 'completed';
|
|
1064
1159
|
try {
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1160
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1161
|
+
(0, diagnostics_1.relocationDebug)('standalone_actor.wait_budget', {
|
|
1162
|
+
actorId: state.actorId,
|
|
1163
|
+
targetRid: String(target.rid)
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1069
1166
|
await this.waitForRelocationBudgetHeadroom(String(target.rid), signal);
|
|
1070
|
-
|
|
1167
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1168
|
+
(0, diagnostics_1.relocationDebug)('standalone_actor.capture_begin', { actorId: state.actorId });
|
|
1169
|
+
}
|
|
1071
1170
|
const captured = await new service_relocation_object_owner_1.ServiceRelocationObjectCaptureOwner().captureStandaloneActor(aggregateId, 1n, measuredUnit, membership, signal);
|
|
1072
|
-
|
|
1171
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1172
|
+
(0, diagnostics_1.relocationDebug)('standalone_actor.capture_complete', { actorId: state.actorId });
|
|
1173
|
+
}
|
|
1073
1174
|
await this.runCoordinator(meshName, target, authority, captured, new Map([[measuredUnit.authorityKey, authority]]), signal, sessions, advertisedReceiveChunkLimitBytes);
|
|
1074
1175
|
}
|
|
1075
1176
|
catch (error) {
|
|
@@ -1084,7 +1185,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1084
1185
|
}
|
|
1085
1186
|
}
|
|
1086
1187
|
async relocatePerActorSpotShell(meshName, activation, target, targetApplicationVersion, signal) {
|
|
1087
|
-
await activation.serial.
|
|
1188
|
+
await activation.serial.executeControlLifecycleOperation(() => this.relocatePerActorSpotShellCore(meshName, activation, target, targetApplicationVersion, signal));
|
|
1088
1189
|
}
|
|
1089
1190
|
async relocatePerActorSpotShellCore(meshName, activation, target, targetApplicationVersion, signal) {
|
|
1090
1191
|
const spotKey = (0, authority_key_codec_1.encodeAuthorityKey)('user_spot', String(activation.spotId));
|
|
@@ -1201,24 +1302,39 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1201
1302
|
target === undefined ||
|
|
1202
1303
|
meshName === undefined)
|
|
1203
1304
|
return;
|
|
1204
|
-
const
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1305
|
+
const failures = [];
|
|
1306
|
+
try {
|
|
1307
|
+
const membershipSpotId = targetMembership?.spotId ?? (target.entrySpotId ?? String(target.rid));
|
|
1308
|
+
const committedAuthority = await requireAuthority(this.requireLocationStore(), (0, authority_key_codec_1.encodeAuthorityKey)('actor', state.actorId));
|
|
1309
|
+
const targetActorRef = {
|
|
1310
|
+
actorId: state.actorId,
|
|
1311
|
+
objectGeneration: authority.objectGeneration,
|
|
1312
|
+
meshName,
|
|
1313
|
+
nodeRid: target.rid
|
|
1314
|
+
};
|
|
1315
|
+
await ownSession.prepared.commit({
|
|
1316
|
+
routerChannelId: meshName,
|
|
1317
|
+
targetNodeRid: target.rid,
|
|
1318
|
+
spotId: membershipSpotId,
|
|
1319
|
+
spotKind: targetMembership?.spotKind ?? contracts_1.ZLinkSpotKind.Entry,
|
|
1320
|
+
authorityOwnerGeneration: committedAuthority.authorityOwnerGeneration
|
|
1321
|
+
}, targetActorRef, (0, actor_transfer_runtime_1.committedActorOwnerFence)(state.actorId, targetActorRef, committedAuthority));
|
|
1322
|
+
}
|
|
1323
|
+
catch (error) {
|
|
1324
|
+
failures.push(error);
|
|
1325
|
+
}
|
|
1219
1326
|
if (!retainSourceForActorJoin) {
|
|
1220
|
-
|
|
1327
|
+
try {
|
|
1328
|
+
await this.requireActorManager().completeRelocationSource(state.actorId);
|
|
1329
|
+
}
|
|
1330
|
+
catch (error) {
|
|
1331
|
+
failures.push(error);
|
|
1332
|
+
}
|
|
1221
1333
|
}
|
|
1334
|
+
if (failures.length > 0)
|
|
1335
|
+
throw failures.length === 1
|
|
1336
|
+
? failures[0]
|
|
1337
|
+
: new AggregateError(failures, 'Actor source retirement failed.');
|
|
1222
1338
|
},
|
|
1223
1339
|
abortSeal: async () => {
|
|
1224
1340
|
if (standalone && ownSession !== undefined)
|
|
@@ -1252,12 +1368,16 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1252
1368
|
async runCoordinator(meshName, target, primary, captured, _authorities, signal, sessions = [],
|
|
1253
1369
|
/** Target's advertised relocation state chunk cap (Actor Join only; spec 15 §4.2). */
|
|
1254
1370
|
advertisedReceiveChunkLimitBytes) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1371
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1372
|
+
(0, diagnostics_1.relocationDebug)('coordinator.begin', {
|
|
1373
|
+
aggregateId: captured.envelope.aggregateId,
|
|
1374
|
+
targetRid: String(target.rid)
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1259
1377
|
const localStatus = this.requireMeshNode(meshName).status();
|
|
1260
|
-
const controlDeadlineAtMs = signal === undefined
|
|
1378
|
+
const controlDeadlineAtMs = signal === undefined
|
|
1379
|
+
? performance.now() + RELOCATION_OPERATION_TIMEOUT_MS
|
|
1380
|
+
: Number.MAX_SAFE_INTEGER;
|
|
1261
1381
|
const coordinator = {
|
|
1262
1382
|
ownerId: primary.ownerId,
|
|
1263
1383
|
leaseGeneration: primary.ownerLeaseGeneration,
|
|
@@ -1306,7 +1426,6 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1306
1426
|
const restoreDeadlineReached = () => signal?.aborted === true || performance.now() >= controlDeadlineAtMs;
|
|
1307
1427
|
let readyReceived = false;
|
|
1308
1428
|
let settlement;
|
|
1309
|
-
let sourceCommitted = false;
|
|
1310
1429
|
try {
|
|
1311
1430
|
const prepare = {
|
|
1312
1431
|
kind: 'prepare',
|
|
@@ -1329,18 +1448,26 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1329
1448
|
// the target assembled, verified, and restored the payload.
|
|
1330
1449
|
const readyOperation = this.sendControl(meshName, target.rid, prepare, signal, controlDeadlineAtMs, encodePrepareSideband(captured.envelope));
|
|
1331
1450
|
try {
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1451
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1452
|
+
(0, diagnostics_1.relocationDebug)('coordinator.state_transfer_begin', {
|
|
1453
|
+
aggregateId: captured.envelope.aggregateId
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1335
1456
|
await this.sendRelocationStateChunks(meshName, target, prepare, encoded, plan, signal);
|
|
1336
1457
|
}
|
|
1337
1458
|
catch (chunkError) {
|
|
1338
1459
|
readyOperation.catch(() => undefined);
|
|
1339
1460
|
throw chunkError;
|
|
1340
1461
|
}
|
|
1341
|
-
|
|
1462
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1463
|
+
(0, diagnostics_1.relocationDebug)('coordinator.await_ready', { aggregateId: captured.envelope.aggregateId });
|
|
1464
|
+
}
|
|
1342
1465
|
const ready = await readyOperation;
|
|
1343
|
-
|
|
1466
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1467
|
+
(0, diagnostics_1.relocationDebug)('coordinator.ready_received', {
|
|
1468
|
+
aggregateId: captured.envelope.aggregateId
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1344
1471
|
validateControlResponse(prepare, ready);
|
|
1345
1472
|
// Ready arms the target's cutover-wait fallback. From this point
|
|
1346
1473
|
// forward the source can no longer reopen dispatch without risking two
|
|
@@ -1402,10 +1529,12 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1402
1529
|
finally {
|
|
1403
1530
|
this.closeSourceCutoverWindow(relayAuthorityId, window);
|
|
1404
1531
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1532
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
1533
|
+
(0, diagnostics_1.relocationDebug)('coordinator.authority_settled', {
|
|
1534
|
+
aggregateId: captured.envelope.aggregateId,
|
|
1535
|
+
settlement
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1409
1538
|
if (settlement === 'source') {
|
|
1410
1539
|
// Preserve won: the captured queue, timers and held records return to
|
|
1411
1540
|
// the source queue in their accepted order, and dispatch reopens.
|
|
@@ -1422,20 +1551,13 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1422
1551
|
for (const session of sessions)
|
|
1423
1552
|
session.prepared.setReplayResults([]);
|
|
1424
1553
|
await captured.commitSource();
|
|
1425
|
-
sourceCommitted = true;
|
|
1426
1554
|
await this.options.reconcileStatefulAuthorityRoutes?.(signal);
|
|
1427
1555
|
}
|
|
1428
1556
|
catch (error) {
|
|
1429
1557
|
if (settlement !== 'target')
|
|
1430
1558
|
throw error;
|
|
1431
1559
|
// Target commit is confirmed; later source cleanup failures cannot move
|
|
1432
|
-
// the authority back (spec 28 §
|
|
1433
|
-
if (!sourceCommitted) {
|
|
1434
|
-
for (const session of sessions)
|
|
1435
|
-
session.prepared.setReplayResults([]);
|
|
1436
|
-
await captured.commitSource().catch(() => undefined);
|
|
1437
|
-
}
|
|
1438
|
-
await this.options.reconcileStatefulAuthorityRoutes?.().catch(() => undefined);
|
|
1560
|
+
// the authority back (spec 28 §10).
|
|
1439
1561
|
const authority = await requireAuthority(this.requireLocationStore(), { value: primaryKey(captured.envelope) }, undefined);
|
|
1440
1562
|
throw new service_relocation_coordinator_1.ServiceRelocationPostCommitError(authority, { id: `${captured.envelope.aggregateId}:${captured.envelope.aggregateGeneration}` }, error);
|
|
1441
1563
|
}
|
|
@@ -1532,7 +1654,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1532
1654
|
window.followExpired = true;
|
|
1533
1655
|
// S1→S4 route convergence: the span the source must keep its Message
|
|
1534
1656
|
// Follow route (spec 30 §7.1).
|
|
1535
|
-
this.options.metrics?.duration(
|
|
1657
|
+
this.options.metrics?.duration(runtime_metrics_1.METRIC_NAMES.RelocationRouteConvergence, Math.max(0, performance.now() - submittedAt) / runtime_metrics_1.MILLISECONDS_PER_SECOND, { mesh_name: meshName });
|
|
1536
1658
|
this.releaseSourceCutoverWindow(relocationKey, window);
|
|
1537
1659
|
}, limits.messageFollowDurationMs);
|
|
1538
1660
|
window.followTimer.unref();
|
|
@@ -1562,8 +1684,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1562
1684
|
return;
|
|
1563
1685
|
const peers = this.requireMeshNode(window.meshName).peers();
|
|
1564
1686
|
const peer = peers.find((value) => value.routingId !== null && String(value.routingId) === String(window.targetNodeRid));
|
|
1565
|
-
|
|
1566
|
-
if (peer !== undefined && peer.state !== 3) {
|
|
1687
|
+
if (peer !== undefined && peer.state !== service_runtime_contracts_1.MeshPeerRuntimeState.Serving) {
|
|
1567
1688
|
window.resendPending = true;
|
|
1568
1689
|
return;
|
|
1569
1690
|
}
|
|
@@ -1597,14 +1718,22 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1597
1718
|
if (this.disposed)
|
|
1598
1719
|
throw new Error('Relocation runtime stopped.');
|
|
1599
1720
|
await this.resendSourceCutover(window);
|
|
1600
|
-
const observed = await this.readSourceSettlement(envelope, primary, target).catch(() =>
|
|
1721
|
+
const observed = await this.readSourceSettlement(envelope, primary, target).catch((error) => {
|
|
1722
|
+
if (!(0, location_store_failure_1.isIndeterminateLocationStoreFailure)(error))
|
|
1723
|
+
throw error;
|
|
1724
|
+
return undefined;
|
|
1725
|
+
});
|
|
1601
1726
|
if (observed?.kind === 'target')
|
|
1602
1727
|
return 'target';
|
|
1603
1728
|
if (observed?.kind === 'other')
|
|
1604
1729
|
return 'lost';
|
|
1605
1730
|
if (restoreDeadlineReached() && observed?.kind === 'source') {
|
|
1606
1731
|
// An unreadable lease is an uncertain result, not an expiry.
|
|
1607
|
-
if (await this.exactSourceLeaseExpired(owner).catch(() =>
|
|
1732
|
+
if (await this.exactSourceLeaseExpired(owner).catch((error) => {
|
|
1733
|
+
if (!(0, location_store_failure_1.isIndeterminateLocationStoreFailure)(error))
|
|
1734
|
+
throw error;
|
|
1735
|
+
return false;
|
|
1736
|
+
}))
|
|
1608
1737
|
return 'lost';
|
|
1609
1738
|
const publication = this.codec.read(observed.current.payload);
|
|
1610
1739
|
const preserved = await store
|
|
@@ -1615,12 +1744,16 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1615
1744
|
? observed.current.payload
|
|
1616
1745
|
: this.codec.clear(observed.current.payload, publication.reference)
|
|
1617
1746
|
})
|
|
1618
|
-
.catch(() =>
|
|
1747
|
+
.catch((error) => {
|
|
1748
|
+
if (!(0, location_store_failure_1.isIndeterminateLocationStoreFailure)(error))
|
|
1749
|
+
throw error;
|
|
1750
|
+
return undefined;
|
|
1751
|
+
});
|
|
1619
1752
|
if (preserved?.kind === 'stored')
|
|
1620
1753
|
return 'source';
|
|
1621
1754
|
}
|
|
1622
1755
|
// The caller awaits this settlement, so the retry timer keeps the loop alive.
|
|
1623
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
1756
|
+
await new Promise((resolve) => setTimeout(resolve, RELOCATION_AUTHORITY_POLL_INTERVAL_MS));
|
|
1624
1757
|
}
|
|
1625
1758
|
}
|
|
1626
1759
|
async readSourceSettlement(envelope, primary, target) {
|
|
@@ -1680,9 +1813,6 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1680
1813
|
}
|
|
1681
1814
|
/** Restores the hidden object and its saved-work prefix before Ready. */
|
|
1682
1815
|
async handlePrepareControl(meshName, stagingId, request, sourceNodeRid, signal) {
|
|
1683
|
-
if (sourceNodeRid === null || String(sourceNodeRid) !== request.sourceNodeRid) {
|
|
1684
|
-
throw new Error('Relocation prepare source node fence does not match the authenticated peer.');
|
|
1685
|
-
}
|
|
1686
1816
|
const targetStatus = this.requireMeshNode(meshName).status();
|
|
1687
1817
|
const targetOwner = this.options.currentOwner();
|
|
1688
1818
|
const targetDescriptor = this.options.localDescriptor?.(meshName);
|
|
@@ -1698,22 +1828,15 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1698
1828
|
const fingerprint = stringifyWire(request);
|
|
1699
1829
|
const existing = this.targetStages.get(stagingId);
|
|
1700
1830
|
if (existing !== undefined) {
|
|
1701
|
-
if (existing.offer.authenticatedSourceNodeRid !== String(sourceNodeRid) ||
|
|
1702
|
-
existing.offer.prepareFingerprint !== fingerprint) {
|
|
1703
|
-
throw new Error('Relocation prepare retry source node changed.');
|
|
1704
|
-
}
|
|
1705
1831
|
return relocationReady(request);
|
|
1706
1832
|
}
|
|
1707
1833
|
const terminal = this.terminalTargets.get(stagingId);
|
|
1708
1834
|
if (terminal !== undefined) {
|
|
1709
|
-
if (terminal !== fingerprint) {
|
|
1710
|
-
throw new Error(`Relocation '${stagingId}' repeated Prepare with different bytes.`);
|
|
1711
|
-
}
|
|
1712
1835
|
this.terminalTargets.touch(stagingId);
|
|
1713
1836
|
return relocationReady(request);
|
|
1714
1837
|
}
|
|
1715
1838
|
const pendingAssembly = this.targetAssemblies.get(stagingId);
|
|
1716
|
-
if (pendingAssembly === undefined
|
|
1839
|
+
if (pendingAssembly === undefined) {
|
|
1717
1840
|
throw new Error(`Relocation '${stagingId}' has no matching payload assembly.`);
|
|
1718
1841
|
}
|
|
1719
1842
|
// The directly transferred payload replaces the shared durable root: the
|
|
@@ -1795,7 +1918,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1795
1918
|
if (stage.finalize !== undefined)
|
|
1796
1919
|
return;
|
|
1797
1920
|
console.warn('[zlink.runtime.relocation.cutover_timeout]', stagingId);
|
|
1798
|
-
this.options.metrics?.count(
|
|
1921
|
+
this.options.metrics?.count(runtime_metrics_1.METRIC_NAMES.RelocationCutoverTimeout, 1, {
|
|
1799
1922
|
mesh_name: meshName
|
|
1800
1923
|
});
|
|
1801
1924
|
void this.beginTargetFinalize(meshName, stagingId, stage).catch((error) => console.error('[zlink.runtime.relocation.location_update_failed]', error));
|
|
@@ -1809,7 +1932,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1809
1932
|
const stagingId = relocationStagingId(request);
|
|
1810
1933
|
const stage = this.targetStages.get(stagingId);
|
|
1811
1934
|
if (stage === undefined) {
|
|
1812
|
-
if (this.terminalTargets.get(stagingId) !== undefined) {
|
|
1935
|
+
if (this.disposed || this.terminalTargets.get(stagingId) !== undefined) {
|
|
1813
1936
|
if (request.kind === 'cutover') {
|
|
1814
1937
|
console.warn('[zlink.runtime.relocation.late_cutover]', stagingId);
|
|
1815
1938
|
}
|
|
@@ -1818,21 +1941,26 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1818
1941
|
throw new Error(`Relocation staging '${stagingId}' is missing.`);
|
|
1819
1942
|
}
|
|
1820
1943
|
validateTargetOneWayControl(stage, request, sourceNodeRid);
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
if (
|
|
1825
|
-
|
|
1944
|
+
stage.lane = stage.lane.then(() => {
|
|
1945
|
+
// A verified cutover closes the boundary batch. A later record or cutover
|
|
1946
|
+
// is a duplicate retransmission and never changes the staged batch.
|
|
1947
|
+
if (stage.cutoverReceived || (stage.phase !== 'ready' && stage.phase !== 'finalizing')) {
|
|
1948
|
+
if (request.kind === 'cutover') {
|
|
1949
|
+
console.warn('[zlink.runtime.relocation.late_cutover]', stagingId);
|
|
1950
|
+
}
|
|
1951
|
+
return;
|
|
1826
1952
|
}
|
|
1953
|
+
if (request.kind === 'data') {
|
|
1954
|
+
return this.stageBoundaryRelay(stage, request);
|
|
1955
|
+
}
|
|
1956
|
+
if (this.targetStageSealed(stage))
|
|
1957
|
+
return;
|
|
1958
|
+
this.reconcileBoundaryRelay(stage, request, stagingId);
|
|
1959
|
+
stage.cutoverReceived = true;
|
|
1960
|
+
});
|
|
1961
|
+
await stage.lane;
|
|
1962
|
+
if (request.kind === 'data')
|
|
1827
1963
|
return;
|
|
1828
|
-
}
|
|
1829
|
-
if (request.kind === 'data') {
|
|
1830
|
-
stage.lane = stage.lane.then(() => this.stageBoundaryRelay(stage, request));
|
|
1831
|
-
await stage.lane;
|
|
1832
|
-
return;
|
|
1833
|
-
}
|
|
1834
|
-
this.reconcileBoundaryRelay(stage, request, stagingId);
|
|
1835
|
-
stage.cutoverReceived = true;
|
|
1836
1964
|
// A settlement started by the cutover wait Warning is still reading the
|
|
1837
1965
|
// Store; it submits the CAS on its next round now that cutover verified.
|
|
1838
1966
|
if (stage.finalize !== undefined)
|
|
@@ -1894,10 +2022,10 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1894
2022
|
try {
|
|
1895
2023
|
authority = await this.commitTargetReservation(stage, stage.offer.reservation, signal);
|
|
1896
2024
|
if (authority === undefined) {
|
|
1897
|
-
//
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
2025
|
+
// The seal owner may have ended staging while a Store read was pending.
|
|
2026
|
+
if (stage.phase === 'failed')
|
|
2027
|
+
return;
|
|
2028
|
+
return this.discardTargetStage(stagingId, stage, signal);
|
|
1901
2029
|
}
|
|
1902
2030
|
authorityCommitted = true;
|
|
1903
2031
|
stage.releaseActivation();
|
|
@@ -1930,7 +2058,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1930
2058
|
}
|
|
1931
2059
|
await stage.owner.openAdmission(stage.staging, signal);
|
|
1932
2060
|
// S2→S3: owner confirmation to application dispatch opening.
|
|
1933
|
-
this.options.metrics?.duration(
|
|
2061
|
+
this.options.metrics?.duration(runtime_metrics_1.METRIC_NAMES.RelocationTargetResume, Math.max(0, performance.now() - resumeStartedAt) / runtime_metrics_1.MILLISECONDS_PER_SECOND, { mesh_name: meshName });
|
|
1934
2062
|
await this.publishSessionRoutes(stage.staging);
|
|
1935
2063
|
await this.relayTerminalReplies(meshName, stage, this.targetReplyRelayCoordinator(meshName, stage, authority), signal);
|
|
1936
2064
|
stage.phase = 'open';
|
|
@@ -1939,14 +2067,16 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
1939
2067
|
this.targetAssemblies.delete(stagingId);
|
|
1940
2068
|
}
|
|
1941
2069
|
catch (error) {
|
|
1942
|
-
stage.phase = 'failed';
|
|
1943
2070
|
this.terminalTargets.remember(stagingId, stage.offer.prepareFingerprint);
|
|
1944
2071
|
this.targetStages.delete(stagingId);
|
|
1945
2072
|
this.targetAssemblies.delete(stagingId);
|
|
1946
2073
|
if (!authorityCommitted) {
|
|
1947
|
-
|
|
2074
|
+
// abortTargetStage may already have assigned failed before throwing.
|
|
2075
|
+
if (stage.phase !== 'failed')
|
|
2076
|
+
await this.abortTargetStage(stage);
|
|
1948
2077
|
throw error;
|
|
1949
2078
|
}
|
|
2079
|
+
stage.phase = 'failed';
|
|
1950
2080
|
if (authority !== undefined) {
|
|
1951
2081
|
throw new service_relocation_coordinator_1.ServiceRelocationPostCommitError(authority, stage.staging, error);
|
|
1952
2082
|
}
|
|
@@ -2030,16 +2160,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2030
2160
|
}
|
|
2031
2161
|
this.sourceActorJoinProfiles.delete(input.transferId);
|
|
2032
2162
|
this.terminalActorJoinSourceLeaves.remember(input.transferId, input.actorId);
|
|
2033
|
-
void profile
|
|
2034
|
-
.then(async () => {
|
|
2035
|
-
await this.options.actorTransfer.completeRelocationSourceLeave(profile.actor, profile.sourceSpotId);
|
|
2036
|
-
await this.options
|
|
2037
|
-
.actorManager()
|
|
2038
|
-
?.completeRelocationSource(input.actorId, profile.sourceActorRef);
|
|
2039
|
-
})
|
|
2040
|
-
.catch((error) => {
|
|
2041
|
-
console.error('[zlink.runtime.relocation.source_leave_failed]', error);
|
|
2042
|
-
});
|
|
2163
|
+
void this.finalizeActorJoinSource(profile);
|
|
2043
2164
|
return true;
|
|
2044
2165
|
}
|
|
2045
2166
|
async sendControlOneWay(meshName, targetNodeRid, request) {
|
|
@@ -2148,13 +2269,13 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2148
2269
|
pending.resolve('sourceLeaseExpired');
|
|
2149
2270
|
return;
|
|
2150
2271
|
}
|
|
2151
|
-
if (++attempts >
|
|
2272
|
+
if (++attempts > RELOCATION_MAX_SEND_ATTEMPTS) {
|
|
2152
2273
|
pending.reject(new Error(`Relocation reply relay ACK '${key}' timed out.`));
|
|
2153
2274
|
return;
|
|
2154
2275
|
}
|
|
2155
2276
|
await this.sendInfrastructureControl(meshName, ackTargetNodeRid, (0, service_stateful_wire_codec_1.encodeMaintenanceReplyRelay)(request));
|
|
2156
2277
|
if (this.pendingReplyRelays.get(key) === pending) {
|
|
2157
|
-
pending.timer = setTimeout(() => void send(),
|
|
2278
|
+
pending.timer = setTimeout(() => void send(), RELOCATION_RESEND_DELAY_MS);
|
|
2158
2279
|
}
|
|
2159
2280
|
}
|
|
2160
2281
|
catch (error) {
|
|
@@ -2249,13 +2370,15 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2249
2370
|
lease.leaseExpiresAt.getTime() <= lease.storeNow.getTime());
|
|
2250
2371
|
}
|
|
2251
2372
|
async publishSessionRoutes(staging) {
|
|
2252
|
-
for (const hidden of staging.hidden
|
|
2253
|
-
if (hidden.actor
|
|
2254
|
-
|
|
2255
|
-
|
|
2373
|
+
for (const [key, hidden] of staging.hidden) {
|
|
2374
|
+
if (hidden.actor === undefined)
|
|
2375
|
+
continue;
|
|
2376
|
+
// The Session seal travels with the relocation envelope, not the Actor.
|
|
2377
|
+
const carried = staging.envelope.participants.find((value) => value.key === key);
|
|
2378
|
+
await this.options.actorTransfer.publishRoutedActorOwnership(hidden.actor, carried === undefined ? undefined : decodeActorSession(carried.boundSessionState));
|
|
2256
2379
|
}
|
|
2257
2380
|
}
|
|
2258
|
-
async sendControl(meshName, targetNodeRid, request, signal, deadlineAtMs = performance.now() +
|
|
2381
|
+
async sendControl(meshName, targetNodeRid, request, signal, deadlineAtMs = performance.now() + RELOCATION_OPERATION_TIMEOUT_MS, sideband = []) {
|
|
2259
2382
|
const key = controlAckKey(request);
|
|
2260
2383
|
const frames = sideband.length === 0
|
|
2261
2384
|
? [(0, service_relocation_control_1.encodeServiceRelocationControlRequest)(request)]
|
|
@@ -2267,7 +2390,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2267
2390
|
if (remainingMs <= 0) {
|
|
2268
2391
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `Relocation control ACK '${key}' timed out.`, true, lastRequestError);
|
|
2269
2392
|
}
|
|
2270
|
-
const attemptTimeoutMs = Math.max(1, Math.min(
|
|
2393
|
+
const attemptTimeoutMs = Math.max(1, Math.min(RELOCATION_ATTEMPT_TIMEOUT_MS, Math.ceil(remainingMs)));
|
|
2271
2394
|
const startedAtMs = performance.now();
|
|
2272
2395
|
try {
|
|
2273
2396
|
const replyFrames = await this.requestInfrastructureControl(meshName, targetNodeRid, frames, attemptTimeoutMs);
|
|
@@ -2287,11 +2410,13 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2287
2410
|
throw error;
|
|
2288
2411
|
}
|
|
2289
2412
|
lastRequestError = error;
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2413
|
+
if ((0, diagnostics_1.isRelocationDebugEnabled)()) {
|
|
2414
|
+
(0, diagnostics_1.relocationDebug)('control.request_retry', {
|
|
2415
|
+
key,
|
|
2416
|
+
kind: request.kind,
|
|
2417
|
+
targetRid: String(targetNodeRid)
|
|
2418
|
+
});
|
|
2419
|
+
}
|
|
2295
2420
|
const retryDelayMs = Math.min(Math.max(0, attemptTimeoutMs - (performance.now() - startedAtMs)), Math.max(0, deadlineAtMs - performance.now()));
|
|
2296
2421
|
if (retryDelayMs > 0) {
|
|
2297
2422
|
await waitForRelocationRetry(retryDelayMs, signal);
|
|
@@ -2316,7 +2441,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2316
2441
|
peers.some((peer) => peer.routingId !== null &&
|
|
2317
2442
|
String(peer.routingId) === String(descriptor.rid) &&
|
|
2318
2443
|
peer.lifecycleGeneration === descriptor.lifecycleGeneration &&
|
|
2319
|
-
peer.state ===
|
|
2444
|
+
peer.state === service_runtime_contracts_1.MeshPeerRuntimeState.Serving) &&
|
|
2320
2445
|
relocationTargetSupports(descriptor, requirements))
|
|
2321
2446
|
.sort((left, right) => String(left.rid).localeCompare(String(right.rid)));
|
|
2322
2447
|
const target = selectWeightedRelocationTarget(candidates);
|
|
@@ -2480,6 +2605,18 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2480
2605
|
throw new AggregateError(failures, 'Relocation target rollback was incomplete.');
|
|
2481
2606
|
}
|
|
2482
2607
|
}
|
|
2608
|
+
async discardTargetStage(stagingId, stage, signal) {
|
|
2609
|
+
stage.phase = 'failed';
|
|
2610
|
+
console.warn('[zlink.runtime.relocation.target_staging_discarded]', stagingId);
|
|
2611
|
+
try {
|
|
2612
|
+
await this.abortTargetStage(stage, signal);
|
|
2613
|
+
}
|
|
2614
|
+
finally {
|
|
2615
|
+
this.terminalTargets.remember(stagingId, stage.offer.prepareFingerprint);
|
|
2616
|
+
this.targetStages.delete(stagingId);
|
|
2617
|
+
this.targetAssemblies.delete(stagingId);
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2483
2620
|
async commitTargetReservation(stage, reservation, signal) {
|
|
2484
2621
|
return await this.commitTargetAggregate(stage, reservation.prepared, signal);
|
|
2485
2622
|
}
|
|
@@ -2497,9 +2634,11 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2497
2634
|
async commitTargetAggregate(stage, prepared, signal) {
|
|
2498
2635
|
const target = stage.offer.prepare.target;
|
|
2499
2636
|
for (;;) {
|
|
2637
|
+
if (stage.phase === 'failed')
|
|
2638
|
+
return undefined;
|
|
2500
2639
|
signal?.throwIfAborted();
|
|
2501
|
-
if (this.
|
|
2502
|
-
|
|
2640
|
+
if (this.targetStageSealed(stage))
|
|
2641
|
+
return undefined;
|
|
2503
2642
|
let conflict = false;
|
|
2504
2643
|
if (stage.cutoverReceived) {
|
|
2505
2644
|
// The boundary relay span is applied to the temporary queue before
|
|
@@ -2511,13 +2650,19 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2511
2650
|
// A thrown provider call has an unknown result; the read below decides.
|
|
2512
2651
|
const result = await this.requireLocationStore()
|
|
2513
2652
|
.commitAggregate(prepared.fence, signal)
|
|
2514
|
-
.catch(() =>
|
|
2653
|
+
.catch((error) => {
|
|
2654
|
+
if (!(0, location_store_failure_1.isIndeterminateLocationStoreFailure)(error, signal))
|
|
2655
|
+
throw error;
|
|
2656
|
+
return undefined;
|
|
2657
|
+
});
|
|
2515
2658
|
if (result?.kind === 'generationExhausted') {
|
|
2516
2659
|
throw new Error('location_update_failed: relocation aggregate commit exhausted.');
|
|
2517
2660
|
}
|
|
2518
2661
|
conflict = result?.kind === 'stale';
|
|
2519
2662
|
}
|
|
2520
2663
|
const observed = await this.readAggregateForCommitRetry(prepared, signal);
|
|
2664
|
+
if (stage.phase === 'failed')
|
|
2665
|
+
return undefined;
|
|
2521
2666
|
if (observed.kind === 'committed') {
|
|
2522
2667
|
const primary = observed.authorities.get(stage.staging.primaryAuthorityKey.value);
|
|
2523
2668
|
if (primary === undefined) {
|
|
@@ -2528,10 +2673,14 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2528
2673
|
if (observed.kind === 'stale' || (conflict && observed.kind === 'source'))
|
|
2529
2674
|
return undefined;
|
|
2530
2675
|
// An unreadable lease is an uncertain result, not an expiry.
|
|
2531
|
-
if (await this.exactSourceLeaseExpired({ ownerId: target.ownerId, leaseGeneration: target.ownerLeaseGeneration }, signal).catch(() =>
|
|
2676
|
+
if (await this.exactSourceLeaseExpired({ ownerId: target.ownerId, leaseGeneration: target.ownerLeaseGeneration }, signal).catch((error) => {
|
|
2677
|
+
if (!(0, location_store_failure_1.isIndeterminateLocationStoreFailure)(error, signal))
|
|
2678
|
+
throw error;
|
|
2679
|
+
return false;
|
|
2680
|
+
})) {
|
|
2532
2681
|
return undefined;
|
|
2533
2682
|
}
|
|
2534
|
-
await waitForRelocationRetry(
|
|
2683
|
+
await waitForRelocationRetry(RELOCATION_AUTHORITY_RETRY_DELAY_MS, signal);
|
|
2535
2684
|
}
|
|
2536
2685
|
}
|
|
2537
2686
|
async readAggregateForCommitRetry(prepared, signal) {
|
|
@@ -2560,7 +2709,9 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2560
2709
|
}
|
|
2561
2710
|
}
|
|
2562
2711
|
}
|
|
2563
|
-
catch {
|
|
2712
|
+
catch (error) {
|
|
2713
|
+
if (!(0, location_store_failure_1.isIndeterminateLocationStoreFailure)(error, signal))
|
|
2714
|
+
throw error;
|
|
2564
2715
|
return { kind: 'unknown' };
|
|
2565
2716
|
}
|
|
2566
2717
|
if (committed === prepared.plan.participants.length) {
|
|
@@ -2592,7 +2743,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2592
2743
|
if (request.object.kind === 'userSpot' || request.object.kind === 'instanceSpot') {
|
|
2593
2744
|
let cursor;
|
|
2594
2745
|
for (;;) {
|
|
2595
|
-
const page = await store.listAuthorities('', cursor,
|
|
2746
|
+
const page = await store.listAuthorities('', cursor, Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE, signal);
|
|
2596
2747
|
if (page.kind === 'scanExpired') {
|
|
2597
2748
|
throw new Error('Location Store authority scan expired during relocation.');
|
|
2598
2749
|
}
|
|
@@ -2699,7 +2850,7 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2699
2850
|
const adapter = await this.createRelocationAdapter(policy.adapterType);
|
|
2700
2851
|
const captured = await (0, relocation_state_adapter_1.captureRelocationAdapterState)(adapter, value, signal ?? new AbortController().signal);
|
|
2701
2852
|
if (captured.byteLength > RELOCATION_PARTICIPANT_STATE_LIMIT_BYTES) {
|
|
2702
|
-
throw new ZLinkRelocationStateIncompatibleError(
|
|
2853
|
+
throw new ZLinkRelocationStateIncompatibleError(`Relocation application state exceeds the ${RELOCATION_PARTICIPANT_STATE_LIMIT_BYTES / (1024 * 1024)} MiB participant limit.`);
|
|
2703
2854
|
}
|
|
2704
2855
|
return captured;
|
|
2705
2856
|
}
|
|
@@ -2707,13 +2858,13 @@ class ZLinkHostServiceRelocationRuntime {
|
|
|
2707
2858
|
return (await (0, spot_provider_1.createProviderInstance)(adapterType, this.options.providerResolver));
|
|
2708
2859
|
}
|
|
2709
2860
|
recordRelocationInterruption(meshName, unitKind, executionMode, startedAt, outcome) {
|
|
2710
|
-
const seconds = Math.max(0, performance.now() - startedAt) /
|
|
2861
|
+
const seconds = Math.max(0, performance.now() - startedAt) / runtime_metrics_1.MILLISECONDS_PER_SECOND;
|
|
2711
2862
|
const attributes = {
|
|
2712
2863
|
unit_kind: unitKind,
|
|
2713
2864
|
...(executionMode === undefined ? {} : { execution_mode: executionMode })
|
|
2714
2865
|
};
|
|
2715
|
-
this.options.metrics?.duration(
|
|
2716
|
-
this.options.metrics?.count(
|
|
2866
|
+
this.options.metrics?.duration(runtime_metrics_1.METRIC_NAMES.RelocationInterruption, seconds, attributes);
|
|
2867
|
+
this.options.metrics?.count(runtime_metrics_1.METRIC_NAMES.RelocationCompleted, 1, {
|
|
2717
2868
|
mesh_name: meshName,
|
|
2718
2869
|
object_kind: unitKind,
|
|
2719
2870
|
policy: unitKind === 'user_spot' && executionMode === 'per_actor' ? 'recreate' : 'configured',
|
|
@@ -2891,11 +3042,6 @@ function actorJoinTargetMembership(manager, relocationId, participants) {
|
|
|
2891
3042
|
}
|
|
2892
3043
|
];
|
|
2893
3044
|
}
|
|
2894
|
-
function relocationDebug(marker, detail) {
|
|
2895
|
-
if (process.env.ZLINK_DEBUG_FRAMEWORK_RELOCATION !== '1')
|
|
2896
|
-
return;
|
|
2897
|
-
console.error('[zlink.runtime.relocation]', marker, detail);
|
|
2898
|
-
}
|
|
2899
3045
|
class LocalTargetPort {
|
|
2900
3046
|
options;
|
|
2901
3047
|
meshName;
|
|
@@ -2916,7 +3062,7 @@ class LocalTargetPort {
|
|
|
2916
3062
|
}).globalId;
|
|
2917
3063
|
const localDescriptor = this.options.localDescriptor?.(this.meshName);
|
|
2918
3064
|
const nativeEntrySpot = localDescriptor?.entrySpotId === spotIdentity;
|
|
2919
|
-
const actor = await this.requireActorManager().prepareRelocationActor(identity, participant.stableType, participant.objectGeneration, participant.authorityOwnerGeneration + 1n,
|
|
3065
|
+
const actor = await this.requireActorManager().prepareRelocationActor(identity, participant.stableType, participant.objectGeneration, participant.authorityOwnerGeneration + 1n, nativeEntrySpot ? undefined : spotIdentity, membership.spotObjectGeneration, membership.membershipEpoch, signal);
|
|
2920
3066
|
return {
|
|
2921
3067
|
authorityKey: participant.key,
|
|
2922
3068
|
participant,
|
|
@@ -3002,8 +3148,14 @@ class LocalTargetPort {
|
|
|
3002
3148
|
const applicationSignaled = hidden.participant.objectKind === 'user_spot' &&
|
|
3003
3149
|
registration.options?.relocationCoordinationMode ===
|
|
3004
3150
|
contracts_1.ZLinkSpotRelocationCoordinationMode.ApplicationSignaled;
|
|
3151
|
+
// createHidden could only predict the owner generation; the native Spot
|
|
3152
|
+
// takes the committed authority, as the Actor branch does above.
|
|
3153
|
+
const node = this.options.meshNode(this.meshName);
|
|
3154
|
+
node?.restoreSpotAuthority?.(String(hidden.activation.spotId),
|
|
3155
|
+
// createHidden stages an activation only for a Spot participant.
|
|
3156
|
+
hidden.participant.objectKind, hidden.participant.stableType, authority.objectGeneration, authority.authorityOwnerGeneration);
|
|
3005
3157
|
await this.requireSpotManager().publishRelocationSpot(hidden.activation, applicationSignaled ? () => hidden.activation.notifyRelocatedBoundary() : undefined);
|
|
3006
|
-
|
|
3158
|
+
node?.rememberSpotRoute?.({
|
|
3007
3159
|
spot: {
|
|
3008
3160
|
spotId: String(hidden.activation.spotId),
|
|
3009
3161
|
generation: authority.objectGeneration
|
|
@@ -3033,15 +3185,14 @@ class LocalTargetPort {
|
|
|
3033
3185
|
hidden.initialized = true;
|
|
3034
3186
|
}
|
|
3035
3187
|
async restoreBoundSession(hidden, payload) {
|
|
3036
|
-
|
|
3188
|
+
const carried = decodeActorSession(payload);
|
|
3189
|
+
if (hidden.actor === undefined || carried === undefined)
|
|
3037
3190
|
return;
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
state.setBoundSessionBindingGeneration(target.bindingGeneration);
|
|
3044
|
-
}
|
|
3191
|
+
// The relocation delivers the binding it carried; the target installs it
|
|
3192
|
+
// through the one install rule (Session–Actor binding §6, §8).
|
|
3193
|
+
this.requireActorManager()
|
|
3194
|
+
.getState(hidden.actor.context.actorId)
|
|
3195
|
+
.installBoundSessionBinding(carried);
|
|
3045
3196
|
}
|
|
3046
3197
|
async replayQueuedMessage(hidden, message) {
|
|
3047
3198
|
if (hidden.actor === undefined) {
|
|
@@ -3374,9 +3525,9 @@ function relocationWireId(value) {
|
|
|
3374
3525
|
}
|
|
3375
3526
|
function createServiceRelocationId(isInUse, entropy = node_crypto_1.randomBytes) {
|
|
3376
3527
|
for (;;) {
|
|
3377
|
-
const bytes = entropy(
|
|
3378
|
-
if (bytes.byteLength !==
|
|
3379
|
-
throw new Error(
|
|
3528
|
+
const bytes = entropy(operation_identity_1.OPERATION_IDENTITY_BYTES);
|
|
3529
|
+
if (bytes.byteLength !== operation_identity_1.OPERATION_IDENTITY_BYTES) {
|
|
3530
|
+
throw new Error(`Relocation identity entropy must return exactly ${operation_identity_1.OPERATION_IDENTITY_BYTES} bytes.`);
|
|
3380
3531
|
}
|
|
3381
3532
|
let nonZero = false;
|
|
3382
3533
|
for (const byte of bytes) {
|
|
@@ -3409,11 +3560,34 @@ function sameWireId(left, right) {
|
|
|
3409
3560
|
}
|
|
3410
3561
|
function sameCoordinator(left, right) {
|
|
3411
3562
|
return (left.ownerId === right.ownerId &&
|
|
3412
|
-
left.leaseGeneration === right.leaseGeneration &&
|
|
3563
|
+
BigInt(left.leaseGeneration) === right.leaseGeneration &&
|
|
3413
3564
|
left.nodeRid === right.nodeRid &&
|
|
3414
|
-
left.nodeGeneration === right.nodeGeneration &&
|
|
3565
|
+
BigInt(left.nodeGeneration) === right.nodeGeneration &&
|
|
3415
3566
|
left.expectedAuthorityStoreVersion === right.expectedAuthorityStoreVersion);
|
|
3416
3567
|
}
|
|
3568
|
+
function sameRelocationTarget(left, right) {
|
|
3569
|
+
return (left.nodeRid === right.nodeRid &&
|
|
3570
|
+
BigInt(left.nodeGeneration) === right.nodeGeneration &&
|
|
3571
|
+
left.ownerId === right.ownerId &&
|
|
3572
|
+
BigInt(left.ownerLeaseGeneration) === right.ownerLeaseGeneration);
|
|
3573
|
+
}
|
|
3574
|
+
function sameRelocationObject(left, right) {
|
|
3575
|
+
if (left.kind !== right.kind || BigInt(left.objectGeneration) !== right.objectGeneration) {
|
|
3576
|
+
return false;
|
|
3577
|
+
}
|
|
3578
|
+
if (left.kind === 'actor' && right.kind === 'actor') {
|
|
3579
|
+
return (left.actorId === right.actorId &&
|
|
3580
|
+
BigInt(left.expectedAuthorityOwnerGeneration) === right.expectedAuthorityOwnerGeneration);
|
|
3581
|
+
}
|
|
3582
|
+
if (left.kind === 'userSpot' && right.kind === 'userSpot') {
|
|
3583
|
+
return (left.spotId === right.spotId &&
|
|
3584
|
+
BigInt(left.expectedAuthorityOwnerGeneration) === right.expectedAuthorityOwnerGeneration);
|
|
3585
|
+
}
|
|
3586
|
+
return (left.kind === 'instanceSpot' &&
|
|
3587
|
+
right.kind === 'instanceSpot' &&
|
|
3588
|
+
left.spotId === right.spotId &&
|
|
3589
|
+
left.stableType === right.stableType);
|
|
3590
|
+
}
|
|
3417
3591
|
function isExactSourceAuthority(current, expected) {
|
|
3418
3592
|
return (current.storeVersion.value === expected.storeVersion.value && isSourceOwner(current, expected));
|
|
3419
3593
|
}
|
|
@@ -3479,14 +3653,16 @@ function maintenanceReplyRelay(stage, coordinator, participantId, completion) {
|
|
|
3479
3653
|
replyRouteId: BigInt(completion.source.replyRouteId),
|
|
3480
3654
|
participantId,
|
|
3481
3655
|
sequence: BigInt(completion.index + 1),
|
|
3482
|
-
terminalResult: completion.result.ok ?
|
|
3483
|
-
failureCode: completion.result.ok
|
|
3656
|
+
terminalResult: completion.result.ok ? runtime_values_1.RequestResult.Ok : runtime_values_1.RequestResult.InternalError,
|
|
3657
|
+
failureCode: completion.result.ok
|
|
3658
|
+
? service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.none
|
|
3659
|
+
: service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestFailed,
|
|
3484
3660
|
...(value === undefined
|
|
3485
3661
|
? {}
|
|
3486
3662
|
: {
|
|
3487
3663
|
payload: {
|
|
3488
|
-
packetName:
|
|
3489
|
-
contentType:
|
|
3664
|
+
packetName: SERVICE_RELOCATION_REPLY_PACKET_NAME,
|
|
3665
|
+
contentType: stream_wire_1.ZlinkStreamContentType.Json,
|
|
3490
3666
|
bytes: Buffer.from(JSON.stringify(value), 'utf8')
|
|
3491
3667
|
}
|
|
3492
3668
|
})
|
|
@@ -3498,15 +3674,15 @@ function handoffResultFromRelay(relay) {
|
|
|
3498
3674
|
}
|
|
3499
3675
|
let value;
|
|
3500
3676
|
if (relay.payload !== undefined) {
|
|
3501
|
-
if (relay.terminalResult !==
|
|
3502
|
-
relay.payload.packetName !==
|
|
3503
|
-
relay.payload.contentType !==
|
|
3677
|
+
if (relay.terminalResult !== runtime_values_1.RequestResult.Ok ||
|
|
3678
|
+
relay.payload.packetName !== SERVICE_RELOCATION_REPLY_PACKET_NAME ||
|
|
3679
|
+
relay.payload.contentType !== stream_wire_1.ZlinkStreamContentType.Json) {
|
|
3504
3680
|
throw new TypeError('Relocation terminal payload boundary is invalid.');
|
|
3505
3681
|
}
|
|
3506
3682
|
value = JSON.parse(Buffer.from(relay.payload.bytes).toString('utf8'));
|
|
3507
3683
|
}
|
|
3508
3684
|
const index = Number(relay.sequence - 1n);
|
|
3509
|
-
return relay.terminalResult ===
|
|
3685
|
+
return relay.terminalResult === runtime_values_1.RequestResult.Ok
|
|
3510
3686
|
? { index, ok: true, ...(value === undefined ? {} : { response: value }) }
|
|
3511
3687
|
: { index, ok: false, error: `Actor handoff failed with framework code ${relay.failureCode}.` };
|
|
3512
3688
|
}
|
|
@@ -3521,73 +3697,15 @@ function wireIdText(value) {
|
|
|
3521
3697
|
class ServiceRelocationDataLostError extends Error {
|
|
3522
3698
|
}
|
|
3523
3699
|
exports.ServiceRelocationDataLostError = ServiceRelocationDataLostError;
|
|
3524
|
-
/**
|
|
3525
|
-
|
|
3526
|
-
* framework-error code the generated schema
|
|
3527
|
-
* ({@link ServiceWireFrameworkErrorCode}) defines — mirrors the java
|
|
3528
|
-
* reference mapping (commit 97fc074058) and the dotnet/cpp ports. The wire
|
|
3529
|
-
* vocabulary predates the framework's typed error kinds and has no
|
|
3530
|
-
* one-to-one code for every kind, so several kinds share the nearest fit
|
|
3531
|
-
* (documented per case below); unresolvable vocabulary gaps belong at the
|
|
3532
|
-
* schema level, not invented here. {@link ServiceRelocationDataLostError}
|
|
3533
|
-
* is this runtime's dedicated tag for a verified checksum/assembly/digest
|
|
3534
|
-
* integrity failure — the case that keeps relocationDataLost(35). An
|
|
3535
|
-
* unclassified error carries no evidence of integrity loss and takes the
|
|
3536
|
-
* generic opaque requestFailed(17). `objectKind` (the Prepare's
|
|
3537
|
-
* ObjectFence.kind, spec 28 §4.2) picks between an Actor- and
|
|
3538
|
-
* Spot-specific code where the schema splits by object kind.
|
|
3539
|
-
*/
|
|
3540
|
-
function relocationFailedFailureCode(error, objectKind) {
|
|
3700
|
+
/** Classifies relocation failure with the error model §2.1 mapping. */
|
|
3701
|
+
function relocationFailedFailureCode(error) {
|
|
3541
3702
|
if (error instanceof ServiceRelocationDataLostError) {
|
|
3542
|
-
return
|
|
3703
|
+
return (0, framework_errors_internal_1.frameworkRelocationFailureCode)(contracts_1.ZLinkFrameworkErrorKind.DataLost);
|
|
3543
3704
|
}
|
|
3544
3705
|
if (!(error instanceof contracts_1.ZLinkFrameworkException)) {
|
|
3545
|
-
return
|
|
3546
|
-
}
|
|
3547
|
-
switch (error.kind) {
|
|
3548
|
-
case contracts_1.ZLinkFrameworkErrorKind.DataLost:
|
|
3549
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.relocationDataLost;
|
|
3550
|
-
case contracts_1.ZLinkFrameworkErrorKind.Rejected:
|
|
3551
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestRejected;
|
|
3552
|
-
case contracts_1.ZLinkFrameworkErrorKind.ProtocolError:
|
|
3553
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestProtocolError;
|
|
3554
|
-
// No dedicated "deadline exceeded" wire code exists; a worker timeout
|
|
3555
|
-
// is the closest timeout-shaped signal.
|
|
3556
|
-
case contracts_1.ZLinkFrameworkErrorKind.DeadlineExceeded:
|
|
3557
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.workerTimedOut;
|
|
3558
|
-
// A stale generation/fence is the concrete cause of InvalidOperation
|
|
3559
|
-
// along this path (spec 15 failure table); pick the
|
|
3560
|
-
// object-kind-specific stale code.
|
|
3561
|
-
case contracts_1.ZLinkFrameworkErrorKind.InvalidOperation:
|
|
3562
|
-
return objectKind === 'actor'
|
|
3563
|
-
? service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.actorLocationStale
|
|
3564
|
-
: service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.spotGenerationStale;
|
|
3565
|
-
// No dedicated generic "unavailable" wire code exists; a disconnected
|
|
3566
|
-
// route is the closest "cannot reach/use the target" signal.
|
|
3567
|
-
case contracts_1.ZLinkFrameworkErrorKind.Unavailable:
|
|
3568
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.routeNotConnected;
|
|
3569
|
-
case contracts_1.ZLinkFrameworkErrorKind.NotFound:
|
|
3570
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestTargetNotFound;
|
|
3571
|
-
// The only "already exists" wire code is Actor-specific; not expected
|
|
3572
|
-
// along this target-failure path, mapped for completeness.
|
|
3573
|
-
case contracts_1.ZLinkFrameworkErrorKind.AlreadyExists:
|
|
3574
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.actorAlreadyExists;
|
|
3575
|
-
case contracts_1.ZLinkFrameworkErrorKind.TypeMismatch:
|
|
3576
|
-
return objectKind === 'actor'
|
|
3577
|
-
? service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.actorTypeMismatch
|
|
3578
|
-
: service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.spotTypeMismatch;
|
|
3579
|
-
// No dedicated "not configured" wire code exists; a missing configured
|
|
3580
|
-
// handler is the closest analog.
|
|
3581
|
-
case contracts_1.ZLinkFrameworkErrorKind.NotConfigured:
|
|
3582
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.handlerNotFound;
|
|
3583
|
-
// No dedicated generic "internal failure" or "shutting down" wire code
|
|
3584
|
-
// exists; the generic opaque request-failure code is the closest fit
|
|
3585
|
-
// for both (ShuttingDown included — re-judged 2026-08-19, C-10).
|
|
3586
|
-
case contracts_1.ZLinkFrameworkErrorKind.ShuttingDown:
|
|
3587
|
-
case contracts_1.ZLinkFrameworkErrorKind.InternalFailure:
|
|
3588
|
-
default:
|
|
3589
|
-
return service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestFailed;
|
|
3706
|
+
return (0, framework_errors_internal_1.frameworkRelocationFailureCode)(contracts_1.ZLinkFrameworkErrorKind.InternalFailure);
|
|
3590
3707
|
}
|
|
3708
|
+
return (0, framework_errors_internal_1.frameworkRelocationFailureCode)(error);
|
|
3591
3709
|
}
|
|
3592
3710
|
function relocationStagingId(value) {
|
|
3593
3711
|
return `${value.relocation.high}:${value.relocation.low}:${value.targetAttemptGeneration}`;
|
|
@@ -3678,7 +3796,7 @@ function relocationFailed(request, failureCode) {
|
|
|
3678
3796
|
function validatePrepareEnvelope(request, envelope) {
|
|
3679
3797
|
if (!sameWireId(request.relocation, relocationWireId(envelope.aggregateId)) ||
|
|
3680
3798
|
request.applicationVersion !== envelope.applicationVersion ||
|
|
3681
|
-
|
|
3799
|
+
!sameRelocationObject(request.object, relocationObject(envelope))) {
|
|
3682
3800
|
throw new Error('Relocation Prepare does not match its immutable root identity.');
|
|
3683
3801
|
}
|
|
3684
3802
|
}
|
|
@@ -3688,14 +3806,9 @@ function validateTargetOneWayControl(stage, request, sourceNodeRid) {
|
|
|
3688
3806
|
!sameWireId(request.relocation, prepare.relocation) ||
|
|
3689
3807
|
request.targetAttemptGeneration !== prepare.targetAttemptGeneration ||
|
|
3690
3808
|
!sameCoordinator(request.coordinator, prepare.coordinator) ||
|
|
3691
|
-
|
|
3692
|
-
stringifyWire(request.kind === 'data' ? request.object : prepare.object)) {
|
|
3809
|
+
(request.kind === 'cutover' && !sameRelocationObject(request.object, prepare.object))) {
|
|
3693
3810
|
throw new Error('Relocation one-way control changed its exact Prepare fence.');
|
|
3694
3811
|
}
|
|
3695
|
-
if (request.kind === 'cutover' &&
|
|
3696
|
-
stringifyWire(request.object) !== stringifyWire(prepare.object)) {
|
|
3697
|
-
throw new Error('Relocation Cutover changed its prepared object.');
|
|
3698
|
-
}
|
|
3699
3812
|
}
|
|
3700
3813
|
function relocationPublication(prepare, envelope) {
|
|
3701
3814
|
// The direct transfer has no durable store root; the authority wrapper
|
|
@@ -3778,7 +3891,7 @@ function canonicalQueuedFrozenRecord(participant, message, coordinator, target)
|
|
|
3778
3891
|
...(packet.returnResponse ? { replyRouteId: BigInt(packet.source.replyRouteId) } : {}),
|
|
3779
3892
|
payload: {
|
|
3780
3893
|
packetName: '__zlink.actor.handoff.accepted',
|
|
3781
|
-
contentType:
|
|
3894
|
+
contentType: stream_wire_1.ZlinkStreamContentType.Json,
|
|
3782
3895
|
bytes: message.payload
|
|
3783
3896
|
}
|
|
3784
3897
|
});
|
|
@@ -3799,14 +3912,22 @@ function parseHandoffOperationId(value) {
|
|
|
3799
3912
|
function stringifyWire(value) {
|
|
3800
3913
|
return JSON.stringify(value, (_key, item) => (typeof item === 'bigint' ? item.toString() : item));
|
|
3801
3914
|
}
|
|
3915
|
+
function samePrepareIdentity(acceptedFingerprint, incoming) {
|
|
3916
|
+
const accepted = JSON.parse(acceptedFingerprint);
|
|
3917
|
+
return (accepted.sourceNodeRid === incoming.sourceNodeRid &&
|
|
3918
|
+
BigInt(accepted.sourceNodeGeneration) === incoming.sourceNodeGeneration &&
|
|
3919
|
+
sameCoordinator(accepted.coordinator, incoming.coordinator) &&
|
|
3920
|
+
sameRelocationTarget(accepted.target, incoming.target) &&
|
|
3921
|
+
sameRelocationObject(accepted.object, incoming.object));
|
|
3922
|
+
}
|
|
3802
3923
|
function validateControlResponse(request, response) {
|
|
3803
3924
|
if (request.kind !== 'prepare' ||
|
|
3804
3925
|
response.kind !== 'ready' ||
|
|
3805
3926
|
!sameWireId(response.relocation, request.relocation) ||
|
|
3806
3927
|
response.targetAttemptGeneration !== request.targetAttemptGeneration ||
|
|
3807
3928
|
!sameCoordinator(response.coordinator, request.coordinator) ||
|
|
3808
|
-
|
|
3809
|
-
|
|
3929
|
+
!sameRelocationTarget(response.target, request.target) ||
|
|
3930
|
+
!sameRelocationObject(response.object, request.object) ||
|
|
3810
3931
|
response.senderRole !== 'target') {
|
|
3811
3932
|
throw new Error('Relocation control response does not match the request fence.');
|
|
3812
3933
|
}
|
|
@@ -3823,78 +3944,16 @@ function validateControlFailureResponse(request, response) {
|
|
|
3823
3944
|
!sameWireId(response.relocation, request.relocation) ||
|
|
3824
3945
|
response.targetAttemptGeneration !== request.targetAttemptGeneration ||
|
|
3825
3946
|
!sameCoordinator(response.coordinator, request.coordinator) ||
|
|
3826
|
-
|
|
3827
|
-
|
|
3947
|
+
!sameRelocationTarget(response.target, request.target) ||
|
|
3948
|
+
!sameRelocationObject(response.object, request.object) ||
|
|
3828
3949
|
response.senderRole !== 'target') {
|
|
3829
3950
|
throw new Error('Relocation control response does not match the request fence.');
|
|
3830
3951
|
}
|
|
3831
3952
|
}
|
|
3832
|
-
/**
|
|
3833
|
-
* Maps a relocationFailed(53) wire failureCode (the generated
|
|
3834
|
-
* ServiceWireFrameworkErrorCode vocabulary) to its internal error kind, so a
|
|
3835
|
-
* source-side reject carries the same classification the target chose
|
|
3836
|
-
* instead of a generic Error. Direct 1:1 correspondence with the generated
|
|
3837
|
-
* names; an unrecognised or absent code falls back to RequestFailed
|
|
3838
|
-
* (InternalFailure) — the closest existing kind (spec 15 §"Failed.Kind").
|
|
3839
|
-
*/
|
|
3840
|
-
function relocationFailureCodeKind(failureCode) {
|
|
3841
|
-
switch (failureCode) {
|
|
3842
|
-
case 1:
|
|
3843
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorRouteNotFound;
|
|
3844
|
-
case 2:
|
|
3845
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorCreateFailed;
|
|
3846
|
-
case 3:
|
|
3847
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorAlreadyExists;
|
|
3848
|
-
case 4:
|
|
3849
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorTypeMismatch;
|
|
3850
|
-
case 5:
|
|
3851
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotCreateFailed;
|
|
3852
|
-
case 6:
|
|
3853
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotRouteNotFound;
|
|
3854
|
-
case 7:
|
|
3855
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotTypeMismatch;
|
|
3856
|
-
case 8:
|
|
3857
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorSessionNotBound;
|
|
3858
|
-
case 9:
|
|
3859
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.HandlerNotFound;
|
|
3860
|
-
case 10:
|
|
3861
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteHandlerNotFound;
|
|
3862
|
-
case 11:
|
|
3863
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorDispatchHandlerNotFound;
|
|
3864
|
-
case 12:
|
|
3865
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.PayloadDecodeFailed;
|
|
3866
|
-
case 13:
|
|
3867
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteNotConnected;
|
|
3868
|
-
case 14:
|
|
3869
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestTargetNotFound;
|
|
3870
|
-
case 15:
|
|
3871
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestRejected;
|
|
3872
|
-
case 16:
|
|
3873
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestProtocolError;
|
|
3874
|
-
case 18:
|
|
3875
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.WorkerQueueFull;
|
|
3876
|
-
case 19:
|
|
3877
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.WorkerTimedOut;
|
|
3878
|
-
case 20:
|
|
3879
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.WorkerFailed;
|
|
3880
|
-
case 21:
|
|
3881
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorLocationStale;
|
|
3882
|
-
case 22:
|
|
3883
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorCreateRejected;
|
|
3884
|
-
case 33:
|
|
3885
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotGenerationStale;
|
|
3886
|
-
case 34:
|
|
3887
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotMoving;
|
|
3888
|
-
case 35:
|
|
3889
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RelocationDataLost;
|
|
3890
|
-
case 17:
|
|
3891
|
-
default:
|
|
3892
|
-
return framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestFailed;
|
|
3893
|
-
}
|
|
3894
|
-
}
|
|
3895
3953
|
/** Builds the typed exception a Prepare waiter rejects with on an explicit Failed(53). */
|
|
3896
3954
|
function relocationFailureException(response) {
|
|
3897
|
-
return (0, framework_errors_internal_1.createInternalFrameworkException)(
|
|
3955
|
+
return (0, framework_errors_internal_1.createInternalFrameworkException)((0, framework_errors_internal_1.internalFrameworkErrorKindFromWireFailureCode)(response.failureCode) ??
|
|
3956
|
+
framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestFailed, `Relocation '${response.relocation.high}:${response.relocation.low}:` +
|
|
3898
3957
|
`${response.targetAttemptGeneration}' failed with wire failureCode ${response.failureCode}.`, true);
|
|
3899
3958
|
}
|
|
3900
3959
|
function controlAckKey(request) {
|
|
@@ -4023,7 +4082,7 @@ function queuedMessageU64(value, field) {
|
|
|
4023
4082
|
throw new TypeError(`Relocation Actor Message Follow ${field} is invalid.`);
|
|
4024
4083
|
}
|
|
4025
4084
|
const result = BigInt(value);
|
|
4026
|
-
if (result >
|
|
4085
|
+
if (result > stream_wire_1.UINT64_MAX) {
|
|
4027
4086
|
throw new TypeError(`Relocation Actor Message Follow ${field} is outside u64.`);
|
|
4028
4087
|
}
|
|
4029
4088
|
return result;
|
|
@@ -4043,6 +4102,14 @@ function toServiceTimer(value) {
|
|
|
4043
4102
|
pendingTicks: value.pendingTicks
|
|
4044
4103
|
};
|
|
4045
4104
|
}
|
|
4105
|
+
const PREPARE_SIDEBAND_MAGIC = 'ZLNI';
|
|
4106
|
+
const PREPARE_SIDEBAND_VERSION = 1;
|
|
4107
|
+
const PREPARE_SIDEBAND_HEADER_BYTES = 11;
|
|
4108
|
+
const PREPARE_SIDEBAND_VERSION_OFFSET = 4;
|
|
4109
|
+
const PREPARE_SIDEBAND_KEY_LENGTH_OFFSET = 5;
|
|
4110
|
+
const PREPARE_SIDEBAND_PAYLOAD_LENGTH_OFFSET = 7;
|
|
4111
|
+
const ACTOR_SESSION_JOURNAL_VERSION = 1;
|
|
4112
|
+
const SERVICE_RELOCATION_REPLY_PACKET_NAME = 'zlink.relocation.reply';
|
|
4046
4113
|
/**
|
|
4047
4114
|
* NODE-INTERNAL Prepare sideband. Frame zero remains the exact canonical
|
|
4048
4115
|
* command-40 schema record; each following ZLNI frame carries one sealed
|
|
@@ -4058,11 +4125,11 @@ function encodePrepareSideband(envelope) {
|
|
|
4058
4125
|
if (key.byteLength === 0 || key.byteLength > 0xffff || payload.byteLength > 0xffff_ffff) {
|
|
4059
4126
|
throw new TypeError('Bound-session relocation sideband is out of bounds.');
|
|
4060
4127
|
}
|
|
4061
|
-
const header = Buffer.allocUnsafe(
|
|
4062
|
-
header.write(
|
|
4063
|
-
header[
|
|
4064
|
-
header.writeUInt16BE(key.byteLength,
|
|
4065
|
-
header.writeUInt32BE(payload.byteLength,
|
|
4128
|
+
const header = Buffer.allocUnsafe(PREPARE_SIDEBAND_HEADER_BYTES);
|
|
4129
|
+
header.write(PREPARE_SIDEBAND_MAGIC, 0, 'ascii');
|
|
4130
|
+
header[PREPARE_SIDEBAND_VERSION_OFFSET] = PREPARE_SIDEBAND_VERSION;
|
|
4131
|
+
header.writeUInt16BE(key.byteLength, PREPARE_SIDEBAND_KEY_LENGTH_OFFSET);
|
|
4132
|
+
header.writeUInt32BE(payload.byteLength, PREPARE_SIDEBAND_PAYLOAD_LENGTH_OFFSET);
|
|
4066
4133
|
return Buffer.concat([header, key, payload]);
|
|
4067
4134
|
});
|
|
4068
4135
|
}
|
|
@@ -4071,20 +4138,27 @@ function decodePrepareSideband(frames) {
|
|
|
4071
4138
|
const keys = new Set();
|
|
4072
4139
|
for (const frame of frames) {
|
|
4073
4140
|
const bytes = Buffer.from(frame);
|
|
4074
|
-
if (bytes.byteLength <
|
|
4075
|
-
bytes.subarray(0,
|
|
4076
|
-
|
|
4141
|
+
if (bytes.byteLength < PREPARE_SIDEBAND_HEADER_BYTES ||
|
|
4142
|
+
bytes.subarray(0, PREPARE_SIDEBAND_VERSION_OFFSET).toString('ascii') !==
|
|
4143
|
+
PREPARE_SIDEBAND_MAGIC ||
|
|
4144
|
+
bytes[PREPARE_SIDEBAND_VERSION_OFFSET] !== PREPARE_SIDEBAND_VERSION) {
|
|
4077
4145
|
return undefined;
|
|
4078
4146
|
}
|
|
4079
|
-
const keyLength = bytes.readUInt16BE(
|
|
4080
|
-
const payloadLength = bytes.readUInt32BE(
|
|
4081
|
-
if (
|
|
4147
|
+
const keyLength = bytes.readUInt16BE(PREPARE_SIDEBAND_KEY_LENGTH_OFFSET);
|
|
4148
|
+
const payloadLength = bytes.readUInt32BE(PREPARE_SIDEBAND_PAYLOAD_LENGTH_OFFSET);
|
|
4149
|
+
if (PREPARE_SIDEBAND_HEADER_BYTES + keyLength + payloadLength !== bytes.byteLength ||
|
|
4150
|
+
keyLength === 0)
|
|
4082
4151
|
return undefined;
|
|
4083
|
-
const participantKey = bytes
|
|
4152
|
+
const participantKey = bytes
|
|
4153
|
+
.subarray(PREPARE_SIDEBAND_HEADER_BYTES, PREPARE_SIDEBAND_HEADER_BYTES + keyLength)
|
|
4154
|
+
.toString('utf8');
|
|
4084
4155
|
if (keys.has(participantKey))
|
|
4085
4156
|
return undefined;
|
|
4086
4157
|
keys.add(participantKey);
|
|
4087
|
-
result.push({
|
|
4158
|
+
result.push({
|
|
4159
|
+
participantKey,
|
|
4160
|
+
payload: Buffer.from(bytes.subarray(PREPARE_SIDEBAND_HEADER_BYTES + keyLength))
|
|
4161
|
+
});
|
|
4088
4162
|
}
|
|
4089
4163
|
return result;
|
|
4090
4164
|
}
|
|
@@ -4110,12 +4184,15 @@ function encodeActorSession(target) {
|
|
|
4110
4184
|
if (target === undefined)
|
|
4111
4185
|
return Buffer.alloc(0);
|
|
4112
4186
|
return Buffer.from(JSON.stringify({
|
|
4113
|
-
version:
|
|
4187
|
+
version: ACTOR_SESSION_JOURNAL_VERSION,
|
|
4114
4188
|
routerChannelId: target.routerChannelId,
|
|
4115
4189
|
targetNodeRid: String(target.targetNodeRid),
|
|
4116
4190
|
spotId: String(target.spotId),
|
|
4117
4191
|
sessionNodeRid: target.sessionNodeRid === undefined ? undefined : String(target.sessionNodeRid),
|
|
4118
4192
|
sessionRid: target.sessionRid === undefined ? undefined : String(target.sessionRid),
|
|
4193
|
+
sessionOwnerNodeGeneration: target.sessionOwnerNodeGeneration?.toString(),
|
|
4194
|
+
sessionOwnerId: target.sessionOwnerId,
|
|
4195
|
+
sessionOwnerLeaseGeneration: target.sessionOwnerLeaseGeneration?.toString(),
|
|
4119
4196
|
bindingGeneration: target.bindingGeneration?.toString(),
|
|
4120
4197
|
previousAuthorityOwnerGeneration: target.previousAuthorityOwnerGeneration?.toString(),
|
|
4121
4198
|
previousOwnerLeaseGeneration: target.previousOwnerLeaseGeneration?.toString(),
|
|
@@ -4140,9 +4217,11 @@ function encodeActorSession(target) {
|
|
|
4140
4217
|
}), 'utf8');
|
|
4141
4218
|
}
|
|
4142
4219
|
function decodeActorSession(payload) {
|
|
4220
|
+
if (payload.byteLength === 0)
|
|
4221
|
+
return undefined;
|
|
4143
4222
|
const value = JSON.parse(Buffer.from(payload).toString('utf8'));
|
|
4144
4223
|
const optionalBigInt = (field) => typeof value[field] === 'string' ? BigInt(value[field]) : undefined;
|
|
4145
|
-
if (value.version !==
|
|
4224
|
+
if (value.version !== ACTOR_SESSION_JOURNAL_VERSION ||
|
|
4146
4225
|
typeof value.routerChannelId !== 'string' ||
|
|
4147
4226
|
typeof value.targetNodeRid !== 'string' ||
|
|
4148
4227
|
typeof value.spotId !== 'string') {
|
|
@@ -4157,6 +4236,13 @@ function decodeActorSession(payload) {
|
|
|
4157
4236
|
? { sessionNodeRid: value.sessionNodeRid }
|
|
4158
4237
|
: {}),
|
|
4159
4238
|
...(typeof value.sessionRid === 'string' ? { sessionRid: value.sessionRid } : {}),
|
|
4239
|
+
...(optionalBigInt('sessionOwnerNodeGeneration') === undefined
|
|
4240
|
+
? {}
|
|
4241
|
+
: { sessionOwnerNodeGeneration: optionalBigInt('sessionOwnerNodeGeneration') }),
|
|
4242
|
+
...(typeof value.sessionOwnerId === 'string' ? { sessionOwnerId: value.sessionOwnerId } : {}),
|
|
4243
|
+
...(optionalBigInt('sessionOwnerLeaseGeneration') === undefined
|
|
4244
|
+
? {}
|
|
4245
|
+
: { sessionOwnerLeaseGeneration: optionalBigInt('sessionOwnerLeaseGeneration') }),
|
|
4160
4246
|
...(optionalBigInt('bindingGeneration') === undefined
|
|
4161
4247
|
? {}
|
|
4162
4248
|
: { bindingGeneration: optionalBigInt('bindingGeneration') }),
|
|
@@ -4255,3 +4341,9 @@ function addCapacity(left, right) {
|
|
|
4255
4341
|
})
|
|
4256
4342
|
};
|
|
4257
4343
|
}
|
|
4344
|
+
if ((0, state_lane_1.isStructuralGuardEnabled)()) {
|
|
4345
|
+
const relocateActorJoin = ZLinkHostServiceRelocationRuntime.prototype.relocateActorJoin;
|
|
4346
|
+
ZLinkHostServiceRelocationRuntime.prototype.relocateActorJoin = function (input) {
|
|
4347
|
+
return (0, state_lane_1.trackDiagnosticCompletion)(relocateActorJoin.call(this, input), `relocation join actor:${input.state.actorId}`);
|
|
4348
|
+
};
|
|
4349
|
+
}
|