@zlink-systems/framework 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkMessage.js +5 -5
- package/dist/contracts/Configuration/CodecContentType.js +5 -7
- package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
- package/dist/contracts/Configuration/EndpointNotation.js +4 -8
- package/dist/contracts/Configuration/Registration.js +14 -11
- package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
- package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
- package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
- package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
- package/dist/location-store-integration.js +16 -16
- package/dist/nest-integration.js +17 -11
- package/dist/runtime/abort.js +9 -5
- package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
- package/dist/runtime/actors/actor-authority-publication.js +18 -17
- package/dist/runtime/actors/actor-client.js +83 -63
- package/dist/runtime/actors/actor-context.js +28 -22
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
- package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
- package/dist/runtime/actors/actor-local-native-join.js +18 -19
- package/dist/runtime/actors/actor-mailbox.js +1 -1
- package/dist/runtime/actors/actor-message-follow-context.js +24 -21
- package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
- package/dist/runtime/actors/actor-remote-joiner.js +20 -17
- package/dist/runtime/actors/actor-remote-wire.js +6 -7
- package/dist/runtime/actors/actor-runtime-state.js +87 -81
- package/dist/runtime/actors/actor-transfer-registry.js +3 -5
- package/dist/runtime/actors/bound-session-wire.js +14 -9
- package/dist/runtime/actors/deferred-join-accepted-journal.js +160 -130
- package/dist/runtime/actors/index.js +2 -5
- package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
- package/dist/runtime/actors/post-commit-actor-location.js +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
- package/dist/runtime/admission.js +2 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
- package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
- package/dist/runtime/backend/contracts/index.d.ts +1 -0
- package/dist/runtime/backend/mesh-completion-table.js +1 -3
- package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
- package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +3 -0
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +134 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
- package/dist/runtime/backend/runtime-message.js +3 -3
- package/dist/runtime/backend/runtime-values.d.ts +2 -2
- package/dist/runtime/backend/runtime-values.js +4 -5
- package/dist/runtime/channels/channel-clients.js +27 -24
- package/dist/runtime/channels/channel-dispatch-pipeline.js +12 -20
- package/dist/runtime/channels/channel-dispatch-services.js +7 -4
- package/dist/runtime/channels/channel-dispatchers.js +9 -9
- package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
- package/dist/runtime/channels/channel-envelope.js +83 -47
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-receive-loops.js +20 -22
- package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
- package/dist/runtime/channels/channel-runtime-manager.js +18 -9
- package/dist/runtime/channels/channel-socket-registry.js +126 -123
- package/dist/runtime/channels/channel-transports.js +46 -42
- package/dist/runtime/channels/client-server-location-runtime.js +32 -40
- package/dist/runtime/channels/client-server-service-wire.js +29 -22
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -0
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -39
- package/dist/runtime/channels/fanout-location-runtime.js +34 -47
- package/dist/runtime/channels/fanout-service-wire.js +3 -5
- package/dist/runtime/channels/local-spot-route-transport.js +7 -1
- package/dist/runtime/channels/route-member-snapshot.js +3 -3
- package/dist/runtime/channels/source-spot-router.js +6 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
- package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +6 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
- package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
- package/dist/runtime/diagnostics/flow-context.js +2 -2
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +58 -42
- package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
- package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
- package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
- package/dist/runtime/execution/index.js +7 -6
- package/dist/runtime/execution/serial-execution-queue.js +12 -18
- package/dist/runtime/execution/state-lane.js +2 -2
- package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -27
- package/dist/runtime/foundation/event-loop-resources.js +4 -4
- package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +4 -2
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +169 -144
- package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
- package/dist/runtime/foundation/runtime-state-projections.js +22 -11
- package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
- package/dist/runtime/foundation/service-discovery-registry.js +35 -33
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
- package/dist/runtime/foundation/service-liveness-registry.js +16 -12
- package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
- package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
- package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +1 -0
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -0
- package/dist/runtime/foundation/service-stateful-runtime.js +461 -439
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
- package/dist/runtime/foundation/service-topology-registry.js +105 -96
- package/dist/runtime/foundation/service-weighted-selection.js +6 -11
- package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
- package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
- package/dist/runtime/framework-errors-internal.js +7 -10
- package/dist/runtime/handlers/handler-instance-scope.js +4 -5
- package/dist/runtime/handlers/index.js +3 -1
- package/dist/runtime/host/actor-packet-relay.js +74 -70
- package/dist/runtime/host/actor-placement-coordinator.js +29 -31
- package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
- package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
- package/dist/runtime/host/actor-transfer-runtime.js +176 -153
- package/dist/runtime/host/application-job-queue.js +18 -22
- package/dist/runtime/host/bound-session-relay.js +3 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
- package/dist/runtime/host/host-capacity-status.js +8 -4
- package/dist/runtime/host/index.js +245 -228
- package/dist/runtime/host/instance-activation-authority.js +93 -96
- package/dist/runtime/host/location-runtime-owner.js +16 -14
- package/dist/runtime/host/mesh-router-resolver.js +11 -13
- package/dist/runtime/host/relocation-direct-transfer.js +10 -9
- package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
- package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
- package/dist/runtime/host/remote-bound-session-relay.js +97 -73
- package/dist/runtime/host/route-mesh-runtime.js +64 -69
- package/dist/runtime/host/runtime-shutdown.js +1 -2
- package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
- package/dist/runtime/host/spot-address-transport.js +69 -71
- package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
- package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
- package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
- package/dist/runtime/locations/actor-location-claims.js +26 -20
- package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
- package/dist/runtime/locations/authority-key-codec.js +7 -7
- package/dist/runtime/locations/auto-connect-loop.js +3 -3
- package/dist/runtime/locations/auto-connect-planner.js +25 -19
- package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
- package/dist/runtime/locations/in-memory-authority-store.js +128 -118
- package/dist/runtime/locations/in-memory-location-store.js +195 -168
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
- package/dist/runtime/locations/key-codec.js +1 -1
- package/dist/runtime/locations/lease-tracker.js +23 -21
- package/dist/runtime/locations/lifecycle.js +4 -5
- package/dist/runtime/locations/location-store-repository.js +368 -324
- package/dist/runtime/locations/opaque-record-key.js +2 -2
- package/dist/runtime/locations/resolvers.js +73 -82
- package/dist/runtime/locations/runtime.js +68 -63
- package/dist/runtime/locations/spot-location-claims.js +39 -35
- package/dist/runtime/messaging/framework-json-v1.js +7 -7
- package/dist/runtime/messaging/packet-name.js +7 -6
- package/dist/runtime/messaging/payload-codec.js +21 -18
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
- package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +20 -18
- package/dist/runtime/routing-id.js +3 -5
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
- package/dist/runtime/spots/index.js +209 -220
- package/dist/runtime/spots/spot-activation-registry.js +15 -14
- package/dist/runtime/spots/spot-activation-state.js +17 -15
- package/dist/runtime/spots/spot-activation.js +33 -16
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
- package/dist/runtime/spots/spot-actor-membership.js +1 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +29 -21
- package/dist/runtime/spots/spot-actor-packet-drain.js +14 -10
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
- package/dist/runtime/spots/spot-closing.js +3 -7
- package/dist/runtime/spots/spot-context.js +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +13 -14
- package/dist/runtime/spots/spot-handle.js +6 -3
- package/dist/runtime/spots/spot-handler-registry.js +12 -12
- package/dist/runtime/spots/spot-manager-public.js +5 -6
- package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
- package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +79 -86
- package/dist/runtime/spots/spot-outbound.js +10 -14
- package/dist/runtime/spots/spot-remote-codec.js +22 -26
- package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
- package/dist/runtime/spots/spot-route-packet-dispatch.js +17 -15
- package/dist/runtime/spots/spot-route-replies.js +4 -6
- package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +2 -3
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
- package/dist/runtime/spots/spot-serial-executor.js +5 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
- package/dist/runtime/spots/spot-subscription-dispatch.js +6 -6
- package/dist/runtime/spots/spot-timer.js +26 -30
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
- package/dist/runtime/streams/actor-session-binding-registry.js +168 -148
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +20 -17
- package/dist/runtime/streams/bound-session-response-target.js +8 -1
- package/dist/runtime/streams/bound-session-service.d.ts +1 -0
- package/dist/runtime/streams/bound-session-service.js +14 -12
- package/dist/runtime/streams/index.js +28 -20
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +52 -31
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.d.ts +5 -1
- package/dist/runtime/streams/protocol.js +68 -20
- package/dist/runtime/streams/session-actor-coordinator.js +37 -41
- package/dist/runtime/streams/session-context.d.ts +9 -2
- package/dist/runtime/streams/session-context.js +50 -32
- package/dist/runtime/streams/session-local-actors.d.ts +3 -1
- package/dist/runtime/streams/session-local-actors.js +17 -2
- package/dist/runtime/streams/session-provider.js +2 -2
- package/dist/runtime/streams/session-serial-executor.js +1 -2
- package/dist/runtime/streams/stream-frame-factory.d.ts +1 -1
- package/dist/runtime/streams/stream-frame-factory.js +14 -7
- package/dist/runtime/streams/stream-session-runtime.js +112 -78
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +3 -3
- package/src/contracts/Channels/RouteCalls.ts +6 -1
- package/src/contracts/Common/ZLinkMessage.ts +5 -5
- package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
- package/src/contracts/Configuration/Builders.ts +14 -14
- package/src/contracts/Configuration/CodecContentType.ts +8 -10
- package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
- package/src/contracts/Configuration/EndpointNotation.ts +11 -11
- package/src/contracts/Configuration/ObjectRoles.ts +1 -3
- package/src/contracts/Configuration/Registration.ts +46 -17
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
- package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
- package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
- package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
- package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
- package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
- package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
- package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -6
- package/src/contracts/Errors/index.ts +1 -4
- package/src/contracts/Handlers/Attributes.ts +15 -9
- package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
- package/src/contracts/Handlers/JsonContract.ts +53 -19
- package/src/contracts/Locations/ActorTransfer.ts +1 -5
- package/src/contracts/Locations/Authority.ts +4 -11
- package/src/contracts/Locations/Keys.ts +6 -1
- package/src/contracts/Locations/Options.ts +3 -2
- package/src/contracts/Locations/RelocationStore.ts +1 -4
- package/src/contracts/Locations/Resolvers.ts +5 -5
- package/src/contracts/Locations/RuntimeQuery.ts +6 -2
- package/src/contracts/Locations/Stores.ts +1 -2
- package/src/contracts/Locations/index.ts +2 -8
- package/src/contracts/RouteMesh/Contracts.ts +1 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
- package/src/contracts/Spots/Contracts.ts +2 -8
- package/src/contracts/Spots/SpotKind.ts +16 -8
- package/src/contracts/Spots/ZLinkSpot.ts +8 -11
- package/src/contracts/Streams/IZLinkSession.ts +2 -2
- package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
- package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
- package/src/internal.ts +5 -4
- package/src/location-store-integration.ts +24 -16
- package/src/nest-integration.ts +40 -25
- package/src/runtime/abort.ts +10 -4
- package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
- package/src/runtime/actors/actor-authority-publication.ts +92 -77
- package/src/runtime/actors/actor-client.ts +162 -133
- package/src/runtime/actors/actor-context.ts +142 -134
- package/src/runtime/actors/actor-creation.ts +47 -44
- package/src/runtime/actors/actor-execution-context.ts +6 -4
- package/src/runtime/actors/actor-handoff.ts +269 -293
- package/src/runtime/actors/actor-join-deferred-scope.ts +1 -32
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
- package/src/runtime/actors/actor-local-native-join.ts +131 -159
- package/src/runtime/actors/actor-mailbox.ts +16 -19
- package/src/runtime/actors/actor-message-follow-context.ts +46 -36
- package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
- package/src/runtime/actors/actor-remote-joiner.ts +50 -54
- package/src/runtime/actors/actor-remote-wire.ts +9 -13
- package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
- package/src/runtime/actors/actor-runtime-state.ts +127 -124
- package/src/runtime/actors/actor-transfer-registry.ts +9 -14
- package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
- package/src/runtime/actors/bound-session-wire.ts +37 -17
- package/src/runtime/actors/deferred-join-accepted-journal.ts +353 -326
- package/src/runtime/actors/index.ts +43 -86
- package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
- package/src/runtime/actors/post-commit-actor-location.ts +30 -23
- package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
- package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
- package/src/runtime/admission.ts +9 -9
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
- package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
- package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
- package/src/runtime/backend/contracts/index.ts +77 -52
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
- package/src/runtime/backend/mesh-completion-table.ts +6 -9
- package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
- package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
- package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
- package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +370 -390
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
- package/src/runtime/backend/runtime-message.ts +5 -3
- package/src/runtime/backend/runtime-values.ts +10 -7
- package/src/runtime/channels/channel-autoconnect.ts +1 -4
- package/src/runtime/channels/channel-clients.ts +93 -73
- package/src/runtime/channels/channel-dispatch-pipeline.ts +44 -44
- package/src/runtime/channels/channel-dispatch-services.ts +51 -49
- package/src/runtime/channels/channel-dispatchers.ts +152 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
- package/src/runtime/channels/channel-envelope.ts +256 -150
- package/src/runtime/channels/channel-multipart.ts +13 -5
- package/src/runtime/channels/channel-outbound-operations.ts +37 -41
- package/src/runtime/channels/channel-receive-loops.ts +102 -98
- package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
- package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
- package/src/runtime/channels/channel-runtime-manager.ts +63 -37
- package/src/runtime/channels/channel-socket-options.ts +3 -10
- package/src/runtime/channels/channel-socket-registry.ts +331 -273
- package/src/runtime/channels/channel-transports.ts +218 -206
- package/src/runtime/channels/client-server-location-runtime.ts +116 -100
- package/src/runtime/channels/client-server-service-wire.ts +37 -36
- package/src/runtime/channels/dispatch-error-reporter.ts +12 -47
- package/src/runtime/channels/fanout-location-runtime.ts +91 -94
- package/src/runtime/channels/fanout-service-wire.ts +5 -12
- package/src/runtime/channels/handler-filter-scope.ts +1 -4
- package/src/runtime/channels/index.ts +1 -4
- package/src/runtime/channels/local-spot-route-transport.ts +20 -5
- package/src/runtime/channels/route-member-snapshot.ts +11 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
- package/src/runtime/channels/source-spot-router.ts +26 -22
- package/src/runtime/channels/spot-direct-envelope.ts +10 -8
- package/src/runtime/channels/spot-node-route-transport.ts +13 -16
- package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
- package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
- package/src/runtime/codecs/index.ts +3 -2
- package/src/runtime/diagnostics/dispatch-error-details.ts +62 -0
- package/src/runtime/diagnostics/flow-context.ts +18 -7
- package/src/runtime/diagnostics/index.ts +96 -61
- package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
- package/src/runtime/diagnostics/message-flow.ts +107 -79
- package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
- package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
- package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
- package/src/runtime/execution/index.ts +18 -26
- package/src/runtime/execution/serial-execution-queue.ts +31 -40
- package/src/runtime/execution/state-lane.ts +2 -2
- package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -55
- package/src/runtime/foundation/event-loop-resources.ts +8 -4
- package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
- package/src/runtime/foundation/operation-identity.ts +1 -2
- package/src/runtime/foundation/operation-registry.ts +8 -2
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +364 -396
- package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
- package/src/runtime/foundation/runtime-state-projections.ts +24 -23
- package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
- package/src/runtime/foundation/service-discovery-registry.ts +67 -59
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
- package/src/runtime/foundation/service-liveness-registry.ts +18 -13
- package/src/runtime/foundation/service-mailbox.ts +14 -14
- package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
- package/src/runtime/foundation/service-metadata-codec.ts +2 -9
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
- package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
- package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
- package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
- package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1233 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +170 -159
- package/src/runtime/foundation/service-weighted-selection.ts +9 -15
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
- package/src/runtime/framework-errors-internal.ts +31 -30
- package/src/runtime/handlers/handler-instance-scope.ts +18 -29
- package/src/runtime/handlers/index.ts +18 -8
- package/src/runtime/host/actor-packet-relay.ts +290 -261
- package/src/runtime/host/actor-placement-coordinator.ts +165 -150
- package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
- package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
- package/src/runtime/host/actor-transfer-runtime.ts +391 -395
- package/src/runtime/host/application-job-queue.ts +32 -48
- package/src/runtime/host/bound-session-relay.ts +7 -9
- package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
- package/src/runtime/host/host-capacity-status.ts +10 -9
- package/src/runtime/host/index.ts +861 -789
- package/src/runtime/host/instance-activation-authority.ts +125 -143
- package/src/runtime/host/location-runtime-owner.ts +38 -26
- package/src/runtime/host/mesh-router-resolver.ts +30 -23
- package/src/runtime/host/relocation-direct-transfer.ts +15 -15
- package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
- package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
- package/src/runtime/host/remote-bound-session-relay.ts +274 -247
- package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
- package/src/runtime/host/route-mesh-runtime.ts +227 -181
- package/src/runtime/host/runtime-shutdown.ts +4 -3
- package/src/runtime/host/service-relocation-control.ts +14 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
- package/src/runtime/host/spot-address-transport.ts +284 -237
- package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
- package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
- package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
- package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
- package/src/runtime/locations/actor-location-claims.ts +61 -49
- package/src/runtime/locations/actor-session-route-claims.ts +1 -4
- package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
- package/src/runtime/locations/authority-key-codec.ts +13 -10
- package/src/runtime/locations/auto-connect-loop.ts +14 -11
- package/src/runtime/locations/auto-connect-planner.ts +42 -31
- package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
- package/src/runtime/locations/canonical-codec.ts +3 -1
- package/src/runtime/locations/creation-operation-id.ts +4 -3
- package/src/runtime/locations/domain-store-contract.ts +13 -7
- package/src/runtime/locations/in-memory-authority-store.ts +232 -199
- package/src/runtime/locations/in-memory-location-store.ts +432 -250
- package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
- package/src/runtime/locations/internal-store-contracts.ts +95 -38
- package/src/runtime/locations/key-codec.ts +3 -4
- package/src/runtime/locations/lease-tracker.ts +36 -27
- package/src/runtime/locations/lifecycle-runtime.ts +15 -3
- package/src/runtime/locations/lifecycle.ts +33 -28
- package/src/runtime/locations/location-store-repository.ts +1329 -1185
- package/src/runtime/locations/opaque-record-key.ts +4 -9
- package/src/runtime/locations/resolvers.ts +201 -178
- package/src/runtime/locations/runtime.ts +251 -159
- package/src/runtime/locations/spot-location-claims.ts +110 -112
- package/src/runtime/messaging/creation-payload-codec.ts +4 -1
- package/src/runtime/messaging/framework-json-v1.ts +34 -15
- package/src/runtime/messaging/packet-name.ts +8 -6
- package/src/runtime/messaging/payload-codec.ts +70 -50
- package/src/runtime/messaging/submission-result.ts +6 -9
- package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +19 -18
- package/src/runtime/routing-id.ts +10 -7
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
- package/src/runtime/spots/index.ts +595 -564
- package/src/runtime/spots/spot-activation-registry.ts +38 -34
- package/src/runtime/spots/spot-activation-state.ts +43 -51
- package/src/runtime/spots/spot-activation.ts +179 -116
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
- package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
- package/src/runtime/spots/spot-actor-membership.ts +25 -27
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +196 -148
- package/src/runtime/spots/spot-actor-packet-drain.ts +56 -42
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
- package/src/runtime/spots/spot-closing.ts +11 -12
- package/src/runtime/spots/spot-context.ts +46 -26
- package/src/runtime/spots/spot-entry-activation.ts +84 -65
- package/src/runtime/spots/spot-handle.ts +17 -15
- package/src/runtime/spots/spot-handler-registry.ts +44 -31
- package/src/runtime/spots/spot-location-claim.ts +5 -4
- package/src/runtime/spots/spot-manager-public.ts +62 -82
- package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
- package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
- package/src/runtime/spots/spot-node-runtime-manager.ts +235 -222
- package/src/runtime/spots/spot-outbound.ts +47 -59
- package/src/runtime/spots/spot-publisher-transport.ts +5 -4
- package/src/runtime/spots/spot-remote-codec.ts +66 -65
- package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
- package/src/runtime/spots/spot-route-packet-dispatch.ts +129 -95
- package/src/runtime/spots/spot-route-replies.ts +23 -24
- package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
- package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +13 -18
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
- package/src/runtime/spots/spot-routing-internal.ts +1 -4
- package/src/runtime/spots/spot-runtime-ports.ts +5 -5
- package/src/runtime/spots/spot-serial-executor.ts +5 -9
- package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
- package/src/runtime/spots/spot-subscription-dispatch.ts +58 -47
- package/src/runtime/spots/spot-timer.ts +103 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +421 -292
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +8 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +60 -50
- package/src/runtime/streams/bound-session-response-target.ts +39 -9
- package/src/runtime/streams/bound-session-service.ts +52 -42
- package/src/runtime/streams/index.ts +183 -100
- package/src/runtime/streams/managed-stream.ts +123 -90
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +115 -46
- package/src/runtime/streams/session-actor-coordinator.ts +109 -93
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +96 -51
- package/src/runtime/streams/session-local-actors.ts +19 -3
- package/src/runtime/streams/session-provider.ts +5 -7
- package/src/runtime/streams/session-serial-executor.ts +7 -6
- package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
- package/src/runtime/streams/stream-frame-factory.ts +59 -40
- package/src/runtime/streams/stream-session-runtime.ts +317 -214
- package/src/runtime/workers/index.ts +68 -29
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ZLinkFrameworkInternalErrorKind,
|
|
3
|
+
createInternalFrameworkException,
|
|
4
|
+
internalFrameworkErrorKind
|
|
5
|
+
} from '../framework-errors-internal';
|
|
2
6
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
3
7
|
import type { ActorRef, RoutingId } from '../../contracts';
|
|
4
|
-
import {
|
|
5
|
-
ZLinkFrameworkException
|
|
6
|
-
} from '../../contracts';
|
|
8
|
+
import { ZLinkFrameworkException } from '../../contracts';
|
|
7
9
|
import type { Message } from '../../contracts/Common/Message';
|
|
8
10
|
import type { ZLinkMessageFollowOrigin } from '../foundation/service-runtime-contracts';
|
|
9
11
|
import {
|
|
@@ -13,10 +15,7 @@ import {
|
|
|
13
15
|
import type { ZLinkSpotRouteTarget } from '../spots/spot-routing-internal';
|
|
14
16
|
import { encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
|
|
15
17
|
import { releaseApplicationJobPermitForDurableHandoff } from '../application-jobs/application-job-queue-scope';
|
|
16
|
-
import {
|
|
17
|
-
decodeActorRequestDeadlineUnixMs,
|
|
18
|
-
decodeStreamHeader
|
|
19
|
-
} from '../streams/protocol';
|
|
18
|
+
import { decodeActorRequestDeadlineUnixMs, decodeStreamHeader } from '../streams/protocol';
|
|
20
19
|
import type { ZLinkActorRoutedJoinTransport } from './actor-routed-join-transport';
|
|
21
20
|
import { requestRoutedJsonReply } from './actor-routed-json-request';
|
|
22
21
|
import type { ZLinkRemoteBoundSessionTarget } from './actor-runtime-state';
|
|
@@ -77,9 +76,7 @@ export interface ZLinkActorHandoffRequestSource {
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
export type ZLinkActorHandoffTerminalAck =
|
|
80
|
-
| '
|
|
81
|
-
| 'alreadyTerminal'
|
|
82
|
-
| 'notAcknowledged';
|
|
79
|
+
'terminalReceived' | 'alreadyTerminal' | 'notAcknowledged';
|
|
83
80
|
|
|
84
81
|
export interface ZLinkActorHandoffTerminalAcceptance {
|
|
85
82
|
readonly status: ZLinkActorHandoffTerminalAck;
|
|
@@ -101,9 +98,7 @@ export type ZLinkActorHandoffDispatch = (
|
|
|
101
98
|
fallbackActorRef?: ActorRef
|
|
102
99
|
) => Promise<unknown>;
|
|
103
100
|
|
|
104
|
-
export type ZLinkActorHandoffReplayAdmission = <T>(
|
|
105
|
-
operation: () => Promise<T>
|
|
106
|
-
) => Promise<T>;
|
|
101
|
+
export type ZLinkActorHandoffReplayAdmission = <T>(operation: () => Promise<T>) => Promise<T>;
|
|
107
102
|
|
|
108
103
|
export interface ZLinkActorHandoffPreparedReplayAdmission {
|
|
109
104
|
run<T>(operation: () => Promise<T>): Promise<T>;
|
|
@@ -216,12 +211,15 @@ interface MessageFollowRoute {
|
|
|
216
211
|
tail: Promise<void>;
|
|
217
212
|
queuedMessages: number;
|
|
218
213
|
queuedBytes: number;
|
|
219
|
-
readonly operations: Map<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
214
|
+
readonly operations: Map<
|
|
215
|
+
string,
|
|
216
|
+
{
|
|
217
|
+
readonly checksum: string;
|
|
218
|
+
readonly request: boolean;
|
|
219
|
+
readonly replyRouteId?: string;
|
|
220
|
+
readonly result: Promise<unknown>;
|
|
221
|
+
}
|
|
222
|
+
>;
|
|
225
223
|
}
|
|
226
224
|
|
|
227
225
|
export interface ZLinkActorHandoffCoordinatorOptions {
|
|
@@ -262,9 +260,7 @@ export interface ZLinkActorHandoffCoordinatorOptions {
|
|
|
262
260
|
readonly authorityOwnerGeneration: bigint;
|
|
263
261
|
};
|
|
264
262
|
readonly validateReplySource: (source: ReplySourceEvidence) => boolean;
|
|
265
|
-
readonly currentOwnerFence?: (
|
|
266
|
-
actorId: string
|
|
267
|
-
) => ZLinkActorMessageFollowOwnerFence | undefined;
|
|
263
|
+
readonly currentOwnerFence?: (actorId: string) => ZLinkActorMessageFollowOwnerFence | undefined;
|
|
268
264
|
}
|
|
269
265
|
|
|
270
266
|
function requireExactTargetOwnerFence(
|
|
@@ -299,35 +295,27 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
299
295
|
private readonly replyRoutes = new Map<string, ReplyRoute>();
|
|
300
296
|
|
|
301
297
|
constructor(private readonly options: ZLinkActorHandoffCoordinatorOptions) {
|
|
302
|
-
this.messageFollowDurationMs =
|
|
298
|
+
this.messageFollowDurationMs =
|
|
299
|
+
options.messageFollowDurationMs ?? DEFAULT_MESSAGE_FOLLOW_DURATION_MS;
|
|
303
300
|
}
|
|
304
301
|
|
|
305
|
-
begin(
|
|
306
|
-
actorId: string,
|
|
307
|
-
oldGeneration: bigint
|
|
308
|
-
): void {
|
|
302
|
+
begin(actorId: string, oldGeneration: bigint): void {
|
|
309
303
|
this.startHandoff(actorId, oldGeneration, { phase: 'relocating' });
|
|
310
304
|
}
|
|
311
305
|
|
|
312
|
-
beginProvisional(
|
|
313
|
-
actorId:
|
|
314
|
-
operationId: string,
|
|
315
|
-
oldGeneration: bigint
|
|
316
|
-
): void {
|
|
317
|
-
this.startHandoff(
|
|
318
|
-
actorId,
|
|
319
|
-
oldGeneration,
|
|
320
|
-
{ phase: 'provisional', operationId }
|
|
321
|
-
);
|
|
306
|
+
beginProvisional(actorId: string, operationId: string, oldGeneration: bigint): void {
|
|
307
|
+
this.startHandoff(actorId, oldGeneration, { phase: 'provisional', operationId });
|
|
322
308
|
}
|
|
323
309
|
|
|
324
310
|
private startHandoff(
|
|
325
311
|
actorId: string,
|
|
326
312
|
oldGeneration: bigint,
|
|
327
|
-
transition:
|
|
328
|
-
readonly phase: '
|
|
329
|
-
|
|
330
|
-
|
|
313
|
+
transition:
|
|
314
|
+
| { readonly phase: 'relocating' }
|
|
315
|
+
| {
|
|
316
|
+
readonly phase: 'provisional';
|
|
317
|
+
readonly operationId: string;
|
|
318
|
+
}
|
|
331
319
|
): void {
|
|
332
320
|
if (this.active.has(actorId)) {
|
|
333
321
|
throw new Error(`Actor '${actorId}' already has an active packet handoff.`);
|
|
@@ -336,10 +324,14 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
336
324
|
throw new Error(`Actor '${actorId}' handoff requires a positive source ObjectGeneration.`);
|
|
337
325
|
}
|
|
338
326
|
const source = this.options.requestSource(actorId);
|
|
339
|
-
if (
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
327
|
+
if (
|
|
328
|
+
source.meshName.length === 0 ||
|
|
329
|
+
source.ownerId.length === 0 ||
|
|
330
|
+
source.ownerLeaseGeneration <= 0n ||
|
|
331
|
+
source.nodeRid.length === 0 ||
|
|
332
|
+
source.nodeGeneration <= 0n ||
|
|
333
|
+
source.authorityOwnerGeneration <= 0n
|
|
334
|
+
) {
|
|
343
335
|
throw new Error(`Actor '${actorId}' handoff requires an exact source owner fence.`);
|
|
344
336
|
}
|
|
345
337
|
if (source.objectGeneration !== oldGeneration) {
|
|
@@ -361,8 +353,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
361
353
|
ownerId: source.ownerId,
|
|
362
354
|
ownerLeaseGeneration: source.ownerLeaseGeneration,
|
|
363
355
|
nodeRid: sourceOwner.nodeRid,
|
|
364
|
-
nodeRidHex: sourceOwner.nodeRidHex
|
|
365
|
-
?? encodeRoutingIdStorageHex(sourceOwner.nodeRid),
|
|
356
|
+
nodeRidHex: sourceOwner.nodeRidHex ?? encodeRoutingIdStorageHex(sourceOwner.nodeRid),
|
|
366
357
|
nodeGeneration: source.nodeGeneration,
|
|
367
358
|
authorityOwnerGeneration: source.authorityOwnerGeneration
|
|
368
359
|
});
|
|
@@ -421,12 +412,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
421
412
|
if (handoff.operationId !== operationId) {
|
|
422
413
|
throw new Error(`Actor '${actorId}' packet handoff belongs to another operation.`);
|
|
423
414
|
}
|
|
424
|
-
await this.releaseHandoff(
|
|
425
|
-
actorId,
|
|
426
|
-
handoff,
|
|
427
|
-
dispatch ?? handoff.replay,
|
|
428
|
-
admission
|
|
429
|
-
);
|
|
415
|
+
await this.releaseHandoff(actorId, handoff, dispatch ?? handoff.replay, admission);
|
|
430
416
|
}
|
|
431
417
|
|
|
432
418
|
async releaseCanceled(
|
|
@@ -509,7 +495,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
509
495
|
release.startOpen = true;
|
|
510
496
|
this.finishPrefixReleaseIfIdle(actorId, handoff, release);
|
|
511
497
|
},
|
|
512
|
-
error => {
|
|
498
|
+
(error) => {
|
|
513
499
|
release.startOpen = true;
|
|
514
500
|
if (handoff.pending.length === 0) release.errors.push(error);
|
|
515
501
|
this.finishPrefixReleaseIfIdle(actorId, handoff, release);
|
|
@@ -539,8 +525,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
539
525
|
const pending = handoff.pending.slice(begin, end);
|
|
540
526
|
let admitted: ZLinkActorHandoffPrefixAdmission;
|
|
541
527
|
try {
|
|
542
|
-
admitted = release.queue(pending.map(record =>
|
|
543
|
-
this.createPrefixRecord(record, release)));
|
|
528
|
+
admitted = release.queue(pending.map((record) => this.createPrefixRecord(record, release)));
|
|
544
529
|
} catch (error) {
|
|
545
530
|
this.failUnqueuedPrefix(handoff, release, error);
|
|
546
531
|
throw error;
|
|
@@ -549,7 +534,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
549
534
|
release.inFlight += 1;
|
|
550
535
|
void admitted.terminal.then(
|
|
551
536
|
() => this.completePrefixBatch(actorId, handoff, release),
|
|
552
|
-
error => {
|
|
537
|
+
(error) => {
|
|
553
538
|
release.errors.push(error);
|
|
554
539
|
this.completePrefixBatch(actorId, handoff, release);
|
|
555
540
|
}
|
|
@@ -568,7 +553,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
568
553
|
return {
|
|
569
554
|
payloadBytes: packetBytes(pending.packet),
|
|
570
555
|
preparation: {
|
|
571
|
-
prepare: async signal => {
|
|
556
|
+
prepare: async (signal) => {
|
|
572
557
|
try {
|
|
573
558
|
await waitForHandoffReplayStart(release.start, signal);
|
|
574
559
|
if (release.preparation !== undefined) {
|
|
@@ -586,10 +571,11 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
586
571
|
},
|
|
587
572
|
cancel
|
|
588
573
|
},
|
|
589
|
-
drain: async replay => {
|
|
590
|
-
const admission =
|
|
591
|
-
|
|
592
|
-
|
|
574
|
+
drain: async (replay) => {
|
|
575
|
+
const admission =
|
|
576
|
+
prepared === undefined
|
|
577
|
+
? undefined
|
|
578
|
+
: <T>(operation: () => Promise<T>) => prepared!.run(operation);
|
|
593
579
|
try {
|
|
594
580
|
await this.replayReleasedPending(pending, replay, admission);
|
|
595
581
|
} finally {
|
|
@@ -621,9 +607,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
621
607
|
handoff: ActiveHandoff,
|
|
622
608
|
release: ActivePrefixRelease
|
|
623
609
|
): void {
|
|
624
|
-
if (!release.startOpen
|
|
625
|
-
|
|
626
|
-
|| release.cursor !== handoff.pending.length) return;
|
|
610
|
+
if (!release.startOpen || release.inFlight !== 0 || release.cursor !== handoff.pending.length)
|
|
611
|
+
return;
|
|
627
612
|
if (handoff.prefixRelease === release) handoff.prefixRelease = undefined;
|
|
628
613
|
if (this.active.get(actorId) === handoff) this.active.delete(actorId);
|
|
629
614
|
if (release.errors.length === 0) {
|
|
@@ -631,10 +616,9 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
631
616
|
} else if (release.errors.length === 1) {
|
|
632
617
|
release.reject(release.errors[0]);
|
|
633
618
|
} else {
|
|
634
|
-
release.reject(
|
|
635
|
-
release.errors,
|
|
636
|
-
|
|
637
|
-
));
|
|
619
|
+
release.reject(
|
|
620
|
+
new AggregateError(release.errors, `Actor '${actorId}' durable prefix replay failed.`)
|
|
621
|
+
);
|
|
638
622
|
}
|
|
639
623
|
}
|
|
640
624
|
|
|
@@ -666,8 +650,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
666
650
|
// the drained tail. A shared task makes duplicate release callbacks join
|
|
667
651
|
// the same drain instead of replaying a record twice.
|
|
668
652
|
handoff.phase = 'releasing';
|
|
669
|
-
const releaseTask = Promise.resolve().then(
|
|
670
|
-
|
|
653
|
+
const releaseTask = Promise.resolve().then(() =>
|
|
654
|
+
this.replayReleasedBacklog(actorId, handoff, replay, admission)
|
|
671
655
|
);
|
|
672
656
|
handoff.releaseTask = releaseTask;
|
|
673
657
|
await releaseTask;
|
|
@@ -682,7 +666,9 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
682
666
|
try {
|
|
683
667
|
if (handoff.pending.length === 0) return;
|
|
684
668
|
if (replay === undefined) {
|
|
685
|
-
const error = new Error(
|
|
669
|
+
const error = new Error(
|
|
670
|
+
`Actor '${actorId}' provisional packet handoff has no replay target.`
|
|
671
|
+
);
|
|
686
672
|
for (const pending of handoff.pending) {
|
|
687
673
|
if (pending.packet.source !== undefined) {
|
|
688
674
|
this.removeReplyRoute(pending.packet.source.replyRouteId);
|
|
@@ -720,12 +706,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
720
706
|
const results = await replayActorHandoffBacklog(
|
|
721
707
|
[pending.packet],
|
|
722
708
|
(parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) => {
|
|
723
|
-
const operation = () =>
|
|
724
|
-
parts,
|
|
725
|
-
returnResponse,
|
|
726
|
-
remoteBoundSessionTarget,
|
|
727
|
-
fallbackActorRef
|
|
728
|
-
);
|
|
709
|
+
const operation = () =>
|
|
710
|
+
replay(parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
729
711
|
return admission === undefined ? operation() : admission(operation);
|
|
730
712
|
}
|
|
731
713
|
);
|
|
@@ -737,12 +719,13 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
737
719
|
pending.resolve?.(result.response);
|
|
738
720
|
return;
|
|
739
721
|
}
|
|
740
|
-
const error =
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
722
|
+
const error =
|
|
723
|
+
result.errorKind === undefined
|
|
724
|
+
? new Error(result.error ?? 'Actor provisional packet replay failed.')
|
|
725
|
+
: createInternalFrameworkException(
|
|
726
|
+
result.errorKind,
|
|
727
|
+
result.error ?? 'Actor provisional packet replay failed.'
|
|
728
|
+
);
|
|
746
729
|
if (pending.reject !== undefined) {
|
|
747
730
|
pending.reject(error);
|
|
748
731
|
return;
|
|
@@ -782,13 +765,16 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
782
765
|
provisionalReplay?: ZLinkActorHandoffDispatch
|
|
783
766
|
): Promise<unknown> | undefined {
|
|
784
767
|
const incomingContext = actorMessageFollowContext(fallbackActorRef);
|
|
785
|
-
const originalDeadlineUnixMs =
|
|
786
|
-
?? incomingContext?.deadlineUnixMs
|
|
787
|
-
?? packetDeadlineUnixMs(parts);
|
|
768
|
+
const originalDeadlineUnixMs =
|
|
769
|
+
deadlineUnixMs ?? incomingContext?.deadlineUnixMs ?? packetDeadlineUnixMs(parts);
|
|
788
770
|
const handoff = this.active.get(actorId);
|
|
789
771
|
if (handoff !== undefined) {
|
|
790
772
|
if (parts.length < 2) return Promise.resolve(undefined);
|
|
791
|
-
if (
|
|
773
|
+
if (
|
|
774
|
+
handoff.connectionBoundSealed &&
|
|
775
|
+
!returnResponse &&
|
|
776
|
+
remoteBoundSessionTarget !== undefined
|
|
777
|
+
) {
|
|
792
778
|
// The Session route seal already fixed the accepted high water. A
|
|
793
779
|
// send whose lifetime is only the Session connection can no longer
|
|
794
780
|
// drain here and must never enter the durable frozen journal, so the
|
|
@@ -798,13 +784,15 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
798
784
|
if (handoff.phase === 'provisional' && handoff.replay === undefined) {
|
|
799
785
|
handoff.replay = provisionalReplay;
|
|
800
786
|
}
|
|
801
|
-
const context =
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
787
|
+
const context =
|
|
788
|
+
incomingContext ??
|
|
789
|
+
this.createInitialIngressContext(
|
|
790
|
+
handoff.sourceOwner,
|
|
791
|
+
handoff.oldGeneration,
|
|
792
|
+
parts,
|
|
793
|
+
returnResponse,
|
|
794
|
+
originalDeadlineUnixMs
|
|
795
|
+
);
|
|
808
796
|
try {
|
|
809
797
|
this.validateContext(actorId, context, parts, returnResponse, fallbackActorRef);
|
|
810
798
|
} catch (error) {
|
|
@@ -841,10 +829,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
841
829
|
return Promise.resolve(undefined);
|
|
842
830
|
}
|
|
843
831
|
const result = new Promise((resolve, reject) => {
|
|
844
|
-
const source = this.captureRequestSource(
|
|
845
|
-
handoff.sourceEvidence,
|
|
846
|
-
context.replyRouteId
|
|
847
|
-
);
|
|
832
|
+
const source = this.captureRequestSource(handoff.sourceEvidence, context.replyRouteId);
|
|
848
833
|
const requestPacket = { ...packet, source };
|
|
849
834
|
const route: ReplyRoute = {
|
|
850
835
|
actorId,
|
|
@@ -859,7 +844,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
859
844
|
route.deadline = setTimeout(() => {
|
|
860
845
|
if (this.replyRoutes.get(source.replyRouteId) !== route) return;
|
|
861
846
|
this.replyRoutes.delete(source.replyRouteId);
|
|
862
|
-
if (!route.delivered)
|
|
847
|
+
if (!route.delivered)
|
|
848
|
+
route.reject(new Error('Relocation reply route retention expired.'));
|
|
863
849
|
}, RELOCATION_REPLY_RETENTION_MS);
|
|
864
850
|
route.deadline.unref();
|
|
865
851
|
this.replyRoutes.set(source.replyRouteId, route);
|
|
@@ -881,23 +867,16 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
881
867
|
const followRoute = this.findMessageFollowRoute(actorId, incomingContext);
|
|
882
868
|
const staleGeneration = fallbackActorRef?.objectGeneration;
|
|
883
869
|
if (
|
|
884
|
-
fallbackActorRef !== undefined
|
|
885
|
-
|
|
870
|
+
fallbackActorRef !== undefined &&
|
|
871
|
+
this.options.isCurrentActorRef?.(actorId, fallbackActorRef) === true
|
|
886
872
|
) {
|
|
887
873
|
if (incomingContext !== undefined) {
|
|
888
|
-
this.validateContext(
|
|
889
|
-
actorId,
|
|
890
|
-
incomingContext,
|
|
891
|
-
parts,
|
|
892
|
-
returnResponse,
|
|
893
|
-
fallbackActorRef
|
|
894
|
-
);
|
|
874
|
+
this.validateContext(actorId, incomingContext, parts, returnResponse, fallbackActorRef);
|
|
895
875
|
const currentFence = this.options.currentOwnerFence?.(actorId);
|
|
896
|
-
if (
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
)) {
|
|
876
|
+
if (
|
|
877
|
+
currentFence !== undefined &&
|
|
878
|
+
!messageFollowOwnerFencesEqual(incomingContext.targetOwner, currentFence)
|
|
879
|
+
) {
|
|
901
880
|
// A relocation round trip (A→B→A) keeps the ObjectGeneration, so a
|
|
902
881
|
// context resolved against a departed tenure still addresses this
|
|
903
882
|
// node while the current tenure holds strictly newer authority
|
|
@@ -927,20 +906,19 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
927
906
|
return undefined;
|
|
928
907
|
}
|
|
929
908
|
if (
|
|
930
|
-
incomingContext === undefined
|
|
931
|
-
|
|
932
|
-
|
|
909
|
+
incomingContext === undefined &&
|
|
910
|
+
fallbackActorRef !== undefined &&
|
|
911
|
+
this.hasMessageFollowRouteForStaleRef(actorId, fallbackActorRef)
|
|
933
912
|
) {
|
|
934
913
|
this.options.onMarker?.('message_follow_rejected', actorId);
|
|
935
914
|
return Promise.reject(actorLocationStale(actorId));
|
|
936
915
|
}
|
|
937
916
|
if (
|
|
938
|
-
followRoute === undefined
|
|
939
|
-
&&
|
|
940
|
-
staleGeneration
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
&& this.isKnownStaleRef(actorId, fallbackActorRef)
|
|
917
|
+
followRoute === undefined &&
|
|
918
|
+
staleGeneration !== undefined &&
|
|
919
|
+
this.staleGenerations.get(actorId)?.has(staleGeneration) === true &&
|
|
920
|
+
fallbackActorRef !== undefined &&
|
|
921
|
+
this.isKnownStaleRef(actorId, fallbackActorRef)
|
|
944
922
|
) {
|
|
945
923
|
this.options.onMarker?.('message_follow_expired', actorId);
|
|
946
924
|
return Promise.reject(actorLocationStale(actorId));
|
|
@@ -989,8 +967,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
989
967
|
const handoff = this.requireActive(actorId);
|
|
990
968
|
let snapshotIndex = -1;
|
|
991
969
|
while (
|
|
992
|
-
snapshotIndex + 1 < handoff.pending.length
|
|
993
|
-
|
|
970
|
+
snapshotIndex + 1 < handoff.pending.length &&
|
|
971
|
+
handoff.pending[snapshotIndex + 1].packet.returnResponse === false
|
|
994
972
|
) {
|
|
995
973
|
snapshotIndex++;
|
|
996
974
|
}
|
|
@@ -1008,7 +986,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1008
986
|
const handoff = this.requireActive(actorId);
|
|
1009
987
|
const first = handoff.snapshotIndex + 1;
|
|
1010
988
|
handoff.snapshotIndex = handoff.pending.length - 1;
|
|
1011
|
-
return handoff.pending.slice(first).map(entry => entry.packet);
|
|
989
|
+
return handoff.pending.slice(first).map((entry) => entry.packet);
|
|
1012
990
|
}
|
|
1013
991
|
|
|
1014
992
|
complete(
|
|
@@ -1029,7 +1007,9 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1029
1007
|
if (result?.ok === false) {
|
|
1030
1008
|
pending.reject?.(new Error(result.error ?? 'Actor handoff replay failed.'));
|
|
1031
1009
|
} else if (result === undefined && pending.resolve !== undefined) {
|
|
1032
|
-
pending.reject?.(
|
|
1010
|
+
pending.reject?.(
|
|
1011
|
+
new Error(`Actor handoff reply '${pending.packet.index}' was not returned by the target.`)
|
|
1012
|
+
);
|
|
1033
1013
|
} else {
|
|
1034
1014
|
pending.resolve?.(result?.response);
|
|
1035
1015
|
}
|
|
@@ -1061,23 +1041,23 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1061
1041
|
if (pending.packet.source !== undefined) {
|
|
1062
1042
|
this.removeReplyRoute(pending.packet.source.replyRouteId);
|
|
1063
1043
|
}
|
|
1064
|
-
void this.enqueueMessageFollow(followRoute, actorId, pending.packet)
|
|
1065
|
-
|
|
1066
|
-
value
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
error
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
);
|
|
1044
|
+
void this.enqueueMessageFollow(followRoute, actorId, pending.packet).then(
|
|
1045
|
+
(value) => {
|
|
1046
|
+
pending.resolve?.(value);
|
|
1047
|
+
},
|
|
1048
|
+
(error) => {
|
|
1049
|
+
pending.reject?.(error);
|
|
1050
|
+
}
|
|
1051
|
+
);
|
|
1073
1052
|
}
|
|
1074
1053
|
}
|
|
1075
1054
|
|
|
1076
1055
|
messageFollowCount(actorId?: string): number {
|
|
1077
1056
|
return actorId === undefined
|
|
1078
1057
|
? this.messageFollowRoutes.size
|
|
1079
|
-
: [...this.messageFollowRoutes.values()]
|
|
1080
|
-
|
|
1058
|
+
: [...this.messageFollowRoutes.values()].filter(
|
|
1059
|
+
(route) => route.targetActorRef.actorId === actorId
|
|
1060
|
+
).length;
|
|
1081
1061
|
}
|
|
1082
1062
|
|
|
1083
1063
|
pendingCount(actorId: string): number {
|
|
@@ -1085,9 +1065,11 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1085
1065
|
}
|
|
1086
1066
|
|
|
1087
1067
|
isKnownStale(actor: ActorRef): boolean {
|
|
1088
|
-
return
|
|
1089
|
-
|
|
1090
|
-
|
|
1068
|
+
return (
|
|
1069
|
+
this.messageFollowCount(actor.actorId) === 0 &&
|
|
1070
|
+
this.options.isCurrentActorRef?.(actor.actorId, actor) !== true &&
|
|
1071
|
+
this.isKnownStaleRef(actor.actorId, actor)
|
|
1072
|
+
);
|
|
1091
1073
|
}
|
|
1092
1074
|
|
|
1093
1075
|
recordStaleFailure(actorId: string): void {
|
|
@@ -1104,13 +1086,12 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1104
1086
|
const source = packet.source;
|
|
1105
1087
|
if (source === undefined || source.replyRouteId.length === 0) return 'notAcknowledged';
|
|
1106
1088
|
const route = this.replyRoutes.get(source.replyRouteId);
|
|
1107
|
-
if (
|
|
1108
|
-
||
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
)) {
|
|
1089
|
+
if (
|
|
1090
|
+
route === undefined ||
|
|
1091
|
+
packet.messageFollowContext.objectGeneration !==
|
|
1092
|
+
route.sourceEvidence.objectGeneration.toString() ||
|
|
1093
|
+
!messageFollowOwnerFencesEqual(packet.messageFollowContext.targetOwner, route.sourceOwner)
|
|
1094
|
+
) {
|
|
1114
1095
|
return 'notAcknowledged';
|
|
1115
1096
|
}
|
|
1116
1097
|
return this.acceptRelocatedTerminalRelay(
|
|
@@ -1137,14 +1118,16 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1137
1118
|
const route = this.replyRoutes.get(replyRouteId);
|
|
1138
1119
|
if (route === undefined) return { status: 'notAcknowledged' };
|
|
1139
1120
|
const exactSource = source ?? route.source;
|
|
1140
|
-
if (
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1121
|
+
if (
|
|
1122
|
+
!requestSourcesEqual(route.source, exactSource) ||
|
|
1123
|
+
(actorId !== undefined && route.actorId !== actorId) ||
|
|
1124
|
+
route.operationId !== operationId ||
|
|
1125
|
+
route.targetNodeRid === undefined ||
|
|
1126
|
+
!routingIdsEqual(route.targetNodeRid, sourceNodeRid) ||
|
|
1127
|
+
route.targetAuthorityOwnerGeneration === undefined ||
|
|
1128
|
+
(targetAuthorityOwnerGeneration !== undefined &&
|
|
1129
|
+
route.targetAuthorityOwnerGeneration !== targetAuthorityOwnerGeneration)
|
|
1130
|
+
) {
|
|
1148
1131
|
return { status: 'notAcknowledged' };
|
|
1149
1132
|
}
|
|
1150
1133
|
try {
|
|
@@ -1203,7 +1186,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1203
1186
|
|
|
1204
1187
|
private requireActive(actorId: string): ActiveHandoff {
|
|
1205
1188
|
const handoff = this.active.get(actorId);
|
|
1206
|
-
if (handoff === undefined)
|
|
1189
|
+
if (handoff === undefined)
|
|
1190
|
+
throw new Error(`Actor '${actorId}' does not have an active packet handoff.`);
|
|
1207
1191
|
return handoff;
|
|
1208
1192
|
}
|
|
1209
1193
|
|
|
@@ -1233,11 +1217,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1233
1217
|
refs = new Map();
|
|
1234
1218
|
this.staleActorRefs.set(actorId, refs);
|
|
1235
1219
|
}
|
|
1236
|
-
const exactRefKey = actorRefEvidenceKey(
|
|
1237
|
-
oldNodeRid,
|
|
1238
|
-
oldNodeRidHex,
|
|
1239
|
-
oldGeneration
|
|
1240
|
-
);
|
|
1220
|
+
const exactRefKey = actorRefEvidenceKey(oldNodeRid, oldNodeRidHex, oldGeneration);
|
|
1241
1221
|
const recordedRef = refs.get(exactRefKey);
|
|
1242
1222
|
if (recordedRef === undefined || recordedRef < departedAuthorityOwnerGeneration) {
|
|
1243
1223
|
refs.set(exactRefKey, departedAuthorityOwnerGeneration);
|
|
@@ -1278,10 +1258,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1278
1258
|
if (previous === undefined) {
|
|
1279
1259
|
this.messageFollowSuppression.retainRoute(suppressionFence);
|
|
1280
1260
|
} else {
|
|
1281
|
-
this.messageFollowSuppression.replaceRoute(
|
|
1282
|
-
previous.suppressionFence,
|
|
1283
|
-
suppressionFence
|
|
1284
|
-
);
|
|
1261
|
+
this.messageFollowSuppression.replaceRoute(previous.suppressionFence, suppressionFence);
|
|
1285
1262
|
}
|
|
1286
1263
|
this.messageFollowRoutes.set(key, entry);
|
|
1287
1264
|
this.options.onMarker?.('message_follow_registered', actorId, this.messageFollowDurationMs);
|
|
@@ -1294,10 +1271,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1294
1271
|
this.messageFollowRoutes.delete(entry.key);
|
|
1295
1272
|
this.messageFollowSuppression.expireRoute(entry.suppressionFence);
|
|
1296
1273
|
this.pruneStaleTenureRecords(entry);
|
|
1297
|
-
this.options.onMarker?.(
|
|
1298
|
-
'message_follow_route_removed',
|
|
1299
|
-
entry.targetActorRef.actorId
|
|
1300
|
-
);
|
|
1274
|
+
this.options.onMarker?.('message_follow_route_removed', entry.targetActorRef.actorId);
|
|
1301
1275
|
}
|
|
1302
1276
|
|
|
1303
1277
|
/**
|
|
@@ -1312,8 +1286,10 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1312
1286
|
const stale = this.staleGenerations.get(actorId);
|
|
1313
1287
|
if (stale !== undefined) {
|
|
1314
1288
|
const recordedGeneration = stale.get(entry.oldGeneration);
|
|
1315
|
-
if (
|
|
1316
|
-
|
|
1289
|
+
if (
|
|
1290
|
+
recordedGeneration !== undefined &&
|
|
1291
|
+
recordedGeneration <= departedAuthorityOwnerGeneration
|
|
1292
|
+
) {
|
|
1317
1293
|
stale.delete(entry.oldGeneration);
|
|
1318
1294
|
}
|
|
1319
1295
|
if (stale.size === 0) this.staleGenerations.delete(actorId);
|
|
@@ -1321,11 +1297,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1321
1297
|
if (entry.oldNodeRid === undefined) return;
|
|
1322
1298
|
const refs = this.staleActorRefs.get(actorId);
|
|
1323
1299
|
if (refs === undefined) return;
|
|
1324
|
-
const refKey = actorRefEvidenceKey(
|
|
1325
|
-
entry.oldNodeRid,
|
|
1326
|
-
entry.oldNodeRidHex,
|
|
1327
|
-
entry.oldGeneration
|
|
1328
|
-
);
|
|
1300
|
+
const refKey = actorRefEvidenceKey(entry.oldNodeRid, entry.oldNodeRidHex, entry.oldGeneration);
|
|
1329
1301
|
const recordedRef = refs.get(refKey);
|
|
1330
1302
|
if (recordedRef !== undefined && recordedRef <= departedAuthorityOwnerGeneration) {
|
|
1331
1303
|
refs.delete(refKey);
|
|
@@ -1338,24 +1310,18 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1338
1310
|
context: ZLinkActorMessageFollowContext | undefined
|
|
1339
1311
|
): MessageFollowRoute | undefined {
|
|
1340
1312
|
if (context === undefined) return undefined;
|
|
1341
|
-
return this.messageFollowRoutes.get(
|
|
1342
|
-
actorId,
|
|
1343
|
-
|
|
1344
|
-
context.targetOwner
|
|
1345
|
-
));
|
|
1313
|
+
return this.messageFollowRoutes.get(
|
|
1314
|
+
messageFollowRouteKey(actorId, BigInt(context.objectGeneration), context.targetOwner)
|
|
1315
|
+
);
|
|
1346
1316
|
}
|
|
1347
1317
|
|
|
1348
1318
|
private hasMessageFollowRouteForStaleRef(actorId: string, actorRef: ActorRef): boolean {
|
|
1349
|
-
return [...this.messageFollowRoutes.values()].some(
|
|
1350
|
-
route
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
route.oldNodeRid === undefined
|
|
1354
|
-
|
|
1355
|
-
actorRef.nodeRid,
|
|
1356
|
-
messageFollowOwnerNodeRid(route.sourceOwner)
|
|
1357
|
-
)
|
|
1358
|
-
)
|
|
1319
|
+
return [...this.messageFollowRoutes.values()].some(
|
|
1320
|
+
(route) =>
|
|
1321
|
+
route.targetActorRef.actorId === actorId &&
|
|
1322
|
+
actorRef.objectGeneration === route.oldGeneration &&
|
|
1323
|
+
(route.oldNodeRid === undefined ||
|
|
1324
|
+
routingIdsEqual(actorRef.nodeRid, messageFollowOwnerNodeRid(route.sourceOwner)))
|
|
1359
1325
|
);
|
|
1360
1326
|
}
|
|
1361
1327
|
|
|
@@ -1389,15 +1355,16 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1389
1355
|
request: boolean,
|
|
1390
1356
|
actorRef?: ActorRef
|
|
1391
1357
|
): void {
|
|
1392
|
-
if (
|
|
1393
|
-
|
|
1358
|
+
if (
|
|
1359
|
+
actorRef !== undefined &&
|
|
1360
|
+
context.objectGeneration !== actorRef.objectGeneration.toString()
|
|
1361
|
+
) {
|
|
1394
1362
|
throw actorGenerationStale(actorId);
|
|
1395
1363
|
}
|
|
1396
1364
|
if (context.objectGeneration === '0' || context.request !== request) {
|
|
1397
1365
|
throw actorLocationStale(actorId);
|
|
1398
1366
|
}
|
|
1399
|
-
if (context.deadlineUnixMs !== undefined
|
|
1400
|
-
&& Date.now() >= context.deadlineUnixMs) {
|
|
1367
|
+
if (context.deadlineUnixMs !== undefined && Date.now() >= context.deadlineUnixMs) {
|
|
1401
1368
|
throw actorDeadlineExceeded(actorId);
|
|
1402
1369
|
}
|
|
1403
1370
|
verifyActorMessageFollowPayload(context, parts);
|
|
@@ -1409,14 +1376,19 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1409
1376
|
const departedAuthorityOwnerGeneration = physicalRefs.get(
|
|
1410
1377
|
actorRefKey(actor.nodeRid, actor.objectGeneration)
|
|
1411
1378
|
);
|
|
1412
|
-
return
|
|
1413
|
-
|
|
1379
|
+
return (
|
|
1380
|
+
departedAuthorityOwnerGeneration !== undefined &&
|
|
1381
|
+
!this.isNewerTenureRef(actorId, actor, departedAuthorityOwnerGeneration)
|
|
1382
|
+
);
|
|
1414
1383
|
}
|
|
1415
|
-
const departedAuthorityOwnerGeneration =
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1384
|
+
const departedAuthorityOwnerGeneration = this.staleGenerations
|
|
1385
|
+
.get(actorId)
|
|
1386
|
+
?.get(actor.objectGeneration);
|
|
1387
|
+
return (
|
|
1388
|
+
departedAuthorityOwnerGeneration !== undefined &&
|
|
1389
|
+
!this.isNewerTenureRef(actorId, actor, departedAuthorityOwnerGeneration) &&
|
|
1390
|
+
this.options.isStaleActorRef?.(actorId, actor) === true
|
|
1391
|
+
);
|
|
1420
1392
|
}
|
|
1421
1393
|
|
|
1422
1394
|
/**
|
|
@@ -1434,10 +1406,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1434
1406
|
return tenure !== undefined && tenure > departedAuthorityOwnerGeneration;
|
|
1435
1407
|
}
|
|
1436
1408
|
|
|
1437
|
-
private tenureAuthorityOwnerGeneration(
|
|
1438
|
-
actorId: string,
|
|
1439
|
-
actor: ActorRef
|
|
1440
|
-
): bigint | undefined {
|
|
1409
|
+
private tenureAuthorityOwnerGeneration(actorId: string, actor: ActorRef): bigint | undefined {
|
|
1441
1410
|
const context = actorMessageFollowContext(actor);
|
|
1442
1411
|
if (context !== undefined) {
|
|
1443
1412
|
return BigInt(context.targetOwner.authorityOwnerGeneration);
|
|
@@ -1457,9 +1426,11 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1457
1426
|
const context = packet.messageFollowContext;
|
|
1458
1427
|
const duplicate = entry.operations.get(context.operationId);
|
|
1459
1428
|
if (duplicate !== undefined) {
|
|
1460
|
-
if (
|
|
1461
|
-
|
|
1462
|
-
|
|
1429
|
+
if (
|
|
1430
|
+
duplicate.checksum !== context.payloadChecksumSha256 ||
|
|
1431
|
+
duplicate.request !== context.request ||
|
|
1432
|
+
duplicate.replyRouteId !== context.replyRouteId
|
|
1433
|
+
) {
|
|
1463
1434
|
this.options.onMarker?.('message_follow_rejected', actorId);
|
|
1464
1435
|
return Promise.reject(actorLocationStale(actorId));
|
|
1465
1436
|
}
|
|
@@ -1507,11 +1478,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1507
1478
|
const context = packet.messageFollowContext;
|
|
1508
1479
|
let advanced: ZLinkActorMessageFollowContext;
|
|
1509
1480
|
try {
|
|
1510
|
-
advanced = advanceActorMessageFollowContext(
|
|
1511
|
-
context,
|
|
1512
|
-
entry.sourceOwner,
|
|
1513
|
-
entry.targetOwner
|
|
1514
|
-
);
|
|
1481
|
+
advanced = advanceActorMessageFollowContext(context, entry.sourceOwner, entry.targetOwner);
|
|
1515
1482
|
} catch {
|
|
1516
1483
|
throw actorLocationStale(actorId);
|
|
1517
1484
|
}
|
|
@@ -1535,10 +1502,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1535
1502
|
await this.messageFollowRelayed(actorId, entry, packet, advanced);
|
|
1536
1503
|
return undefined;
|
|
1537
1504
|
}
|
|
1538
|
-
const remainingMs = remainingRequestTime(
|
|
1539
|
-
actorId,
|
|
1540
|
-
packet.messageFollowContext.deadlineUnixMs
|
|
1541
|
-
);
|
|
1505
|
+
const remainingMs = remainingRequestTime(actorId, packet.messageFollowContext.deadlineUnixMs);
|
|
1542
1506
|
if (this.options.routedTransport.requestRawToSpot === undefined) {
|
|
1543
1507
|
const reply = await awaitBeforeDeadline(
|
|
1544
1508
|
this.options.routedTransport.requestToSpot<Record<string, unknown>>(target, payload, {
|
|
@@ -1596,14 +1560,15 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1596
1560
|
if (claim === undefined) return;
|
|
1597
1561
|
let accepted = false;
|
|
1598
1562
|
try {
|
|
1599
|
-
accepted =
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1563
|
+
accepted =
|
|
1564
|
+
(await this.options.onMessageFollowRelayed?.(
|
|
1565
|
+
actorId,
|
|
1566
|
+
entry.targetActorRef,
|
|
1567
|
+
context,
|
|
1568
|
+
packet.messageFollowOrigin,
|
|
1569
|
+
entry.queuedMessages,
|
|
1570
|
+
entry.queuedBytes
|
|
1571
|
+
)) === true;
|
|
1607
1572
|
} catch {
|
|
1608
1573
|
accepted = false;
|
|
1609
1574
|
}
|
|
@@ -1649,27 +1614,34 @@ export function decodeHandoffPacket(packet: ZLinkActorHandoffPacket): {
|
|
|
1649
1614
|
RuntimeMessage.from(Buffer.from(packet.header, 'base64')) as Message,
|
|
1650
1615
|
RuntimeMessage.from(Buffer.from(packet.payload, 'base64')) as Message
|
|
1651
1616
|
],
|
|
1652
|
-
remoteBoundSessionTarget:
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
optionalBigInt(
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1617
|
+
remoteBoundSessionTarget:
|
|
1618
|
+
packet.remoteBoundSessionTarget === undefined
|
|
1619
|
+
? undefined
|
|
1620
|
+
: {
|
|
1621
|
+
routerChannelId: packet.remoteBoundSessionTarget.routerChannelId,
|
|
1622
|
+
targetNodeRid: packet.remoteBoundSessionTarget.targetNodeRid,
|
|
1623
|
+
spotId: packet.remoteBoundSessionTarget.spotId,
|
|
1624
|
+
bindingGeneration: optionalBigInt(packet.remoteBoundSessionTarget.bindingGeneration),
|
|
1625
|
+
previousAuthorityOwnerGeneration: optionalBigInt(
|
|
1626
|
+
packet.remoteBoundSessionTarget.previousAuthorityOwnerGeneration
|
|
1627
|
+
),
|
|
1628
|
+
previousOwnerLeaseGeneration: optionalBigInt(
|
|
1629
|
+
packet.remoteBoundSessionTarget.previousOwnerLeaseGeneration
|
|
1630
|
+
),
|
|
1631
|
+
relocationSealId: packet.remoteBoundSessionTarget.relocationSealId
|
|
1632
|
+
},
|
|
1633
|
+
fallbackActorRef:
|
|
1634
|
+
packet.fallbackActorRef === undefined
|
|
1635
|
+
? undefined
|
|
1636
|
+
: attachActorMessageFollowContext(
|
|
1637
|
+
{
|
|
1638
|
+
actorId: packet.fallbackActorRef.actorId,
|
|
1639
|
+
objectGeneration: BigInt(packet.fallbackActorRef.objectGeneration),
|
|
1640
|
+
meshName: packet.fallbackActorRef.meshName,
|
|
1641
|
+
nodeRid: packet.fallbackActorRef.nodeRid
|
|
1642
|
+
},
|
|
1643
|
+
packet.messageFollowContext
|
|
1644
|
+
)
|
|
1673
1645
|
};
|
|
1674
1646
|
}
|
|
1675
1647
|
|
|
@@ -1688,9 +1660,9 @@ export async function replayActorHandoffBacklog(
|
|
|
1688
1660
|
const decoded = decodeHandoffPacket(packet);
|
|
1689
1661
|
try {
|
|
1690
1662
|
if (
|
|
1691
|
-
packet.returnResponse
|
|
1692
|
-
|
|
1693
|
-
|
|
1663
|
+
packet.returnResponse &&
|
|
1664
|
+
packet.messageFollowContext.deadlineUnixMs !== undefined &&
|
|
1665
|
+
Date.now() >= packet.messageFollowContext.deadlineUnixMs
|
|
1694
1666
|
) {
|
|
1695
1667
|
throw actorDeadlineExceeded(packet.fallbackActorRef?.actorId ?? 'accepted-handoff');
|
|
1696
1668
|
}
|
|
@@ -1707,9 +1679,8 @@ export async function replayActorHandoffBacklog(
|
|
|
1707
1679
|
index: packet.index,
|
|
1708
1680
|
ok: false,
|
|
1709
1681
|
error: error instanceof Error ? error.message : String(error),
|
|
1710
|
-
errorKind:
|
|
1711
|
-
? internalFrameworkErrorKind(error)
|
|
1712
|
-
: undefined
|
|
1682
|
+
errorKind:
|
|
1683
|
+
error instanceof ZLinkFrameworkException ? internalFrameworkErrorKind(error) : undefined
|
|
1713
1684
|
});
|
|
1714
1685
|
} finally {
|
|
1715
1686
|
decoded.parts.forEach((part) => part.close());
|
|
@@ -1737,27 +1708,29 @@ function encodePacket(
|
|
|
1737
1708
|
returnResponse,
|
|
1738
1709
|
messageFollowContext,
|
|
1739
1710
|
...(messageFollowOrigin === undefined ? {} : { messageFollowOrigin }),
|
|
1740
|
-
remoteBoundSessionTarget:
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1711
|
+
remoteBoundSessionTarget:
|
|
1712
|
+
remoteBoundSessionTarget === undefined
|
|
1713
|
+
? undefined
|
|
1714
|
+
: {
|
|
1715
|
+
routerChannelId: remoteBoundSessionTarget.routerChannelId,
|
|
1716
|
+
targetNodeRid: String(remoteBoundSessionTarget.targetNodeRid),
|
|
1717
|
+
spotId: String(remoteBoundSessionTarget.spotId),
|
|
1718
|
+
bindingGeneration: remoteBoundSessionTarget.bindingGeneration?.toString(),
|
|
1719
|
+
previousAuthorityOwnerGeneration:
|
|
1720
|
+
remoteBoundSessionTarget.previousAuthorityOwnerGeneration?.toString(),
|
|
1721
|
+
previousOwnerLeaseGeneration:
|
|
1722
|
+
remoteBoundSessionTarget.previousOwnerLeaseGeneration?.toString(),
|
|
1723
|
+
relocationSealId: remoteBoundSessionTarget.relocationSealId
|
|
1724
|
+
},
|
|
1725
|
+
fallbackActorRef:
|
|
1726
|
+
fallbackActorRef === undefined
|
|
1727
|
+
? undefined
|
|
1728
|
+
: {
|
|
1729
|
+
actorId: fallbackActorRef.actorId,
|
|
1730
|
+
objectGeneration: fallbackActorRef.objectGeneration.toString(),
|
|
1731
|
+
meshName: fallbackActorRef.meshName,
|
|
1732
|
+
nodeRid: String(fallbackActorRef.nodeRid)
|
|
1733
|
+
}
|
|
1761
1734
|
};
|
|
1762
1735
|
}
|
|
1763
1736
|
|
|
@@ -1778,7 +1751,10 @@ function packetDeadlineUnixMs(parts: readonly Message[]): number | undefined {
|
|
|
1778
1751
|
}
|
|
1779
1752
|
}
|
|
1780
1753
|
|
|
1781
|
-
function remainingRequestTime(
|
|
1754
|
+
function remainingRequestTime(
|
|
1755
|
+
actorId: string,
|
|
1756
|
+
deadlineUnixMs: number | undefined
|
|
1757
|
+
): number | undefined {
|
|
1782
1758
|
if (deadlineUnixMs === undefined) return undefined;
|
|
1783
1759
|
const remaining = deadlineUnixMs - Date.now();
|
|
1784
1760
|
if (remaining <= 0) throw actorDeadlineExceeded(actorId);
|
|
@@ -1804,10 +1780,7 @@ async function awaitBeforeDeadline<T>(
|
|
|
1804
1780
|
}
|
|
1805
1781
|
}
|
|
1806
1782
|
|
|
1807
|
-
async function waitForHandoffReplayStart(
|
|
1808
|
-
start: Promise<void>,
|
|
1809
|
-
signal: AbortSignal
|
|
1810
|
-
): Promise<void> {
|
|
1783
|
+
async function waitForHandoffReplayStart(start: Promise<void>, signal: AbortSignal): Promise<void> {
|
|
1811
1784
|
if (signal.aborted) throw signal.reason;
|
|
1812
1785
|
let abort!: () => void;
|
|
1813
1786
|
const aborted = new Promise<never>((_resolve, reject) => {
|
|
@@ -1845,13 +1818,15 @@ function requestSourcesEqual(
|
|
|
1845
1818
|
expected: ZLinkActorHandoffRequestSource,
|
|
1846
1819
|
actual: ZLinkActorHandoffRequestSource
|
|
1847
1820
|
): boolean {
|
|
1848
|
-
return
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1821
|
+
return (
|
|
1822
|
+
expected.replyRouteId === actual.replyRouteId &&
|
|
1823
|
+
expected.ownerId === actual.ownerId &&
|
|
1824
|
+
expected.ownerLeaseGeneration === actual.ownerLeaseGeneration &&
|
|
1825
|
+
expected.nodeRid === actual.nodeRid &&
|
|
1826
|
+
expected.nodeGeneration === actual.nodeGeneration &&
|
|
1827
|
+
/^[1-9][0-9]*$/.test(actual.ownerLeaseGeneration) &&
|
|
1828
|
+
/^[1-9][0-9]*$/.test(actual.nodeGeneration)
|
|
1829
|
+
);
|
|
1855
1830
|
}
|
|
1856
1831
|
|
|
1857
1832
|
function terminalRequestSource(route: ReplyRoute): ZLinkActorHandoffRequestSource {
|
|
@@ -1898,14 +1873,15 @@ function actorRelayError(
|
|
|
1898
1873
|
errorKind: unknown,
|
|
1899
1874
|
error: unknown
|
|
1900
1875
|
): ZLinkFrameworkException {
|
|
1901
|
-
const kind = Object.values(ZLinkFrameworkInternalErrorKind)
|
|
1902
|
-
|
|
1903
|
-
|
|
1876
|
+
const kind = Object.values(ZLinkFrameworkInternalErrorKind).includes(
|
|
1877
|
+
errorKind as ZLinkFrameworkInternalErrorKind
|
|
1878
|
+
)
|
|
1879
|
+
? (errorKind as ZLinkFrameworkInternalErrorKind)
|
|
1904
1880
|
: ZLinkFrameworkInternalErrorKind.RequestFailed;
|
|
1905
1881
|
return createInternalFrameworkException(
|
|
1906
1882
|
kind,
|
|
1907
1883
|
String(error ?? `Actor Message Follow relay failed for '${actorId}'.`),
|
|
1908
|
-
kind === ZLinkFrameworkInternalErrorKind.ActorMoving
|
|
1909
|
-
|
|
1884
|
+
kind === ZLinkFrameworkInternalErrorKind.ActorMoving ||
|
|
1885
|
+
kind === ZLinkFrameworkInternalErrorKind.RouteNotConnected
|
|
1910
1886
|
);
|
|
1911
1887
|
}
|