@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
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
ZLinkSpot,
|
|
11
11
|
ZLinkSpotActorJoinResult,
|
|
12
12
|
ZLinkSpotInfo,
|
|
13
|
-
ZLinkSpotPublisherClient
|
|
13
|
+
ZLinkSpotPublisherClient
|
|
14
14
|
} from '../../contracts';
|
|
15
15
|
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
16
16
|
import type {
|
|
@@ -58,19 +58,14 @@ import {
|
|
|
58
58
|
type ReceiveRecord
|
|
59
59
|
} from '../foundation/service-runtime-contracts';
|
|
60
60
|
import { zlinkMetadataByteLength, zlinkSerialWorkOptions } from '../execution/serial-work-size';
|
|
61
|
-
import {
|
|
62
|
-
ZLinkConfigurationException
|
|
63
|
-
} from '../configuration';
|
|
61
|
+
import { ZLinkConfigurationException } from '../configuration';
|
|
64
62
|
import {
|
|
65
63
|
ZLinkFrameworkInternalErrorKind,
|
|
66
64
|
createInternalFrameworkException,
|
|
67
65
|
internalFrameworkErrorKind,
|
|
68
66
|
internalFrameworkWireReply
|
|
69
67
|
} from '../framework-errors-internal';
|
|
70
|
-
import type {
|
|
71
|
-
ZLinkBackendSpot,
|
|
72
|
-
ZLinkBackendSpotNode
|
|
73
|
-
} from '../backend/contracts';
|
|
68
|
+
import type { ZLinkBackendSpot, ZLinkBackendSpotNode } from '../backend/contracts';
|
|
74
69
|
|
|
75
70
|
import { ZLinkDispatchErrorReporter } from '../channels';
|
|
76
71
|
import { ZLinkWorkerRuntime } from '../workers';
|
|
@@ -114,17 +109,12 @@ import {
|
|
|
114
109
|
decodeRemoteBoundSessionTarget
|
|
115
110
|
} from './spot-remote-codec';
|
|
116
111
|
import { decodeRoutingId, encodeRoutingIdStorageHex } from '../routing-id';
|
|
117
|
-
import type {
|
|
118
|
-
CanonicalActorJoinRecovery
|
|
119
|
-
} from '../foundation/actor-join-recovery-codec';
|
|
112
|
+
import type { CanonicalActorJoinRecovery } from '../foundation/actor-join-recovery-codec';
|
|
120
113
|
import { SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE } from '../foundation/service-wire-constants.generated';
|
|
121
114
|
|
|
122
115
|
export { ZLinkSpotSerialTurnExecutor } from './spot-serial-turn-executor';
|
|
123
116
|
export { ZLinkSpotSerialExecutor } from './spot-serial-executor';
|
|
124
|
-
export {
|
|
125
|
-
ZLinkManagedTimer,
|
|
126
|
-
ZLinkSpotTimerRegistry
|
|
127
|
-
} from './spot-timer';
|
|
117
|
+
export { ZLinkManagedTimer, ZLinkSpotTimerRegistry } from './spot-timer';
|
|
128
118
|
export {
|
|
129
119
|
DefaultZLinkSpotOutbound,
|
|
130
120
|
type ZLinkSpotAddressCallOptions,
|
|
@@ -133,25 +123,15 @@ export {
|
|
|
133
123
|
type ZLinkSpotRoutedSendOptions,
|
|
134
124
|
type ZLinkSpotRoutedTransport
|
|
135
125
|
} from './spot-outbound';
|
|
136
|
-
import {
|
|
137
|
-
type ZLinkSpotRoutedTransport
|
|
138
|
-
} from './spot-outbound';
|
|
126
|
+
import { type ZLinkSpotRoutedTransport } from './spot-outbound';
|
|
139
127
|
export {
|
|
140
128
|
DefaultZLinkSpotHandlerRegistry,
|
|
141
129
|
type ZLinkSpotHandlerRegistration
|
|
142
130
|
} from './spot-handler-registry';
|
|
143
131
|
export { ZLinkRuntimeSpotPublisherTransport } from './spot-publisher-transport';
|
|
144
|
-
import {
|
|
145
|
-
|
|
146
|
-
} from './spot-activation
|
|
147
|
-
import {
|
|
148
|
-
ZLinkSpotCloseOccupiedError,
|
|
149
|
-
type ZLinkSpotActivation
|
|
150
|
-
} from './spot-activation-state';
|
|
151
|
-
import {
|
|
152
|
-
ZLinkSpotActivationLifecycle,
|
|
153
|
-
type ZLinkNativeSpotAuthority
|
|
154
|
-
} from './spot-activation';
|
|
132
|
+
import { ZLinkSpotActivationRegistry } from './spot-activation-registry';
|
|
133
|
+
import { ZLinkSpotCloseOccupiedError, type ZLinkSpotActivation } from './spot-activation-state';
|
|
134
|
+
import { ZLinkSpotActivationLifecycle, type ZLinkNativeSpotAuthority } from './spot-activation';
|
|
155
135
|
import { ZLinkSpotActorMembership, type ZLinkActorJoinRollback } from './spot-actor-membership';
|
|
156
136
|
import { ZLinkFormalRemoteActorTransferRegistry } from './formal-remote-actor-transfer-registry';
|
|
157
137
|
import {
|
|
@@ -177,10 +157,7 @@ export {
|
|
|
177
157
|
ZLinkSpotNodeRuntimeManager,
|
|
178
158
|
type ZLinkSpotNodeRuntimeManagerOptions
|
|
179
159
|
} from './spot-node-runtime-manager';
|
|
180
|
-
export {
|
|
181
|
-
ZLinkPublicSpotManager,
|
|
182
|
-
type ZLinkPublicSpotManagerOptions
|
|
183
|
-
} from './spot-manager-public';
|
|
160
|
+
export { ZLinkPublicSpotManager, type ZLinkPublicSpotManagerOptions } from './spot-manager-public';
|
|
184
161
|
|
|
185
162
|
export interface ZLinkSpotManagerOptions {
|
|
186
163
|
readonly spotFactories: readonly Type<ZLinkSpot>[];
|
|
@@ -329,20 +306,26 @@ export class DefaultZLinkSpotManager {
|
|
|
329
306
|
string,
|
|
330
307
|
Map<string, Promise<ZLinkSpotActivation>>
|
|
331
308
|
>();
|
|
332
|
-
private readonly instanceActivationGates = new Map<
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
309
|
+
private readonly instanceActivationGates = new Map<
|
|
310
|
+
string,
|
|
311
|
+
{
|
|
312
|
+
readonly meshName: string;
|
|
313
|
+
readonly limit: number;
|
|
314
|
+
active: number;
|
|
315
|
+
// Tombstone slots + head cursor keep abort O(1) and admit O(1) amortized
|
|
316
|
+
// instead of indexOf/splice + shift scans under a cancellation storm.
|
|
317
|
+
readonly waiters: Array<
|
|
318
|
+
| {
|
|
319
|
+
resolve: (release: () => void) => void;
|
|
320
|
+
reject: (error: unknown) => void;
|
|
321
|
+
signal?: AbortSignal;
|
|
322
|
+
abort?: () => void;
|
|
323
|
+
}
|
|
324
|
+
| undefined
|
|
325
|
+
>;
|
|
326
|
+
waiterHead: number;
|
|
327
|
+
}
|
|
328
|
+
>();
|
|
346
329
|
private readonly pendingInstanceCloses = new Map<string, Promise<boolean>>();
|
|
347
330
|
private readonly pendingInstanceTerminals = new Map<string, number>();
|
|
348
331
|
private readonly pendingInstanceTerminalGenerations = new Map<string, Map<string, number>>();
|
|
@@ -365,16 +348,18 @@ export class DefaultZLinkSpotManager {
|
|
|
365
348
|
});
|
|
366
349
|
this.routedSpotPackets = new ZLinkRoutedSpotPacketDispatch({
|
|
367
350
|
resolveActivation: (spotId) => this.activations.resolveUnique(spotId),
|
|
368
|
-
claimApplicationWork:
|
|
369
|
-
|
|
370
|
-
|
|
351
|
+
claimApplicationWork:
|
|
352
|
+
options.admission === undefined
|
|
353
|
+
? undefined
|
|
354
|
+
: (meshName) => options.admission!.claim(meshName, 'Spot route dispatch'),
|
|
371
355
|
providerResolver: options.providerResolver,
|
|
372
356
|
dispatchErrors: options.dispatchErrors
|
|
373
357
|
});
|
|
374
358
|
this.actorMembership = new ZLinkSpotActorMembership({
|
|
375
|
-
resolveActivation: (spotId, meshName) =>
|
|
376
|
-
|
|
377
|
-
|
|
359
|
+
resolveActivation: (spotId, meshName) =>
|
|
360
|
+
meshName === undefined
|
|
361
|
+
? this.activations.resolveUnique(spotId)
|
|
362
|
+
: this.activations.resolve(meshName, spotId),
|
|
378
363
|
providerResolver: options.providerResolver,
|
|
379
364
|
messageSerializers: options.messageSerializers,
|
|
380
365
|
dispatchErrors: options.dispatchErrors,
|
|
@@ -445,8 +430,10 @@ export class DefaultZLinkSpotManager {
|
|
|
445
430
|
meshName,
|
|
446
431
|
spotId
|
|
447
432
|
);
|
|
448
|
-
if (
|
|
449
|
-
|
|
433
|
+
if (
|
|
434
|
+
currentApplication !== undefined &&
|
|
435
|
+
currentApplication.objectGeneration !== activation.domain.objectGeneration
|
|
436
|
+
) {
|
|
450
437
|
// A superseded local application must not release the authority row
|
|
451
438
|
// that now belongs to the newer object generation.
|
|
452
439
|
return Promise.resolve();
|
|
@@ -470,16 +457,23 @@ export class DefaultZLinkSpotManager {
|
|
|
470
457
|
}
|
|
471
458
|
|
|
472
459
|
relocationActivations(meshName: string): readonly ZLinkSpotActivation[] {
|
|
473
|
-
return this.activations
|
|
474
|
-
|
|
475
|
-
|
|
460
|
+
return this.activations
|
|
461
|
+
.activeActivations()
|
|
462
|
+
.filter(
|
|
463
|
+
(activation) =>
|
|
464
|
+
activation.meshName === meshName &&
|
|
465
|
+
this.activations.resolve(meshName, activation.spotId) === activation
|
|
466
|
+
);
|
|
476
467
|
}
|
|
477
468
|
|
|
478
469
|
activeSpotCount(meshName: string): number {
|
|
479
470
|
return this.activations.list(meshName).length;
|
|
480
471
|
}
|
|
481
472
|
|
|
482
|
-
instanceActivationConcurrency(meshName: string): {
|
|
473
|
+
instanceActivationConcurrency(meshName: string): {
|
|
474
|
+
readonly active: number;
|
|
475
|
+
readonly limit: number;
|
|
476
|
+
} {
|
|
483
477
|
const limit = this.options.activationConcurrencyLimitProvider?.(meshName) ?? 128;
|
|
484
478
|
return { active: this.instanceActivationGates.get(meshName)?.active ?? 0, limit };
|
|
485
479
|
}
|
|
@@ -534,9 +528,7 @@ export class DefaultZLinkSpotManager {
|
|
|
534
528
|
await activation.nativeSpot?.dispose();
|
|
535
529
|
}
|
|
536
530
|
|
|
537
|
-
async completeRelocationSource(
|
|
538
|
-
activation: ZLinkSpotActivation
|
|
539
|
-
): Promise<void> {
|
|
531
|
+
async completeRelocationSource(activation: ZLinkSpotActivation): Promise<void> {
|
|
540
532
|
this.activations.detachRelocated(activation.meshName, activation.spotId);
|
|
541
533
|
await activation.nativeSpot?.dispose();
|
|
542
534
|
}
|
|
@@ -598,10 +590,7 @@ export class DefaultZLinkSpotManager {
|
|
|
598
590
|
);
|
|
599
591
|
}
|
|
600
592
|
if (current.objectGeneration === objectGeneration) return;
|
|
601
|
-
if (
|
|
602
|
-
current.objectGeneration === undefined
|
|
603
|
-
|| current.objectGeneration > objectGeneration
|
|
604
|
-
) {
|
|
593
|
+
if (current.objectGeneration === undefined || current.objectGeneration > objectGeneration) {
|
|
605
594
|
throw createInternalFrameworkException(
|
|
606
595
|
ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
|
|
607
596
|
`Instance Spot '${String(spotId)}' has a newer application generation.`
|
|
@@ -616,9 +605,12 @@ export class DefaultZLinkSpotManager {
|
|
|
616
605
|
continue;
|
|
617
606
|
}
|
|
618
607
|
|
|
619
|
-
const lifecycleActivation = this.activations
|
|
620
|
-
|
|
621
|
-
|
|
608
|
+
const lifecycleActivation = this.activations
|
|
609
|
+
.activeActivations()
|
|
610
|
+
.find(
|
|
611
|
+
(activation) =>
|
|
612
|
+
activation.meshName === meshName && String(activation.spotId) === String(spotId)
|
|
613
|
+
);
|
|
622
614
|
if (lifecycleActivation?.isIdleEvicting === true) {
|
|
623
615
|
throw createInternalFrameworkException(
|
|
624
616
|
ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
|
|
@@ -629,9 +621,7 @@ export class DefaultZLinkSpotManager {
|
|
|
629
621
|
let pending = this.pendingInstanceMaterializations.get(materializationKey);
|
|
630
622
|
if (pending === undefined) {
|
|
631
623
|
const siblings = this.pendingInstanceMaterializationsByPrefix.get(materializationPrefix);
|
|
632
|
-
const otherPending = siblings === undefined
|
|
633
|
-
? undefined
|
|
634
|
-
: siblings.values().next().value;
|
|
624
|
+
const otherPending = siblings === undefined ? undefined : siblings.values().next().value;
|
|
635
625
|
if (otherPending !== undefined) {
|
|
636
626
|
await awaitWithAbort(otherPending, signal);
|
|
637
627
|
continue;
|
|
@@ -639,19 +629,14 @@ export class DefaultZLinkSpotManager {
|
|
|
639
629
|
}
|
|
640
630
|
if (pending === undefined) {
|
|
641
631
|
const metric = this.options.metrics?.startInstanceSpotActivation(meshName, instanceType);
|
|
642
|
-
pending = this.activationLifecycle
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
spotId,
|
|
647
|
-
objectGeneration,
|
|
648
|
-
signal
|
|
649
|
-
).then(
|
|
650
|
-
activation => {
|
|
632
|
+
pending = this.activationLifecycle
|
|
633
|
+
.materializeInstance(meshName, instanceType, factory, spotId, objectGeneration, signal)
|
|
634
|
+
.then(
|
|
635
|
+
(activation) => {
|
|
651
636
|
metric?.complete('ready');
|
|
652
637
|
return activation;
|
|
653
638
|
},
|
|
654
|
-
error => {
|
|
639
|
+
(error) => {
|
|
655
640
|
metric?.complete(instanceActivationOutcome(error));
|
|
656
641
|
throw error;
|
|
657
642
|
}
|
|
@@ -663,18 +648,20 @@ export class DefaultZLinkSpotManager {
|
|
|
663
648
|
this.pendingInstanceMaterializationsByPrefix.set(materializationPrefix, siblings);
|
|
664
649
|
}
|
|
665
650
|
siblings.set(materializationKey, pending);
|
|
666
|
-
void pending
|
|
667
|
-
|
|
668
|
-
this.pendingInstanceMaterializations.
|
|
669
|
-
|
|
670
|
-
const bucket = this.pendingInstanceMaterializationsByPrefix.get(materializationPrefix);
|
|
671
|
-
if (bucket !== undefined && bucket.get(materializationKey) === pending) {
|
|
672
|
-
bucket.delete(materializationKey);
|
|
673
|
-
if (bucket.size === 0) {
|
|
674
|
-
this.pendingInstanceMaterializationsByPrefix.delete(materializationPrefix);
|
|
651
|
+
void pending
|
|
652
|
+
.finally(() => {
|
|
653
|
+
if (this.pendingInstanceMaterializations.get(materializationKey) === pending) {
|
|
654
|
+
this.pendingInstanceMaterializations.delete(materializationKey);
|
|
675
655
|
}
|
|
676
|
-
|
|
677
|
-
|
|
656
|
+
const bucket = this.pendingInstanceMaterializationsByPrefix.get(materializationPrefix);
|
|
657
|
+
if (bucket !== undefined && bucket.get(materializationKey) === pending) {
|
|
658
|
+
bucket.delete(materializationKey);
|
|
659
|
+
if (bucket.size === 0) {
|
|
660
|
+
this.pendingInstanceMaterializationsByPrefix.delete(materializationPrefix);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
})
|
|
664
|
+
.catch(() => undefined);
|
|
678
665
|
}
|
|
679
666
|
await pending;
|
|
680
667
|
return;
|
|
@@ -718,12 +705,15 @@ export class DefaultZLinkSpotManager {
|
|
|
718
705
|
readonly meshName: string;
|
|
719
706
|
readonly limit: number;
|
|
720
707
|
active: number;
|
|
721
|
-
readonly waiters: Array<
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
708
|
+
readonly waiters: Array<
|
|
709
|
+
| {
|
|
710
|
+
resolve: (release: () => void) => void;
|
|
711
|
+
reject: (error: unknown) => void;
|
|
712
|
+
signal?: AbortSignal;
|
|
713
|
+
abort?: () => void;
|
|
714
|
+
}
|
|
715
|
+
| undefined
|
|
716
|
+
>;
|
|
727
717
|
waiterHead: number;
|
|
728
718
|
}): void {
|
|
729
719
|
while (gate.waiterHead < gate.waiters.length) {
|
|
@@ -745,14 +735,12 @@ export class DefaultZLinkSpotManager {
|
|
|
745
735
|
this.options.onInstanceActivationConcurrencyChanged?.(gate.meshName);
|
|
746
736
|
}
|
|
747
737
|
|
|
748
|
-
isInstanceMaterialized(
|
|
749
|
-
meshName: string,
|
|
750
|
-
instanceType: string,
|
|
751
|
-
spotId: RoutingId
|
|
752
|
-
): boolean {
|
|
738
|
+
isInstanceMaterialized(meshName: string, instanceType: string, spotId: RoutingId): boolean {
|
|
753
739
|
const activation = this.activations.resolve(meshName, spotId);
|
|
754
|
-
return
|
|
755
|
-
|
|
740
|
+
return (
|
|
741
|
+
activation !== undefined &&
|
|
742
|
+
activation.spotType === this.requireInstanceFactory(meshName, instanceType)
|
|
743
|
+
);
|
|
756
744
|
}
|
|
757
745
|
|
|
758
746
|
isInstanceMaterializing(meshName: string, spotId: RoutingId): boolean {
|
|
@@ -762,8 +750,10 @@ export class DefaultZLinkSpotManager {
|
|
|
762
750
|
|
|
763
751
|
isInstanceClosing(meshName: string, spotId: RoutingId): boolean {
|
|
764
752
|
const key = `${meshName}\0${String(spotId)}`;
|
|
765
|
-
return
|
|
766
|
-
|
|
753
|
+
return (
|
|
754
|
+
this.pendingInstanceCloses.has(key) ||
|
|
755
|
+
this.activations.closingOperation(meshName, spotId) !== undefined
|
|
756
|
+
);
|
|
767
757
|
}
|
|
768
758
|
|
|
769
759
|
async discardInstance(meshName: string, spotId: RoutingId): Promise<void> {
|
|
@@ -780,22 +770,28 @@ export class DefaultZLinkSpotManager {
|
|
|
780
770
|
}
|
|
781
771
|
|
|
782
772
|
isInstanceSpotIdleEvicting(meshName: string, spotId: RoutingId): boolean {
|
|
783
|
-
const activation = this.activations
|
|
784
|
-
|
|
773
|
+
const activation = this.activations
|
|
774
|
+
.activeActivations()
|
|
775
|
+
.find(
|
|
776
|
+
(candidate) =>
|
|
777
|
+
candidate.meshName === meshName && String(candidate.spotId) === String(spotId)
|
|
778
|
+
);
|
|
779
|
+
return (
|
|
780
|
+
activation !== undefined && activation.domain.kind === 'instance' && activation.isIdleEvicting
|
|
785
781
|
);
|
|
786
|
-
return activation !== undefined
|
|
787
|
-
&& activation.domain.kind === 'instance'
|
|
788
|
-
&& activation.isIdleEvicting;
|
|
789
782
|
}
|
|
790
783
|
|
|
791
784
|
beginInstanceSpotIdleEviction(meshName: string, spotId: RoutingId): boolean {
|
|
792
|
-
const activation = this.activations
|
|
793
|
-
|
|
794
|
-
|
|
785
|
+
const activation = this.activations
|
|
786
|
+
.activeActivations()
|
|
787
|
+
.find(
|
|
788
|
+
(candidate) =>
|
|
789
|
+
candidate.meshName === meshName && String(candidate.spotId) === String(spotId)
|
|
790
|
+
);
|
|
795
791
|
if (
|
|
796
|
-
activation === undefined
|
|
797
|
-
|
|
798
|
-
|
|
792
|
+
activation === undefined ||
|
|
793
|
+
activation.domain.kind !== 'instance' ||
|
|
794
|
+
!activation.isIdleFor(
|
|
799
795
|
performance.now(),
|
|
800
796
|
this.options.instanceSpotIdleTimeoutMs?.get(meshName) ?? 0
|
|
801
797
|
)
|
|
@@ -826,17 +822,18 @@ export class DefaultZLinkSpotManager {
|
|
|
826
822
|
await pendingClose;
|
|
827
823
|
return true;
|
|
828
824
|
}
|
|
829
|
-
const deferredRelease =
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
&& this.activations.closingOperation(meshName, spotId) === undefined
|
|
833
|
-
) {
|
|
825
|
+
const deferredRelease =
|
|
826
|
+
this.deferredInstanceAuthorityReleases.get(key)?.has(objectGeneration) === true;
|
|
827
|
+
if (!deferredRelease && this.activations.closingOperation(meshName, spotId) === undefined) {
|
|
834
828
|
return false;
|
|
835
829
|
}
|
|
836
|
-
const currentApplication = this.options.instanceSpotApplicationTargetProvider?.(
|
|
830
|
+
const currentApplication = this.options.instanceSpotApplicationTargetProvider?.(
|
|
831
|
+
meshName,
|
|
832
|
+
spotId
|
|
833
|
+
);
|
|
837
834
|
if (
|
|
838
|
-
currentApplication !== undefined
|
|
839
|
-
|
|
835
|
+
currentApplication !== undefined &&
|
|
836
|
+
currentApplication.objectGeneration !== objectGeneration
|
|
840
837
|
) {
|
|
841
838
|
this.removeDeferredInstanceAuthorityRelease(key, objectGeneration);
|
|
842
839
|
return false;
|
|
@@ -848,11 +845,9 @@ export class DefaultZLinkSpotManager {
|
|
|
848
845
|
|
|
849
846
|
beginInstanceTerminal(meshName: string, spotId: RoutingId, objectGeneration: bigint): void {
|
|
850
847
|
const key = `${meshName}\0${String(spotId)}`;
|
|
851
|
-
this.pendingInstanceTerminals.set(
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
);
|
|
855
|
-
const generations = this.pendingInstanceTerminalGenerations.get(key) ?? new Map<string, number>();
|
|
848
|
+
this.pendingInstanceTerminals.set(key, (this.pendingInstanceTerminals.get(key) ?? 0) + 1);
|
|
849
|
+
const generations =
|
|
850
|
+
this.pendingInstanceTerminalGenerations.get(key) ?? new Map<string, number>();
|
|
856
851
|
const generationKey = objectGeneration.toString();
|
|
857
852
|
generations.set(generationKey, (generations.get(generationKey) ?? 0) + 1);
|
|
858
853
|
this.pendingInstanceTerminalGenerations.set(key, generations);
|
|
@@ -885,14 +880,13 @@ export class DefaultZLinkSpotManager {
|
|
|
885
880
|
spotId: RoutingId,
|
|
886
881
|
objectGeneration: bigint
|
|
887
882
|
): Promise<void> {
|
|
888
|
-
return
|
|
889
|
-
|
|
883
|
+
return (
|
|
884
|
+
this.options.releaseInstanceAuthority?.(meshName, spotId, objectGeneration) ??
|
|
885
|
+
Promise.resolve()
|
|
886
|
+
);
|
|
890
887
|
}
|
|
891
888
|
|
|
892
|
-
private requireInstanceFactory(
|
|
893
|
-
meshName: string,
|
|
894
|
-
instanceType: string
|
|
895
|
-
): Type<ZLinkInstanceSpot> {
|
|
889
|
+
private requireInstanceFactory(meshName: string, instanceType: string): Type<ZLinkInstanceSpot> {
|
|
896
890
|
const factory = this.options.instanceSpotFactories?.get(meshName)?.get(instanceType);
|
|
897
891
|
if (factory === undefined) {
|
|
898
892
|
throw new ZLinkConfigurationException(
|
|
@@ -905,8 +899,9 @@ export class DefaultZLinkSpotManager {
|
|
|
905
899
|
private scheduleIdleSweep(): void {
|
|
906
900
|
if (this.idleSweepTimer !== undefined) return;
|
|
907
901
|
if (!this.hasIdleSweepTarget()) return;
|
|
908
|
-
const delays = [...(this.options.instanceSpotIdleTimeoutMs?.values() ?? [])]
|
|
909
|
-
|
|
902
|
+
const delays = [...(this.options.instanceSpotIdleTimeoutMs?.values() ?? [])].filter(
|
|
903
|
+
(value) => value > 0
|
|
904
|
+
);
|
|
910
905
|
if (delays.length === 0) return;
|
|
911
906
|
const delay = Math.max(1, Math.min(...delays));
|
|
912
907
|
const timer = setTimeout(() => {
|
|
@@ -929,21 +924,19 @@ export class DefaultZLinkSpotManager {
|
|
|
929
924
|
for (const activation of this.activations.nextActiveActivationBatch()) {
|
|
930
925
|
const timeoutMs = this.options.instanceSpotIdleTimeoutMs?.get(activation.meshName) ?? 0;
|
|
931
926
|
if (
|
|
932
|
-
timeoutMs <= 0
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
927
|
+
timeoutMs <= 0 ||
|
|
928
|
+
activation.domain.kind !== 'instance' ||
|
|
929
|
+
!activation.isIdleFor(now, timeoutMs) ||
|
|
930
|
+
!activation.beginIdleEviction()
|
|
936
931
|
) {
|
|
937
932
|
continue;
|
|
938
933
|
}
|
|
939
934
|
let durableClosing: { restoreReady(): Promise<void> } | undefined;
|
|
940
935
|
try {
|
|
941
|
-
durableClosing = await (
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
) ?? Promise.resolve({ restoreReady: async () => undefined })
|
|
946
|
-
);
|
|
936
|
+
durableClosing = await (this.options.beginInstanceIdleClosingAuthority?.(
|
|
937
|
+
activation.meshName,
|
|
938
|
+
activation.spotId
|
|
939
|
+
) ?? Promise.resolve({ restoreReady: async () => undefined }));
|
|
947
940
|
} catch (error) {
|
|
948
941
|
activation.abortIdleEviction();
|
|
949
942
|
throw error;
|
|
@@ -1014,9 +1007,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1014
1007
|
const args = normalizeSpotCreateArgs(requestOrSignal, signal);
|
|
1015
1008
|
this.options.admission?.requireRequest('SPOT create', meshName);
|
|
1016
1009
|
const spotId = this.activations.allocateSpotId(meshName);
|
|
1017
|
-
const ownedRequest =
|
|
1018
|
-
|
|
1019
|
-
|
|
1010
|
+
const ownedRequest =
|
|
1011
|
+
args.request === undefined
|
|
1012
|
+
? RuntimeMessage.from(Buffer.alloc(0))
|
|
1013
|
+
: encodeFrameworkPayloadMessage(args.request, this.options.messageSerializers);
|
|
1020
1014
|
try {
|
|
1021
1015
|
return await this.createActivation(meshName, spotType, spotId, ownedRequest, args.signal);
|
|
1022
1016
|
} finally {
|
|
@@ -1074,9 +1068,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1074
1068
|
throwIfAborted(args.signal);
|
|
1075
1069
|
const operation = this.activations.getOrBegin(meshName, spotType, spotId, async () => {
|
|
1076
1070
|
this.options.admission?.requireRequest('SPOT create', meshName);
|
|
1077
|
-
const ownedRequest =
|
|
1078
|
-
|
|
1079
|
-
|
|
1071
|
+
const ownedRequest =
|
|
1072
|
+
args.request === undefined
|
|
1073
|
+
? RuntimeMessage.from(Buffer.alloc(0))
|
|
1074
|
+
: encodeFrameworkPayloadMessage(args.request, this.options.messageSerializers);
|
|
1080
1075
|
try {
|
|
1081
1076
|
return await this.createActivation(
|
|
1082
1077
|
meshName,
|
|
@@ -1104,25 +1099,29 @@ export class DefaultZLinkSpotManager {
|
|
|
1104
1099
|
}
|
|
1105
1100
|
|
|
1106
1101
|
async drainForShutdown(meshName: string, signal?: AbortSignal, deadline?: Date): Promise<void> {
|
|
1107
|
-
const results = await Promise.allSettled(
|
|
1108
|
-
.
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1102
|
+
const results = await Promise.allSettled(
|
|
1103
|
+
this.activations
|
|
1104
|
+
.activeActivations()
|
|
1105
|
+
.filter((activation) => activation.meshName === meshName)
|
|
1106
|
+
.map((activation) =>
|
|
1107
|
+
this.closeWithReason(
|
|
1108
|
+
meshName,
|
|
1109
|
+
activation.spotId,
|
|
1110
|
+
signal,
|
|
1111
|
+
ZLinkSpotCloseReason.HostShutdown,
|
|
1112
|
+
deadline
|
|
1113
|
+
)
|
|
1114
|
+
)
|
|
1115
|
+
);
|
|
1112
1116
|
const errors = results
|
|
1113
1117
|
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
|
1114
|
-
.map(result => result.reason);
|
|
1118
|
+
.map((result) => result.reason);
|
|
1115
1119
|
if (errors.length === 1) throw errors[0];
|
|
1116
1120
|
if (errors.length > 1) throw new AggregateError(errors, 'Spot shutdown cleanup failed.');
|
|
1117
1121
|
}
|
|
1118
1122
|
|
|
1119
1123
|
async close(meshName: string, spotId: RoutingId, signal?: AbortSignal): Promise<boolean> {
|
|
1120
|
-
return await this.closeWithReason(
|
|
1121
|
-
meshName,
|
|
1122
|
-
spotId,
|
|
1123
|
-
signal,
|
|
1124
|
-
ZLinkSpotCloseReason.ExplicitClose
|
|
1125
|
-
);
|
|
1124
|
+
return await this.closeWithReason(meshName, spotId, signal, ZLinkSpotCloseReason.ExplicitClose);
|
|
1126
1125
|
}
|
|
1127
1126
|
|
|
1128
1127
|
private async closeWithReason(
|
|
@@ -1166,9 +1165,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1166
1165
|
};
|
|
1167
1166
|
|
|
1168
1167
|
if (isInstance) {
|
|
1169
|
-
const beginAuthorityClose =
|
|
1170
|
-
|
|
1171
|
-
|
|
1168
|
+
const beginAuthorityClose =
|
|
1169
|
+
reason === ZLinkSpotCloseReason.ExplicitClose
|
|
1170
|
+
? this.options.beginInstanceClosingAuthority
|
|
1171
|
+
: undefined;
|
|
1172
1172
|
// Register the close gate before waiting for the current application
|
|
1173
1173
|
// and activation-authority terminal completions. A close requested from
|
|
1174
1174
|
// a handler cannot publish Closing until that handler's durable inbox
|
|
@@ -1182,9 +1182,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1182
1182
|
if (waitForApplication !== undefined) {
|
|
1183
1183
|
await waitForApplication;
|
|
1184
1184
|
}
|
|
1185
|
-
const closingAuthority =
|
|
1186
|
-
|
|
1187
|
-
|
|
1185
|
+
const closingAuthority =
|
|
1186
|
+
beginAuthorityClose === undefined
|
|
1187
|
+
? undefined
|
|
1188
|
+
: await beginAuthorityClose(meshName, spotId);
|
|
1188
1189
|
if (beginAuthorityClose !== undefined && closingAuthority === undefined) {
|
|
1189
1190
|
return false;
|
|
1190
1191
|
}
|
|
@@ -1209,7 +1210,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1209
1210
|
// that detached close finishes.
|
|
1210
1211
|
this.options.detachedTaskRunner?.runDetached(
|
|
1211
1212
|
`instance spot close ${String(spotId)}`,
|
|
1212
|
-
async () => {
|
|
1213
|
+
async () => {
|
|
1214
|
+
await trackedClosePromise;
|
|
1215
|
+
}
|
|
1213
1216
|
);
|
|
1214
1217
|
if (this.options.detachedTaskRunner === undefined) {
|
|
1215
1218
|
void trackedClosePromise.catch(() => undefined);
|
|
@@ -1225,10 +1228,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1225
1228
|
}
|
|
1226
1229
|
if (currentTurn) {
|
|
1227
1230
|
if (operation.started) {
|
|
1228
|
-
this.options.detachedTaskRunner?.runDetached(
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
);
|
|
1231
|
+
this.options.detachedTaskRunner?.runDetached(`spot close ${String(spotId)}`, async () => {
|
|
1232
|
+
await operation.ready;
|
|
1233
|
+
});
|
|
1232
1234
|
if (this.options.detachedTaskRunner === undefined) {
|
|
1233
1235
|
void operation.ready.catch(() => undefined);
|
|
1234
1236
|
}
|
|
@@ -1292,7 +1294,8 @@ export class DefaultZLinkSpotManager {
|
|
|
1292
1294
|
return undefined;
|
|
1293
1295
|
}
|
|
1294
1296
|
return {
|
|
1295
|
-
routerChannelId:
|
|
1297
|
+
routerChannelId:
|
|
1298
|
+
this.options.spotRouterChannelIdForMesh?.(activation.meshName) ?? activation.meshName,
|
|
1296
1299
|
targetNodeRid: nodeRid,
|
|
1297
1300
|
spotId: activation.spotId,
|
|
1298
1301
|
spotKind: ZLinkSpotKind.User,
|
|
@@ -1304,7 +1307,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1304
1307
|
spotId: RoutingId,
|
|
1305
1308
|
actor: ZLinkActor,
|
|
1306
1309
|
request: Message,
|
|
1307
|
-
commit: (
|
|
1310
|
+
commit: (
|
|
1311
|
+
spot: ZLinkSpot
|
|
1312
|
+
) => Promise<ZLinkActorJoinRollback | void> | ZLinkActorJoinRollback | void,
|
|
1308
1313
|
signal?: AbortSignal,
|
|
1309
1314
|
leaveSource?: () => Promise<void>,
|
|
1310
1315
|
contentType = 'application/json'
|
|
@@ -1322,11 +1327,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1322
1327
|
);
|
|
1323
1328
|
}
|
|
1324
1329
|
|
|
1325
|
-
async leaveActor(
|
|
1326
|
-
spotId: RoutingId,
|
|
1327
|
-
actor: ZLinkActor,
|
|
1328
|
-
signal?: AbortSignal
|
|
1329
|
-
): Promise<void> {
|
|
1330
|
+
async leaveActor(spotId: RoutingId, actor: ZLinkActor, signal?: AbortSignal): Promise<void> {
|
|
1330
1331
|
const meshName = this.activations.resolveUnique(spotId)?.meshName;
|
|
1331
1332
|
await this.actorMembership.leaveActor(spotId, actor, signal, meshName);
|
|
1332
1333
|
}
|
|
@@ -1440,11 +1441,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1440
1441
|
if (activation === undefined) {
|
|
1441
1442
|
throw new ZLinkConfigurationException(`Spot '${spotId}' is not active.`);
|
|
1442
1443
|
}
|
|
1443
|
-
return this.activationLifecycle.admitActorPacketPrefix(
|
|
1444
|
-
activation,
|
|
1445
|
-
actorId,
|
|
1446
|
-
records
|
|
1447
|
-
);
|
|
1444
|
+
return this.activationLifecycle.admitActorPacketPrefix(activation, actorId, records);
|
|
1448
1445
|
}
|
|
1449
1446
|
|
|
1450
1447
|
async dispatchRoutedSpotSend(
|
|
@@ -1477,7 +1474,11 @@ export class DefaultZLinkSpotManager {
|
|
|
1477
1474
|
return await this.routedSpotPackets.request<TReply>(spotId, packetName, request, context);
|
|
1478
1475
|
}
|
|
1479
1476
|
|
|
1480
|
-
async dispatchMeshSpot(
|
|
1477
|
+
async dispatchMeshSpot(
|
|
1478
|
+
meshName: string,
|
|
1479
|
+
owner: ReadyRecord,
|
|
1480
|
+
record: ReceiveRecord
|
|
1481
|
+
): Promise<void> {
|
|
1481
1482
|
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
1482
1483
|
if (spotId === null) {
|
|
1483
1484
|
throw new ZLinkConfigurationException('MeshNode Spot record is missing the owner Spot RID.');
|
|
@@ -1490,7 +1491,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1490
1491
|
);
|
|
1491
1492
|
}
|
|
1492
1493
|
if (record.topic === null || record.topic.length === 0) {
|
|
1493
|
-
throw new ZLinkConfigurationException(
|
|
1494
|
+
throw new ZLinkConfigurationException(
|
|
1495
|
+
'MeshNode Spot multicast record is missing its topic.'
|
|
1496
|
+
);
|
|
1494
1497
|
}
|
|
1495
1498
|
await activation.actorDispatch.dispatchSubscriptionRecord(
|
|
1496
1499
|
record.topic,
|
|
@@ -1505,9 +1508,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1505
1508
|
this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
|
|
1506
1509
|
);
|
|
1507
1510
|
const packetName = envelope.packetName;
|
|
1508
|
-
const codecs =
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
+
const codecs =
|
|
1512
|
+
this.options.messageSerializers === undefined
|
|
1513
|
+
? undefined
|
|
1514
|
+
: { serializers: this.options.messageSerializers };
|
|
1511
1515
|
const decodePayload = () => decodeChannelPayload(envelope, codecs);
|
|
1512
1516
|
const context = {
|
|
1513
1517
|
channelName: envelope.header.channelName,
|
|
@@ -1523,7 +1527,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1523
1527
|
return;
|
|
1524
1528
|
}
|
|
1525
1529
|
if (record.kind !== ReceiveKind.SpotRequest) {
|
|
1526
|
-
throw new ZLinkConfigurationException(
|
|
1530
|
+
throw new ZLinkConfigurationException(
|
|
1531
|
+
`Unsupported MeshNode Spot record kind '${record.kind}'.`
|
|
1532
|
+
);
|
|
1527
1533
|
}
|
|
1528
1534
|
try {
|
|
1529
1535
|
await this.ensureInstanceApplicationActivation(meshName, spotId);
|
|
@@ -1533,12 +1539,18 @@ export class DefaultZLinkSpotManager {
|
|
|
1533
1539
|
decodePayload,
|
|
1534
1540
|
context
|
|
1535
1541
|
);
|
|
1536
|
-
requireMeshSpotReply(
|
|
1542
|
+
requireMeshSpotReply(
|
|
1543
|
+
record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
|
|
1544
|
+
);
|
|
1537
1545
|
} catch (error) {
|
|
1538
|
-
requireMeshSpotReply(
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1546
|
+
requireMeshSpotReply(
|
|
1547
|
+
record.reply(
|
|
1548
|
+
encodeChannelErrorReplyParts(
|
|
1549
|
+
envelope.header,
|
|
1550
|
+
error instanceof Error ? error.message : String(error)
|
|
1551
|
+
)
|
|
1552
|
+
)
|
|
1553
|
+
);
|
|
1542
1554
|
}
|
|
1543
1555
|
}
|
|
1544
1556
|
|
|
@@ -1551,16 +1563,12 @@ export class DefaultZLinkSpotManager {
|
|
|
1551
1563
|
for (;;) {
|
|
1552
1564
|
const current = this.activations.resolve(meshName, spotId);
|
|
1553
1565
|
if (
|
|
1554
|
-
current !== undefined
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
)
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
target.stableType,
|
|
1561
|
-
spotId,
|
|
1562
|
-
target.objectGeneration
|
|
1563
|
-
);
|
|
1566
|
+
current !== undefined &&
|
|
1567
|
+
current.objectGeneration === target.objectGeneration &&
|
|
1568
|
+
current.spotType === this.requireInstanceFactory(meshName, target.stableType)
|
|
1569
|
+
)
|
|
1570
|
+
return;
|
|
1571
|
+
await this.materializeInstance(meshName, target.stableType, spotId, target.objectGeneration);
|
|
1564
1572
|
const latest = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
|
|
1565
1573
|
if (latest === undefined) {
|
|
1566
1574
|
throw createInternalFrameworkException(
|
|
@@ -1592,7 +1600,8 @@ export class DefaultZLinkSpotManager {
|
|
|
1592
1600
|
const inboundFlow = createInboundFlow(
|
|
1593
1601
|
envelope.header.flowId,
|
|
1594
1602
|
envelope.header.flowOrigin,
|
|
1595
|
-
this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
|
|
1603
|
+
this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true,
|
|
1604
|
+
undefined
|
|
1596
1605
|
);
|
|
1597
1606
|
await runWithFlow(inboundFlow, async () => {
|
|
1598
1607
|
const request = record.operationKind === OperationKind.InstanceSpotRequest;
|
|
@@ -1613,16 +1622,19 @@ export class DefaultZLinkSpotManager {
|
|
|
1613
1622
|
);
|
|
1614
1623
|
}
|
|
1615
1624
|
const target = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
|
|
1616
|
-
if (
|
|
1617
|
-
|
|
1625
|
+
if (
|
|
1626
|
+
target !== undefined &&
|
|
1627
|
+
activation.domain.objectGeneration !== target.objectGeneration
|
|
1628
|
+
) {
|
|
1618
1629
|
throw createInternalFrameworkException(
|
|
1619
1630
|
ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
|
|
1620
1631
|
`Instance Spot target '${String(spotId)}' application generation is stale.`
|
|
1621
1632
|
);
|
|
1622
1633
|
}
|
|
1623
|
-
const codecs =
|
|
1624
|
-
|
|
1625
|
-
|
|
1634
|
+
const codecs =
|
|
1635
|
+
this.options.messageSerializers === undefined
|
|
1636
|
+
? undefined
|
|
1637
|
+
: { serializers: this.options.messageSerializers };
|
|
1626
1638
|
const decodePayload = () => decodeChannelPayload(envelope, codecs);
|
|
1627
1639
|
const context = {
|
|
1628
1640
|
channelName: envelope.header.channelName,
|
|
@@ -1630,7 +1642,8 @@ export class DefaultZLinkSpotManager {
|
|
|
1630
1642
|
awaitFirstHandlerTurn: record.kind === ReceiveKind.InstanceSpotActivation,
|
|
1631
1643
|
workOptions: zlinkSerialWorkOptions(
|
|
1632
1644
|
envelope.payload.byteLength,
|
|
1633
|
-
record.applicationMetadata?.byteLength ??
|
|
1645
|
+
record.applicationMetadata?.byteLength ??
|
|
1646
|
+
zlinkMetadataByteLength(envelope.header.metadata)
|
|
1634
1647
|
)
|
|
1635
1648
|
};
|
|
1636
1649
|
this.traceInstanceMessage(
|
|
@@ -1652,7 +1665,12 @@ export class DefaultZLinkSpotManager {
|
|
|
1652
1665
|
'ready',
|
|
1653
1666
|
target?.stableType
|
|
1654
1667
|
);
|
|
1655
|
-
await this.routedSpotPackets.sendEncoded(
|
|
1668
|
+
await this.routedSpotPackets.sendEncoded(
|
|
1669
|
+
spotId,
|
|
1670
|
+
envelope.packetName,
|
|
1671
|
+
decodePayload,
|
|
1672
|
+
context
|
|
1673
|
+
);
|
|
1656
1674
|
this.traceInstanceMessage(
|
|
1657
1675
|
ZLinkMessageFlowOutcome.Completed,
|
|
1658
1676
|
meshName,
|
|
@@ -1679,7 +1697,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1679
1697
|
decodePayload,
|
|
1680
1698
|
context
|
|
1681
1699
|
);
|
|
1682
|
-
requireMeshSpotReply(
|
|
1700
|
+
requireMeshSpotReply(
|
|
1701
|
+
record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
|
|
1702
|
+
);
|
|
1683
1703
|
this.traceInstanceMessage(
|
|
1684
1704
|
ZLinkMessageFlowOutcome.Replied,
|
|
1685
1705
|
meshName,
|
|
@@ -1713,7 +1733,8 @@ export class DefaultZLinkSpotManager {
|
|
|
1713
1733
|
correlationId: envelope.header.correlationId ?? undefined,
|
|
1714
1734
|
sourceRid: record.sourceNodeRid === null ? undefined : String(record.sourceNodeRid),
|
|
1715
1735
|
spotId: String(spotId),
|
|
1716
|
-
instanceSpotType: this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId)
|
|
1736
|
+
instanceSpotType: this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId)
|
|
1737
|
+
?.stableType,
|
|
1717
1738
|
activationState: 'closing',
|
|
1718
1739
|
flowId: envelope.header.flowId,
|
|
1719
1740
|
flowOrigin: envelope.header.flowOrigin,
|
|
@@ -1721,10 +1742,14 @@ export class DefaultZLinkSpotManager {
|
|
|
1721
1742
|
action: ZLinkDispatchErrorAction.ReplyError,
|
|
1722
1743
|
error
|
|
1723
1744
|
});
|
|
1724
|
-
requireMeshSpotReply(
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1745
|
+
requireMeshSpotReply(
|
|
1746
|
+
record.reply(
|
|
1747
|
+
encodeChannelErrorReplyParts(
|
|
1748
|
+
envelope.header,
|
|
1749
|
+
error instanceof Error ? error.message : String(error)
|
|
1750
|
+
)
|
|
1751
|
+
)
|
|
1752
|
+
);
|
|
1728
1753
|
}
|
|
1729
1754
|
});
|
|
1730
1755
|
}
|
|
@@ -1749,9 +1774,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1749
1774
|
flow.trace({
|
|
1750
1775
|
outcome,
|
|
1751
1776
|
surface: ZLinkDispatchErrorSurface.InstanceSpot,
|
|
1752
|
-
messageKind:
|
|
1753
|
-
|
|
1754
|
-
|
|
1777
|
+
messageKind:
|
|
1778
|
+
record.operationKind === OperationKind.InstanceSpotRequest
|
|
1779
|
+
? ZLinkDispatchMessageKind.Request
|
|
1780
|
+
: ZLinkDispatchMessageKind.Send,
|
|
1755
1781
|
packetName: envelope.packetName,
|
|
1756
1782
|
channelName: envelope.header.channelName,
|
|
1757
1783
|
meshName,
|
|
@@ -1766,11 +1792,15 @@ export class DefaultZLinkSpotManager {
|
|
|
1766
1792
|
});
|
|
1767
1793
|
}
|
|
1768
1794
|
|
|
1769
|
-
async dispatchMeshActor(
|
|
1795
|
+
async dispatchMeshActor(
|
|
1796
|
+
meshName: string,
|
|
1797
|
+
owner: ReadyRecord,
|
|
1798
|
+
record: ReceiveRecord
|
|
1799
|
+
): Promise<void> {
|
|
1770
1800
|
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
1771
1801
|
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
1772
|
-
const targetsEntrySpot =
|
|
1773
|
-
|| (entrySpotId !== undefined && spotId === entrySpotId);
|
|
1802
|
+
const targetsEntrySpot =
|
|
1803
|
+
spotId === null || (entrySpotId !== undefined && spotId === entrySpotId);
|
|
1774
1804
|
const actor = owner.actor;
|
|
1775
1805
|
if (actor === null) {
|
|
1776
1806
|
throw new ZLinkConfigurationException('MeshNode Actor record is missing its Actor owner.');
|
|
@@ -1786,24 +1816,26 @@ export class DefaultZLinkSpotManager {
|
|
|
1786
1816
|
meshName,
|
|
1787
1817
|
nodeRid: String(actor.nodeRid)
|
|
1788
1818
|
};
|
|
1789
|
-
const responseActorRef =
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1819
|
+
const responseActorRef =
|
|
1820
|
+
record.sourceBindingGeneration > 0n
|
|
1821
|
+
? ({
|
|
1822
|
+
...resolvedActorRef,
|
|
1823
|
+
bindingGeneration: record.sourceBindingGeneration
|
|
1824
|
+
} as ActorRef)
|
|
1825
|
+
: resolvedActorRef;
|
|
1795
1826
|
const ownerActorRef = responseActorRef;
|
|
1796
1827
|
const requestTerminalState = { prepared: false, submitted: false };
|
|
1797
1828
|
const requestTerminal = request
|
|
1798
1829
|
? Object.assign(
|
|
1799
1830
|
(response: unknown, preparedReply?: unknown) => {
|
|
1800
|
-
const encoded =
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1831
|
+
const encoded =
|
|
1832
|
+
preparedReply === undefined
|
|
1833
|
+
? this.encodeMeshActorReply(
|
|
1834
|
+
record.parts[0],
|
|
1835
|
+
ZLinkStreamMessageKind.Response,
|
|
1836
|
+
response
|
|
1837
|
+
)
|
|
1838
|
+
: (preparedReply as readonly Buffer[]);
|
|
1807
1839
|
requireMeshSpotReply(record.reply(encoded));
|
|
1808
1840
|
requestTerminalState.submitted = true;
|
|
1809
1841
|
},
|
|
@@ -1822,39 +1854,39 @@ export class DefaultZLinkSpotManager {
|
|
|
1822
1854
|
: undefined;
|
|
1823
1855
|
try {
|
|
1824
1856
|
if (this.formalRemoteTransfers.has(actor.actorId)) {
|
|
1825
|
-
throw new Error(
|
|
1826
|
-
`Actor '${actor.actorId}' target transfer reconciliation is not complete.`
|
|
1827
|
-
);
|
|
1857
|
+
throw new Error(`Actor '${actor.actorId}' target transfer reconciliation is not complete.`);
|
|
1828
1858
|
}
|
|
1829
1859
|
const response = targetsEntrySpot
|
|
1830
1860
|
? await this.options.dispatchEntryActorPacket?.(
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1861
|
+
actor.actorId,
|
|
1862
|
+
record.parts,
|
|
1863
|
+
request,
|
|
1864
|
+
undefined,
|
|
1865
|
+
ownerActorRef,
|
|
1866
|
+
requestTerminal,
|
|
1867
|
+
record.messageFollowOrigin
|
|
1868
|
+
)
|
|
1839
1869
|
: await this.dispatchMeshActorPacket(
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1870
|
+
meshName,
|
|
1871
|
+
spotId,
|
|
1872
|
+
actor.actorId,
|
|
1873
|
+
record.parts,
|
|
1874
|
+
request,
|
|
1875
|
+
ownerActorRef,
|
|
1876
|
+
requestTerminal,
|
|
1877
|
+
record.messageFollowOrigin
|
|
1878
|
+
);
|
|
1849
1879
|
if (targetsEntrySpot && this.options.dispatchEntryActorPacket === undefined) {
|
|
1850
|
-
throw new ZLinkConfigurationException(
|
|
1880
|
+
throw new ZLinkConfigurationException(
|
|
1881
|
+
'MeshNode Entry Spot Actor dispatch is not configured.'
|
|
1882
|
+
);
|
|
1851
1883
|
}
|
|
1852
1884
|
if (request && !requestTerminalState.submitted) {
|
|
1853
|
-
requireMeshSpotReply(
|
|
1854
|
-
record.
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
)
|
|
1885
|
+
requireMeshSpotReply(
|
|
1886
|
+
record.reply(
|
|
1887
|
+
this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Response, response)
|
|
1888
|
+
)
|
|
1889
|
+
);
|
|
1858
1890
|
}
|
|
1859
1891
|
} catch (error) {
|
|
1860
1892
|
if (!request) {
|
|
@@ -1863,50 +1895,59 @@ export class DefaultZLinkSpotManager {
|
|
|
1863
1895
|
if (requestTerminalState.prepared || requestTerminalState.submitted) {
|
|
1864
1896
|
throw error;
|
|
1865
1897
|
}
|
|
1866
|
-
requireMeshSpotReply(
|
|
1867
|
-
record.
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1898
|
+
requireMeshSpotReply(
|
|
1899
|
+
record.reply(
|
|
1900
|
+
this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Error, {
|
|
1901
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1902
|
+
kind:
|
|
1903
|
+
error instanceof ZLinkFrameworkException
|
|
1904
|
+
? error.kind
|
|
1905
|
+
: ZLinkFrameworkErrorKind.InternalFailure
|
|
1906
|
+
})
|
|
1907
|
+
)
|
|
1908
|
+
);
|
|
1876
1909
|
}
|
|
1877
1910
|
}
|
|
1878
1911
|
|
|
1879
|
-
async dispatchMeshActorJoin(
|
|
1912
|
+
async dispatchMeshActorJoin(
|
|
1913
|
+
meshName: string,
|
|
1914
|
+
owner: ReadyRecord,
|
|
1915
|
+
record: ReceiveRecord
|
|
1916
|
+
): Promise<void> {
|
|
1880
1917
|
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
1881
1918
|
const control = record.kindData;
|
|
1882
1919
|
if (control?.kind !== 'actorControl') {
|
|
1883
|
-
throw new ZLinkConfigurationException(
|
|
1920
|
+
throw new ZLinkConfigurationException(
|
|
1921
|
+
'MeshNode Actor join record is missing lifecycle identity data.'
|
|
1922
|
+
);
|
|
1884
1923
|
}
|
|
1885
1924
|
const actorId = control.currentActor?.actorId;
|
|
1886
1925
|
if (spotId === null || actorId === undefined) {
|
|
1887
|
-
throw new ZLinkConfigurationException(
|
|
1926
|
+
throw new ZLinkConfigurationException(
|
|
1927
|
+
'MeshNode Actor join record is missing its Spot or Actor owner.'
|
|
1928
|
+
);
|
|
1888
1929
|
}
|
|
1889
1930
|
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
1890
1931
|
let requestContentType = record.contentType ?? 'application/json';
|
|
1891
|
-
const targetsEntrySpot = entrySpotId !== undefined
|
|
1892
|
-
&& String(spotId) === String(entrySpotId);
|
|
1932
|
+
const targetsEntrySpot = entrySpotId !== undefined && String(spotId) === String(entrySpotId);
|
|
1893
1933
|
const activation = this.activations.resolve(meshName, spotId);
|
|
1894
|
-
const transferRequest =
|
|
1895
|
-
? undefined
|
|
1896
|
-
: decodeFormalRemoteTransferRequest(record.parts[0]!);
|
|
1934
|
+
const transferRequest =
|
|
1935
|
+
record.parts.length === 0 ? undefined : decodeFormalRemoteTransferRequest(record.parts[0]!);
|
|
1897
1936
|
const remoteJoinPhase = transferRequest?.phase;
|
|
1898
1937
|
const isRemoteAdmission = remoteJoinPhase === REMOTE_ACTOR_JOIN_ADMISSION;
|
|
1899
1938
|
const isRemoteCommit = remoteJoinPhase === REMOTE_ACTOR_JOIN_COMMIT;
|
|
1900
1939
|
const isRemoteAbort = remoteJoinPhase === REMOTE_ACTOR_JOIN_ABORT;
|
|
1901
|
-
let admissionRecord =
|
|
1902
|
-
|
|
1903
|
-
|
|
1940
|
+
let admissionRecord =
|
|
1941
|
+
transferRequest !== undefined
|
|
1942
|
+
? this.formalRemoteActorAdmissions.get(transferRequest.transferId)
|
|
1943
|
+
: undefined;
|
|
1904
1944
|
let canonicalAdmissionCreated = false;
|
|
1905
1945
|
let pendingAdmission = isRemoteCommit ? admissionRecord : undefined;
|
|
1906
1946
|
let commitAdmissionMissing = isRemoteCommit && admissionRecord === undefined;
|
|
1907
|
-
const applicationClaim =
|
|
1908
|
-
|
|
1909
|
-
|
|
1947
|
+
const applicationClaim =
|
|
1948
|
+
transferRequest === undefined
|
|
1949
|
+
? this.options.admission?.claim(meshName, 'Actor join dispatch')
|
|
1950
|
+
: undefined;
|
|
1910
1951
|
let canonicalActorType: string | undefined;
|
|
1911
1952
|
if (control.canonicalActorJoin !== undefined) {
|
|
1912
1953
|
const resolver = this.options.canonicalActorJoinResolver;
|
|
@@ -1962,9 +2003,8 @@ export class DefaultZLinkSpotManager {
|
|
|
1962
2003
|
if (actor === undefined && admissionRecord?.actor !== undefined) {
|
|
1963
2004
|
actor = admissionRecord.actor;
|
|
1964
2005
|
}
|
|
1965
|
-
let callbackRequest: Message | undefined =
|
|
1966
|
-
? undefined
|
|
1967
|
-
: record.parts[0]!;
|
|
2006
|
+
let callbackRequest: Message | undefined =
|
|
2007
|
+
record.parts.length === 0 ? undefined : record.parts[0]!;
|
|
1968
2008
|
let ownedCallbackRequest: Message | undefined;
|
|
1969
2009
|
let materialized = false;
|
|
1970
2010
|
let reply: Message | undefined;
|
|
@@ -1972,13 +2012,11 @@ export class DefaultZLinkSpotManager {
|
|
|
1972
2012
|
let preparedTransferState: Message | undefined;
|
|
1973
2013
|
let admissionOutcome: ZLinkFormalRemoteActorAdmissionResult | undefined;
|
|
1974
2014
|
let accepted = false;
|
|
1975
|
-
let committedAdmissionReplay = isRemoteCommit
|
|
1976
|
-
&& admissionRecord?.state === 'committed';
|
|
2015
|
+
let committedAdmissionReplay = isRemoteCommit && admissionRecord?.state === 'committed';
|
|
1977
2016
|
let targetCommitPublished: boolean | undefined;
|
|
1978
|
-
const actorJoinIsCurrent = (): boolean =>
|
|
1979
|
-
(record.deadlineUnixMs === undefined || record.deadlineUnixMs > BigInt(Date.now()))
|
|
1980
|
-
|
|
1981
|
-
);
|
|
2017
|
+
const actorJoinIsCurrent = (): boolean =>
|
|
2018
|
+
(record.deadlineUnixMs === undefined || record.deadlineUnixMs > BigInt(Date.now())) &&
|
|
2019
|
+
(record.isPending?.() ?? true);
|
|
1982
2020
|
const abandonStaleAdmission = (): void => {
|
|
1983
2021
|
if (isRemoteAdmission && transferRequest !== undefined) {
|
|
1984
2022
|
this.formalRemoteActorAdmissions.abort(transferRequest.transferId);
|
|
@@ -1997,14 +2035,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1997
2035
|
return;
|
|
1998
2036
|
}
|
|
1999
2037
|
if (transferRequest !== undefined) {
|
|
2000
|
-
ownedCallbackRequest = RuntimeMessage.from(
|
|
2001
|
-
Buffer.from(transferRequest.request, 'base64')
|
|
2002
|
-
);
|
|
2038
|
+
ownedCallbackRequest = RuntimeMessage.from(Buffer.from(transferRequest.request, 'base64'));
|
|
2003
2039
|
callbackRequest = ownedCallbackRequest;
|
|
2004
2040
|
} else if (callbackRequest !== undefined) {
|
|
2005
|
-
ownedCallbackRequest = RuntimeMessage.from(
|
|
2006
|
-
callbackRequest.data()
|
|
2007
|
-
);
|
|
2041
|
+
ownedCallbackRequest = RuntimeMessage.from(callbackRequest.data());
|
|
2008
2042
|
callbackRequest = ownedCallbackRequest;
|
|
2009
2043
|
}
|
|
2010
2044
|
if (control.canonicalActorJoin !== undefined) {
|
|
@@ -2026,15 +2060,15 @@ export class DefaultZLinkSpotManager {
|
|
|
2026
2060
|
admissionRecord = this.formalRemoteActorAdmissions.finalizeProvisional(
|
|
2027
2061
|
control.canonicalActorJoin.handoffId,
|
|
2028
2062
|
{
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2063
|
+
actorId,
|
|
2064
|
+
actorType,
|
|
2065
|
+
actorRef,
|
|
2066
|
+
spotId,
|
|
2067
|
+
targetSpotGeneration: control.currentSpotGeneration,
|
|
2068
|
+
expectedMembershipEpoch: control.currentMembershipEpoch,
|
|
2069
|
+
requestFingerprint: callbackRequest.data().toString('base64'),
|
|
2070
|
+
transferId: control.canonicalActorJoin.handoffId,
|
|
2071
|
+
sourceActorNodeRid: control.canonicalActorJoin.actorNodeRid as RoutingId
|
|
2038
2072
|
}
|
|
2039
2073
|
);
|
|
2040
2074
|
if (canonicalAdmissionCreated) {
|
|
@@ -2058,9 +2092,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2058
2092
|
);
|
|
2059
2093
|
let encodedReply: Message | undefined;
|
|
2060
2094
|
try {
|
|
2061
|
-
encodedReply =
|
|
2062
|
-
|
|
2063
|
-
|
|
2095
|
+
encodedReply =
|
|
2096
|
+
response.reply === undefined
|
|
2097
|
+
? undefined
|
|
2098
|
+
: encodeFrameworkPayloadMessage(response.reply, this.options.messageSerializers);
|
|
2064
2099
|
admissionOutcome = {
|
|
2065
2100
|
accepted: response.accepted,
|
|
2066
2101
|
actorRef,
|
|
@@ -2080,18 +2115,15 @@ export class DefaultZLinkSpotManager {
|
|
|
2080
2115
|
admissionOutcome
|
|
2081
2116
|
);
|
|
2082
2117
|
}
|
|
2083
|
-
admissionOutcome = admissionRecord.result ?? await admissionRecord.resultTask;
|
|
2118
|
+
admissionOutcome = admissionRecord.result ?? (await admissionRecord.resultTask);
|
|
2084
2119
|
if ('error' in admissionOutcome) throw admissionOutcome.error;
|
|
2085
2120
|
accepted = admissionOutcome.accepted;
|
|
2086
|
-
reply =
|
|
2087
|
-
|
|
2088
|
-
|
|
2121
|
+
reply =
|
|
2122
|
+
admissionOutcome.reply === undefined
|
|
2123
|
+
? undefined
|
|
2124
|
+
: RuntimeMessage.from(admissionOutcome.reply);
|
|
2089
2125
|
}
|
|
2090
|
-
if (
|
|
2091
|
-
transferRequest !== undefined
|
|
2092
|
-
&& !targetsEntrySpot
|
|
2093
|
-
&& remoteJoinPhase === undefined
|
|
2094
|
-
) {
|
|
2126
|
+
if (transferRequest !== undefined && !targetsEntrySpot && remoteJoinPhase === undefined) {
|
|
2095
2127
|
// User Spot transfers must carry the private admission/commit phases.
|
|
2096
2128
|
// A legacy one-phase request would otherwise read relocation state
|
|
2097
2129
|
// before the target application has accepted the Actor.
|
|
@@ -2121,12 +2153,12 @@ export class DefaultZLinkSpotManager {
|
|
|
2121
2153
|
try {
|
|
2122
2154
|
if (targetsEntrySpot) {
|
|
2123
2155
|
if (
|
|
2124
|
-
this.options.dispatchEntryActorJoin !== undefined
|
|
2125
|
-
|
|
2126
|
-
|
|
2156
|
+
this.options.dispatchEntryActorJoin !== undefined &&
|
|
2157
|
+
transferRequest.completionOperationId !== undefined &&
|
|
2158
|
+
this.options.actorTransferRuntime !== undefined
|
|
2127
2159
|
) {
|
|
2128
|
-
deferredJoinRoot =
|
|
2129
|
-
.prepareDeferredJoinAccepted(
|
|
2160
|
+
deferredJoinRoot =
|
|
2161
|
+
await this.options.actorTransferRuntime.prepareDeferredJoinAccepted(
|
|
2130
2162
|
actorId,
|
|
2131
2163
|
transferRequest.completionOperationId,
|
|
2132
2164
|
actorRef,
|
|
@@ -2157,16 +2189,20 @@ export class DefaultZLinkSpotManager {
|
|
|
2157
2189
|
);
|
|
2158
2190
|
let encodedReply: Message | undefined;
|
|
2159
2191
|
try {
|
|
2160
|
-
encodedReply =
|
|
2161
|
-
|
|
2162
|
-
|
|
2192
|
+
encodedReply =
|
|
2193
|
+
response.reply === undefined
|
|
2194
|
+
? undefined
|
|
2195
|
+
: encodeFrameworkPayloadMessage(
|
|
2196
|
+
response.reply,
|
|
2197
|
+
this.options.messageSerializers
|
|
2198
|
+
);
|
|
2163
2199
|
if (
|
|
2164
|
-
response.accepted
|
|
2165
|
-
|
|
2166
|
-
|
|
2200
|
+
response.accepted &&
|
|
2201
|
+
transferRequest.completionOperationId !== undefined &&
|
|
2202
|
+
this.options.actorTransferRuntime !== undefined
|
|
2167
2203
|
) {
|
|
2168
|
-
deferredJoinRoot =
|
|
2169
|
-
.prepareDeferredJoinAccepted(
|
|
2204
|
+
deferredJoinRoot =
|
|
2205
|
+
await this.options.actorTransferRuntime.prepareDeferredJoinAccepted(
|
|
2170
2206
|
actorId,
|
|
2171
2207
|
transferRequest.completionOperationId,
|
|
2172
2208
|
actorRef,
|
|
@@ -2201,10 +2237,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2201
2237
|
return;
|
|
2202
2238
|
}
|
|
2203
2239
|
}
|
|
2204
|
-
this.formalRemoteActorAdmissions.complete(
|
|
2205
|
-
transferRequest.transferId,
|
|
2206
|
-
admissionOutcome
|
|
2207
|
-
);
|
|
2240
|
+
this.formalRemoteActorAdmissions.complete(transferRequest.transferId, admissionOutcome);
|
|
2208
2241
|
} catch (error) {
|
|
2209
2242
|
this.formalRemoteActorAdmissions.fail(transferRequest.transferId, error);
|
|
2210
2243
|
throw error;
|
|
@@ -2215,9 +2248,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2215
2248
|
throw admissionOutcome.error;
|
|
2216
2249
|
}
|
|
2217
2250
|
accepted = admissionOutcome.accepted;
|
|
2218
|
-
reply =
|
|
2219
|
-
|
|
2220
|
-
|
|
2251
|
+
reply =
|
|
2252
|
+
admissionOutcome.reply === undefined
|
|
2253
|
+
? undefined
|
|
2254
|
+
: RuntimeMessage.from(admissionOutcome.reply);
|
|
2221
2255
|
}
|
|
2222
2256
|
if (isRemoteCommit && admissionRecord !== undefined) {
|
|
2223
2257
|
admissionOutcome = await admissionRecord.resultTask;
|
|
@@ -2227,13 +2261,13 @@ export class DefaultZLinkSpotManager {
|
|
|
2227
2261
|
deferredJoinRoot = admissionOutcome.deferredJoinRoot;
|
|
2228
2262
|
}
|
|
2229
2263
|
if (
|
|
2230
|
-
actor === undefined
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2264
|
+
actor === undefined &&
|
|
2265
|
+
transferRequest !== undefined &&
|
|
2266
|
+
this.options.actorTransferRuntime !== undefined &&
|
|
2267
|
+
!isRemoteAdmission &&
|
|
2268
|
+
!commitAdmissionMissing &&
|
|
2269
|
+
admissionRecord?.state !== 'committed' &&
|
|
2270
|
+
(targetsEntrySpot || activation !== undefined)
|
|
2237
2271
|
) {
|
|
2238
2272
|
// Relocation state travels inline with the join request. The store
|
|
2239
2273
|
// reference handoff was removed with the direct-transfer contract
|
|
@@ -2248,13 +2282,13 @@ export class DefaultZLinkSpotManager {
|
|
|
2248
2282
|
);
|
|
2249
2283
|
}
|
|
2250
2284
|
if (isRemoteAdmission && targetsEntrySpot) {
|
|
2251
|
-
accepted =
|
|
2252
|
-
|
|
2253
|
-
|
|
2285
|
+
accepted =
|
|
2286
|
+
admissionOutcome !== undefined &&
|
|
2287
|
+
!('error' in admissionOutcome) &&
|
|
2288
|
+
admissionOutcome.accepted;
|
|
2254
2289
|
} else if (isRemoteCommit && pendingAdmission !== undefined) {
|
|
2255
2290
|
validateRemoteAdmissionCommit(pendingAdmission, transferRequest!, actorId, control);
|
|
2256
|
-
accepted = pendingAdmission.state === 'admitted'
|
|
2257
|
-
|| pendingAdmission.state === 'committed';
|
|
2291
|
+
accepted = pendingAdmission.state === 'admitted' || pendingAdmission.state === 'committed';
|
|
2258
2292
|
} else if (commitAdmissionMissing) {
|
|
2259
2293
|
accepted = false;
|
|
2260
2294
|
} else if (targetsEntrySpot) {
|
|
@@ -2262,15 +2296,15 @@ export class DefaultZLinkSpotManager {
|
|
|
2262
2296
|
// actor-manager transaction is committed after the Core reply below.
|
|
2263
2297
|
// A formal transfer payload materializes the existing actor state at
|
|
2264
2298
|
// the Entry owner before that transaction is committed.
|
|
2265
|
-
accepted =
|
|
2266
|
-
|
|
2299
|
+
accepted =
|
|
2300
|
+
actor !== undefined ||
|
|
2301
|
+
(transferRequest !== undefined && this.options.actorTransferRuntime !== undefined);
|
|
2267
2302
|
} else if (
|
|
2268
|
-
!isRemoteAdmission
|
|
2269
|
-
|
|
2270
|
-
&&
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
&& (actor !== undefined || transferRequest !== undefined)
|
|
2303
|
+
!isRemoteAdmission &&
|
|
2304
|
+
control.canonicalActorJoin === undefined &&
|
|
2305
|
+
activation !== undefined &&
|
|
2306
|
+
callbackRequest !== undefined &&
|
|
2307
|
+
(actor !== undefined || transferRequest !== undefined)
|
|
2274
2308
|
) {
|
|
2275
2309
|
if (!actorJoinIsCurrent()) return;
|
|
2276
2310
|
const request = callbackRequest;
|
|
@@ -2280,9 +2314,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2280
2314
|
}
|
|
2281
2315
|
const actorRef: ActorRef = {
|
|
2282
2316
|
actorId: rawActorRef.actorId,
|
|
2283
|
-
objectGeneration:
|
|
2284
|
-
|
|
2285
|
-
|
|
2317
|
+
objectGeneration:
|
|
2318
|
+
'objectGeneration' in rawActorRef
|
|
2319
|
+
? rawActorRef.objectGeneration
|
|
2320
|
+
: rawActorRef.generation,
|
|
2286
2321
|
meshName,
|
|
2287
2322
|
nodeRid: rawActorRef.nodeRid as unknown as RoutingId
|
|
2288
2323
|
};
|
|
@@ -2298,22 +2333,22 @@ export class DefaultZLinkSpotManager {
|
|
|
2298
2333
|
);
|
|
2299
2334
|
if (!actorJoinIsCurrent()) return;
|
|
2300
2335
|
accepted = response.accepted;
|
|
2301
|
-
reply =
|
|
2302
|
-
|
|
2303
|
-
|
|
2336
|
+
reply =
|
|
2337
|
+
response.reply === undefined
|
|
2338
|
+
? undefined
|
|
2339
|
+
: encodeFrameworkPayloadMessage(response.reply, this.options.messageSerializers);
|
|
2304
2340
|
if (
|
|
2305
|
-
accepted
|
|
2306
|
-
|
|
2307
|
-
|
|
2341
|
+
accepted &&
|
|
2342
|
+
transferRequest?.completionOperationId !== undefined &&
|
|
2343
|
+
this.options.actorTransferRuntime !== undefined
|
|
2308
2344
|
) {
|
|
2309
|
-
deferredJoinRoot = await this.options.actorTransferRuntime
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
);
|
|
2345
|
+
deferredJoinRoot = await this.options.actorTransferRuntime.prepareDeferredJoinAccepted(
|
|
2346
|
+
actorId,
|
|
2347
|
+
transferRequest.completionOperationId,
|
|
2348
|
+
actorRef,
|
|
2349
|
+
reply?.data() ?? Buffer.alloc(0),
|
|
2350
|
+
reply === undefined ? undefined : frameworkPayloadContentType(reply)
|
|
2351
|
+
);
|
|
2317
2352
|
this.options.runtimeEventPublisher?.publish({
|
|
2318
2353
|
sourceName: 'zlink.framework.actor-handoff',
|
|
2319
2354
|
timestamp: new Date(),
|
|
@@ -2323,11 +2358,11 @@ export class DefaultZLinkSpotManager {
|
|
|
2323
2358
|
}
|
|
2324
2359
|
}
|
|
2325
2360
|
if (
|
|
2326
|
-
accepted
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2361
|
+
accepted &&
|
|
2362
|
+
!isRemoteAdmission &&
|
|
2363
|
+
actor === undefined &&
|
|
2364
|
+
transferRequest !== undefined &&
|
|
2365
|
+
this.options.actorTransferRuntime !== undefined
|
|
2331
2366
|
) {
|
|
2332
2367
|
if (!actorJoinIsCurrent()) return;
|
|
2333
2368
|
const transferState = preparedTransferState;
|
|
@@ -2371,10 +2406,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2371
2406
|
}
|
|
2372
2407
|
}
|
|
2373
2408
|
if (
|
|
2374
|
-
accepted
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2409
|
+
accepted &&
|
|
2410
|
+
transferRequest !== undefined &&
|
|
2411
|
+
this.options.actorTransferRuntime !== undefined &&
|
|
2412
|
+
!isRemoteAdmission
|
|
2378
2413
|
) {
|
|
2379
2414
|
// A lightweight Core actor-join notification can create the Actor
|
|
2380
2415
|
// before the formal transfer request reaches this branch. Preserve
|
|
@@ -2386,11 +2421,11 @@ export class DefaultZLinkSpotManager {
|
|
|
2386
2421
|
);
|
|
2387
2422
|
}
|
|
2388
2423
|
if (
|
|
2389
|
-
accepted
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2424
|
+
accepted &&
|
|
2425
|
+
actor !== undefined &&
|
|
2426
|
+
transferRequest !== undefined &&
|
|
2427
|
+
!isRemoteAdmission &&
|
|
2428
|
+
!committedAdmissionReplay
|
|
2394
2429
|
) {
|
|
2395
2430
|
this.formalRemoteTransfers.begin({
|
|
2396
2431
|
actor,
|
|
@@ -2400,10 +2435,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2400
2435
|
deferredJoinRoot
|
|
2401
2436
|
});
|
|
2402
2437
|
if (isRemoteCommit && admissionRecord !== undefined) {
|
|
2403
|
-
this.formalRemoteActorAdmissions.markCommitted(
|
|
2404
|
-
transferRequest.transferId,
|
|
2405
|
-
actor
|
|
2406
|
-
);
|
|
2438
|
+
this.formalRemoteActorAdmissions.markCommitted(transferRequest.transferId, actor);
|
|
2407
2439
|
}
|
|
2408
2440
|
}
|
|
2409
2441
|
const replyActorJoin = (): boolean => {
|
|
@@ -2431,9 +2463,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2431
2463
|
}
|
|
2432
2464
|
if (accepted && targetsEntrySpot && actor !== undefined) {
|
|
2433
2465
|
const entryActor = actor;
|
|
2434
|
-
const pendingTransfer =
|
|
2435
|
-
? undefined
|
|
2436
|
-
: this.formalRemoteTransfers.get(actorId);
|
|
2466
|
+
const pendingTransfer =
|
|
2467
|
+
transferRequest === undefined ? undefined : this.formalRemoteTransfers.get(actorId);
|
|
2437
2468
|
if (committedAdmissionReplay) {
|
|
2438
2469
|
if (!replyActorJoin()) return;
|
|
2439
2470
|
} else if (pendingTransfer === undefined) {
|
|
@@ -2446,11 +2477,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2446
2477
|
if (!replyActorJoin()) return;
|
|
2447
2478
|
const commitEntryTransfer = async (): Promise<void> => {
|
|
2448
2479
|
try {
|
|
2449
|
-
await this.options.dispatchEntryActorJoin?.(
|
|
2450
|
-
meshName,
|
|
2451
|
-
entryActor,
|
|
2452
|
-
[]
|
|
2453
|
-
);
|
|
2480
|
+
await this.options.dispatchEntryActorJoin?.(meshName, entryActor, []);
|
|
2454
2481
|
} finally {
|
|
2455
2482
|
this.formalRemoteTransfers.completeTargetLifecycle(
|
|
2456
2483
|
entryActor.context.actorId,
|
|
@@ -2467,7 +2494,9 @@ export class DefaultZLinkSpotManager {
|
|
|
2467
2494
|
pendingTransfer.handoffBacklog,
|
|
2468
2495
|
async (parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) => {
|
|
2469
2496
|
if (this.options.dispatchEntryActorPacket === undefined) {
|
|
2470
|
-
throw new Error(
|
|
2497
|
+
throw new Error(
|
|
2498
|
+
'Entry Spot saved handoff replay requires its Actor packet runtime.'
|
|
2499
|
+
);
|
|
2471
2500
|
}
|
|
2472
2501
|
return await this.options.dispatchEntryActorPacket(
|
|
2473
2502
|
entryActor.context.actorId,
|
|
@@ -2477,19 +2506,20 @@ export class DefaultZLinkSpotManager {
|
|
|
2477
2506
|
fallbackActorRef
|
|
2478
2507
|
);
|
|
2479
2508
|
},
|
|
2480
|
-
index =>
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2509
|
+
(index) =>
|
|
2510
|
+
this.options.runtimeEventPublisher?.publish({
|
|
2511
|
+
sourceName: 'zlink.framework.actor-handoff',
|
|
2512
|
+
timestamp: new Date(),
|
|
2513
|
+
marker: 'backlog_enqueued',
|
|
2514
|
+
actorId: entryActor.context.actorId,
|
|
2515
|
+
index
|
|
2516
|
+
})
|
|
2487
2517
|
);
|
|
2488
|
-
const failedHandoff = handoffResults.find(result => !result.ok);
|
|
2518
|
+
const failedHandoff = handoffResults.find((result) => !result.ok);
|
|
2489
2519
|
if (failedHandoff !== undefined) {
|
|
2490
2520
|
throw new Error(
|
|
2491
|
-
`Actor '${entryActor.context.actorId}' saved Entry handoff packet `
|
|
2492
|
-
|
|
2521
|
+
`Actor '${entryActor.context.actorId}' saved Entry handoff packet ` +
|
|
2522
|
+
`${failedHandoff.index} failed: ${failedHandoff.error ?? 'unknown error'}.`
|
|
2493
2523
|
);
|
|
2494
2524
|
}
|
|
2495
2525
|
this.formalRemoteTransfers.delete(entryActor.context.actorId);
|
|
@@ -2507,15 +2537,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2507
2537
|
}
|
|
2508
2538
|
} catch (error) {
|
|
2509
2539
|
if (control.canonicalActorJoin !== undefined) {
|
|
2510
|
-
this.formalRemoteActorAdmissions.fail(
|
|
2511
|
-
control.canonicalActorJoin.handoffId,
|
|
2512
|
-
error
|
|
2513
|
-
);
|
|
2540
|
+
this.formalRemoteActorAdmissions.fail(control.canonicalActorJoin.handoffId, error);
|
|
2514
2541
|
}
|
|
2515
2542
|
if (deferredJoinRoot !== undefined && targetCommitPublished !== true) {
|
|
2516
|
-
await this.options.actorTransferRuntime?.discardDeferredJoinAccepted(
|
|
2517
|
-
deferredJoinRoot
|
|
2518
|
-
);
|
|
2543
|
+
await this.options.actorTransferRuntime?.discardDeferredJoinAccepted(deferredJoinRoot);
|
|
2519
2544
|
}
|
|
2520
2545
|
if (targetCommitPublished !== true) {
|
|
2521
2546
|
this.formalRemoteTransfers.delete(actorId);
|
|
@@ -2532,37 +2557,46 @@ export class DefaultZLinkSpotManager {
|
|
|
2532
2557
|
}
|
|
2533
2558
|
}
|
|
2534
2559
|
|
|
2535
|
-
async dispatchMeshSpotControl(
|
|
2560
|
+
async dispatchMeshSpotControl(
|
|
2561
|
+
meshName: string,
|
|
2562
|
+
owner: ReadyRecord,
|
|
2563
|
+
record: ReceiveRecord
|
|
2564
|
+
): Promise<void> {
|
|
2536
2565
|
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
2537
2566
|
const control = record.kindData;
|
|
2538
2567
|
if (control?.kind !== 'actorControl') {
|
|
2539
|
-
throw new ZLinkConfigurationException(
|
|
2568
|
+
throw new ZLinkConfigurationException(
|
|
2569
|
+
'MeshNode Spot control record is missing actor lifecycle data.'
|
|
2570
|
+
);
|
|
2540
2571
|
}
|
|
2541
|
-
const actorRef =
|
|
2542
|
-
|
|
2543
|
-
|
|
2572
|
+
const actorRef =
|
|
2573
|
+
control.lifecycleKind === ActorLifecycleKind.Left
|
|
2574
|
+
? control.previousActor
|
|
2575
|
+
: control.currentActor;
|
|
2544
2576
|
const actorId = actorRef?.actorId;
|
|
2545
|
-
const pendingTransfer =
|
|
2546
|
-
? undefined
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
const sourceJoinedActor =
|
|
2552
|
-
? undefined
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2577
|
+
const pendingTransfer =
|
|
2578
|
+
actorId === undefined ? undefined : this.formalRemoteTransfers.get(actorId);
|
|
2579
|
+
const sourceActivation =
|
|
2580
|
+
actorId === undefined || spotId === null
|
|
2581
|
+
? undefined
|
|
2582
|
+
: this.activations.resolve(meshName, spotId);
|
|
2583
|
+
const sourceJoinedActor =
|
|
2584
|
+
actorId === undefined ? undefined : sourceActivation?.resolveJoinedActor(actorId);
|
|
2585
|
+
const actor =
|
|
2586
|
+
actorId === undefined
|
|
2587
|
+
? undefined
|
|
2588
|
+
: (pendingTransfer?.actor ??
|
|
2589
|
+
sourceJoinedActor ??
|
|
2590
|
+
this.options.actorLifecycleResolver?.(actorId) ??
|
|
2591
|
+
this.options.actorResolver?.(actorId));
|
|
2560
2592
|
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
2561
2593
|
if (actor === undefined) {
|
|
2562
2594
|
return;
|
|
2563
2595
|
}
|
|
2564
|
-
if (
|
|
2565
|
-
|
|
2596
|
+
if (
|
|
2597
|
+
control.lifecycleKind === ActorLifecycleKind.Left &&
|
|
2598
|
+
(spotId === null || (entrySpotId !== undefined && String(spotId) === String(entrySpotId)))
|
|
2599
|
+
) {
|
|
2566
2600
|
const callback = async () => {
|
|
2567
2601
|
await this.options.entrySpotCallbacks?.onLeaveActor(
|
|
2568
2602
|
actor,
|
|
@@ -2613,20 +2647,21 @@ export class DefaultZLinkSpotManager {
|
|
|
2613
2647
|
const completePublicJoin = async (): Promise<void> => {
|
|
2614
2648
|
const deferredJoinRoot = pendingTransfer?.deferredJoinRoot;
|
|
2615
2649
|
if (deferredJoinRoot !== undefined) {
|
|
2616
|
-
const currentRef =
|
|
2617
|
-
|
|
2618
|
-
|
|
2650
|
+
const currentRef =
|
|
2651
|
+
this.options.actorTransferRuntime === undefined
|
|
2652
|
+
? null
|
|
2653
|
+
: (control.currentActor as unknown as ActorRef | null);
|
|
2619
2654
|
if (currentRef === null) {
|
|
2620
|
-
throw new Error(
|
|
2655
|
+
throw new Error(
|
|
2656
|
+
`Actor '${actor.context.actorId}' has no target ref for deferred Join completion.`
|
|
2657
|
+
);
|
|
2621
2658
|
}
|
|
2622
2659
|
await this.options.actorTransferRuntime?.commitAndDeliverDeferredJoinAccepted(
|
|
2623
2660
|
deferredJoinRoot,
|
|
2624
2661
|
actor,
|
|
2625
2662
|
currentRef,
|
|
2626
|
-
operation =>
|
|
2627
|
-
actor.context.actorId,
|
|
2628
|
-
async () => await operation()
|
|
2629
|
-
)
|
|
2663
|
+
(operation) =>
|
|
2664
|
+
activation.executeActor(actor.context.actorId, async () => await operation())
|
|
2630
2665
|
);
|
|
2631
2666
|
}
|
|
2632
2667
|
};
|
|
@@ -2643,19 +2678,20 @@ export class DefaultZLinkSpotManager {
|
|
|
2643
2678
|
remoteBoundSessionTarget,
|
|
2644
2679
|
undefined
|
|
2645
2680
|
),
|
|
2646
|
-
(index) =>
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2681
|
+
(index) =>
|
|
2682
|
+
this.options.runtimeEventPublisher?.publish({
|
|
2683
|
+
sourceName: 'zlink.framework.actor-handoff',
|
|
2684
|
+
timestamp: new Date(),
|
|
2685
|
+
marker: 'backlog_enqueued',
|
|
2686
|
+
actorId: actor.context.actorId,
|
|
2687
|
+
index
|
|
2688
|
+
})
|
|
2653
2689
|
);
|
|
2654
|
-
const failedHandoff = handoffResults.find(result => !result.ok);
|
|
2690
|
+
const failedHandoff = handoffResults.find((result) => !result.ok);
|
|
2655
2691
|
if (failedHandoff !== undefined) {
|
|
2656
2692
|
throw new Error(
|
|
2657
|
-
`Actor '${actor.context.actorId}' saved handoff packet `
|
|
2658
|
-
|
|
2693
|
+
`Actor '${actor.context.actorId}' saved handoff packet ` +
|
|
2694
|
+
`${failedHandoff.index} failed: ${failedHandoff.error ?? 'unknown error'}.`
|
|
2659
2695
|
);
|
|
2660
2696
|
}
|
|
2661
2697
|
// Spec 15 §4.2 relocation temporary queue: arrivals parked at
|
|
@@ -2730,9 +2766,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2730
2766
|
if (sourceJoinedActor === undefined && pendingTransfer === undefined) {
|
|
2731
2767
|
return;
|
|
2732
2768
|
}
|
|
2733
|
-
await this.options.actorTransferRuntime.notifyCoreSourceLeave(
|
|
2734
|
-
actor
|
|
2735
|
-
() => activation.spot.onLeaveActor(actor)
|
|
2769
|
+
await this.options.actorTransferRuntime.notifyCoreSourceLeave(actor, () =>
|
|
2770
|
+
activation.spot.onLeaveActor(actor)
|
|
2736
2771
|
);
|
|
2737
2772
|
}
|
|
2738
2773
|
activation.commitActorDeparture(actor.context.actorId);
|
|
@@ -2770,14 +2805,14 @@ export class DefaultZLinkSpotManager {
|
|
|
2770
2805
|
if (admission.admission.actorId !== actor.context.actorId) {
|
|
2771
2806
|
throw new Error(`Actor Join relocation '${relocationId}' changed its admitted Actor.`);
|
|
2772
2807
|
}
|
|
2773
|
-
const outcome = admission.result ?? await admission.resultTask;
|
|
2808
|
+
const outcome = admission.result ?? (await admission.resultTask);
|
|
2774
2809
|
if ('error' in outcome) throw outcome.error;
|
|
2775
2810
|
if (!outcome.accepted || admission.state !== 'admitted') {
|
|
2776
2811
|
throw new Error(`Actor Join relocation '${relocationId}' has no accepted admission.`);
|
|
2777
2812
|
}
|
|
2778
2813
|
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
2779
|
-
const targetsEntry =
|
|
2780
|
-
&& String(admission.admission.spotId) === String(entrySpotId);
|
|
2814
|
+
const targetsEntry =
|
|
2815
|
+
entrySpotId !== undefined && String(admission.admission.spotId) === String(entrySpotId);
|
|
2781
2816
|
if (targetsEntry) {
|
|
2782
2817
|
await this.options.dispatchEntryActorJoin?.(meshName, actor, []);
|
|
2783
2818
|
} else {
|
|
@@ -2822,7 +2857,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2822
2857
|
`Actor Join recovery '${recovery.request.handoffId}' has no canonical command-28 admission.`
|
|
2823
2858
|
);
|
|
2824
2859
|
}
|
|
2825
|
-
const outcome = admission.result ?? await admission.resultTask;
|
|
2860
|
+
const outcome = admission.result ?? (await admission.resultTask);
|
|
2826
2861
|
if ('error' in outcome || !outcome.accepted || admission.state !== 'admitted') {
|
|
2827
2862
|
throw new Error(
|
|
2828
2863
|
`Actor Join recovery '${recovery.request.handoffId}' has no accepted admission.`
|
|
@@ -2839,13 +2874,13 @@ export class DefaultZLinkSpotManager {
|
|
|
2839
2874
|
'hex'
|
|
2840
2875
|
);
|
|
2841
2876
|
if (
|
|
2842
|
-
admitted.actorId !== recovery.request.actorId
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2877
|
+
admitted.actorId !== recovery.request.actorId ||
|
|
2878
|
+
admitted.actorType !== recovery.request.actorType ||
|
|
2879
|
+
admitted.requestFingerprint !== recovery.request.request.toString('base64') ||
|
|
2880
|
+
String(admitted.spotId) !== recovery.targetSpotId ||
|
|
2881
|
+
admitted.targetSpotGeneration !== recovery.targetSpotGeneration ||
|
|
2882
|
+
admitted.actorRef.objectGeneration !== recovery.request.actorGeneration ||
|
|
2883
|
+
!admittedNodeBytes.equals(recovery.request.sourceNodeRid)
|
|
2849
2884
|
) {
|
|
2850
2885
|
throw new Error(
|
|
2851
2886
|
`Actor Join recovery '${recovery.request.handoffId}' changed its command-28 identity.`
|
|
@@ -2865,9 +2900,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2865
2900
|
}
|
|
2866
2901
|
return;
|
|
2867
2902
|
}
|
|
2868
|
-
const outerReplyContentType =
|
|
2869
|
-
|
|
2870
|
-
|
|
2903
|
+
const outerReplyContentType =
|
|
2904
|
+
admittedReply.byteLength === 0
|
|
2905
|
+
? recovery.replyContentType
|
|
2906
|
+
: SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE;
|
|
2871
2907
|
if (recovery.replyContentType !== outerReplyContentType) {
|
|
2872
2908
|
throw new Error(
|
|
2873
2909
|
`Actor Join recovery '${recovery.request.handoffId}' changed its reply content type.`
|
|
@@ -2876,9 +2912,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2876
2912
|
// Command 28 carries a present reply in one outer framework-multipart
|
|
2877
2913
|
// part. The accepted target admission still owns the inner typed content
|
|
2878
2914
|
// type, which the durable completion must retain for application decode.
|
|
2879
|
-
const admittedContentType =
|
|
2880
|
-
? recovery.replyContentType
|
|
2881
|
-
: outcome.replyContentType;
|
|
2915
|
+
const admittedContentType =
|
|
2916
|
+
admittedReply.byteLength === 0 ? recovery.replyContentType : outcome.replyContentType;
|
|
2882
2917
|
const transfer = this.options.actorTransferRuntime;
|
|
2883
2918
|
if (transfer === undefined) {
|
|
2884
2919
|
throw new Error('Canonical Actor Join recovery requires the Actor transfer runtime.');
|
|
@@ -2892,10 +2927,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2892
2927
|
signal,
|
|
2893
2928
|
canonicalInventoryDigest
|
|
2894
2929
|
);
|
|
2895
|
-
this.formalRemoteActorAdmissions.attachDeferredJoinRoot(
|
|
2896
|
-
recovery.request.handoffId,
|
|
2897
|
-
deferred
|
|
2898
|
-
);
|
|
2930
|
+
this.formalRemoteActorAdmissions.attachDeferredJoinRoot(recovery.request.handoffId, deferred);
|
|
2899
2931
|
return deferred;
|
|
2900
2932
|
}
|
|
2901
2933
|
|
|
@@ -3003,10 +3035,7 @@ export class DefaultZLinkSpotManager {
|
|
|
3003
3035
|
const response = await this.dispatchActorPacket(
|
|
3004
3036
|
activation,
|
|
3005
3037
|
actor.context.actorId,
|
|
3006
|
-
[
|
|
3007
|
-
RuntimeMessage.from(arrival.header),
|
|
3008
|
-
RuntimeMessage.from(arrival.payload)
|
|
3009
|
-
],
|
|
3038
|
+
[RuntimeMessage.from(arrival.header), RuntimeMessage.from(arrival.payload)],
|
|
3010
3039
|
arrival.returnResponse,
|
|
3011
3040
|
arrival.remoteBoundSessionTarget,
|
|
3012
3041
|
arrival.fallbackActorRef,
|
|
@@ -3046,17 +3075,16 @@ export class DefaultZLinkSpotManager {
|
|
|
3046
3075
|
messageFollowOrigin
|
|
3047
3076
|
);
|
|
3048
3077
|
}
|
|
3049
|
-
|
|
3050
3078
|
}
|
|
3051
3079
|
|
|
3052
3080
|
function instanceDispatchErrorReason(error: unknown): ZLinkDispatchErrorReason {
|
|
3053
3081
|
if (error instanceof ZLinkFrameworkException) {
|
|
3054
3082
|
const kind = internalFrameworkErrorKind(error);
|
|
3055
3083
|
if (
|
|
3056
|
-
kind === ZLinkFrameworkInternalErrorKind.SpotGenerationStale
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3084
|
+
kind === ZLinkFrameworkInternalErrorKind.SpotGenerationStale ||
|
|
3085
|
+
kind === ZLinkFrameworkInternalErrorKind.SpotMoving ||
|
|
3086
|
+
kind === ZLinkFrameworkInternalErrorKind.SpotRouteNotFound ||
|
|
3087
|
+
kind === ZLinkFrameworkInternalErrorKind.RequestTargetNotFound
|
|
3060
3088
|
) {
|
|
3061
3089
|
return ZLinkDispatchErrorReason.StaleTarget;
|
|
3062
3090
|
}
|
|
@@ -3101,51 +3129,48 @@ function decodeFormalRemoteTransferRequestBytes(
|
|
|
3101
3129
|
return undefined;
|
|
3102
3130
|
}
|
|
3103
3131
|
if (
|
|
3104
|
-
payload.packetName !== REMOTE_ACTOR_JOIN_PACKET
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
payload.phase === REMOTE_ACTOR_JOIN_ADMISSION
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
)
|
|
3113
|
-
|
|
3114
|
-
payload.phase === REMOTE_ACTOR_JOIN_ADMISSION
|
|
3115
|
-
|
|
3116
|
-
|| (
|
|
3132
|
+
payload.packetName !== REMOTE_ACTOR_JOIN_PACKET ||
|
|
3133
|
+
typeof payload.actorType !== 'string' ||
|
|
3134
|
+
typeof payload.transferId !== 'string' ||
|
|
3135
|
+
!(
|
|
3136
|
+
payload.phase === REMOTE_ACTOR_JOIN_ADMISSION ||
|
|
3137
|
+
payload.phase === REMOTE_ACTOR_JOIN_ABORT ||
|
|
3138
|
+
payload.phase === REMOTE_ACTOR_JOIN_COMMIT ||
|
|
3139
|
+
payload.phase === undefined
|
|
3140
|
+
) ||
|
|
3141
|
+
!(
|
|
3142
|
+
payload.phase === REMOTE_ACTOR_JOIN_ADMISSION ||
|
|
3143
|
+
payload.phase === REMOTE_ACTOR_JOIN_ABORT ||
|
|
3117
3144
|
typeof payload.transferState === 'string'
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|| typeof payload.request !== 'string'
|
|
3145
|
+
) ||
|
|
3146
|
+
typeof payload.request !== 'string'
|
|
3121
3147
|
) {
|
|
3122
3148
|
return undefined;
|
|
3123
3149
|
}
|
|
3124
3150
|
return {
|
|
3125
3151
|
actorType: payload.actorType,
|
|
3126
3152
|
actorId: typeof payload.actorId === 'string' ? payload.actorId : undefined,
|
|
3127
|
-
phase:
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3153
|
+
phase:
|
|
3154
|
+
payload.phase === REMOTE_ACTOR_JOIN_ADMISSION ||
|
|
3155
|
+
payload.phase === REMOTE_ACTOR_JOIN_COMMIT ||
|
|
3156
|
+
payload.phase === REMOTE_ACTOR_JOIN_ABORT
|
|
3157
|
+
? payload.phase
|
|
3158
|
+
: undefined,
|
|
3132
3159
|
transferId: payload.transferId,
|
|
3133
|
-
transferAdapterKey:
|
|
3134
|
-
? payload.transferAdapterKey
|
|
3135
|
-
|
|
3136
|
-
transferState: typeof payload.transferState === 'string'
|
|
3137
|
-
? payload.transferState
|
|
3138
|
-
: undefined,
|
|
3160
|
+
transferAdapterKey:
|
|
3161
|
+
typeof payload.transferAdapterKey === 'string' ? payload.transferAdapterKey : undefined,
|
|
3162
|
+
transferState: typeof payload.transferState === 'string' ? payload.transferState : undefined,
|
|
3139
3163
|
request: payload.request,
|
|
3140
|
-
requestContentType:
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3164
|
+
requestContentType:
|
|
3165
|
+
typeof payload.requestContentType === 'string'
|
|
3166
|
+
? payload.requestContentType
|
|
3167
|
+
: 'application/json',
|
|
3168
|
+
actorEntryNodeRid:
|
|
3169
|
+
typeof payload.actorEntryNodeRid === 'string'
|
|
3170
|
+
? decodeRoutingId(payload.actorEntryNodeRid, payload.actorEntryNodeRidHex)
|
|
3171
|
+
: undefined,
|
|
3172
|
+
sourceSpotId:
|
|
3173
|
+
typeof payload.sourceSpotId === 'string' ? (payload.sourceSpotId as RoutingId) : undefined,
|
|
3149
3174
|
actorRef: decodeFormalRemoteActorRef(payload),
|
|
3150
3175
|
remoteBoundSessionTarget: decodeRemoteBoundSessionTarget(
|
|
3151
3176
|
payload.boundSessionRouterChannelId,
|
|
@@ -3162,13 +3187,14 @@ function decodeFormalRemoteTransferRequestBytes(
|
|
|
3162
3187
|
payload.boundSessionRelocationSealId,
|
|
3163
3188
|
payload.boundSessionServiceWireRelocation
|
|
3164
3189
|
),
|
|
3165
|
-
expectedMembershipEpoch:
|
|
3166
|
-
|
|
3167
|
-
|
|
3190
|
+
expectedMembershipEpoch:
|
|
3191
|
+
typeof payload.expectedMembershipEpoch === 'string'
|
|
3192
|
+
? BigInt(payload.expectedMembershipEpoch)
|
|
3193
|
+
: 0n,
|
|
3168
3194
|
handoffBacklog: decodeHandoffBacklog(payload.handoffBacklog),
|
|
3169
3195
|
completionOperationId:
|
|
3170
|
-
typeof payload.completionOperationHigh === 'string'
|
|
3171
|
-
|
|
3196
|
+
typeof payload.completionOperationHigh === 'string' &&
|
|
3197
|
+
typeof payload.completionOperationLow === 'string'
|
|
3172
3198
|
? {
|
|
3173
3199
|
high: BigInt(payload.completionOperationHigh),
|
|
3174
3200
|
low: BigInt(payload.completionOperationLow)
|
|
@@ -3197,7 +3223,6 @@ function decodeFormalRemoteActorRef(
|
|
|
3197
3223
|
};
|
|
3198
3224
|
}
|
|
3199
3225
|
|
|
3200
|
-
|
|
3201
3226
|
function requireMeshSpotReply(result: number): void {
|
|
3202
3227
|
if (result !== SubmitResult.Ok) {
|
|
3203
3228
|
throw new ZLinkConfigurationException(
|
|
@@ -3238,15 +3263,15 @@ function validateRemoteAdmissionCommit(
|
|
|
3238
3263
|
const expected = admission.admission;
|
|
3239
3264
|
const actorRef = request.actorRef;
|
|
3240
3265
|
if (
|
|
3241
|
-
expected.actorId !== actorId
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3266
|
+
expected.actorId !== actorId ||
|
|
3267
|
+
expected.actorType !== request.actorType ||
|
|
3268
|
+
expected.expectedMembershipEpoch !== request.expectedMembershipEpoch ||
|
|
3269
|
+
expected.requestFingerprint !== request.request ||
|
|
3270
|
+
expected.targetSpotGeneration !== (control.currentSpotGeneration ?? 0n) ||
|
|
3271
|
+
actorRef === undefined ||
|
|
3272
|
+
actorRef.actorId !== expected.actorRef.actorId ||
|
|
3273
|
+
String(actorRef.nodeRid) !== String(expected.actorRef.nodeRid) ||
|
|
3274
|
+
actorRef.objectGeneration !== expected.actorRef.objectGeneration
|
|
3250
3275
|
) {
|
|
3251
3276
|
throw new ZLinkConfigurationException(
|
|
3252
3277
|
`Remote Actor '${actorId}' commit does not match its target admission.`
|
|
@@ -3257,7 +3282,10 @@ function validateRemoteAdmissionCommit(
|
|
|
3257
3282
|
function normalizeSpotCreateArgs<TRequest>(
|
|
3258
3283
|
requestOrSignal: ZLinkMessage | TRequest | AbortSignal | undefined,
|
|
3259
3284
|
signal: AbortSignal | undefined
|
|
3260
|
-
): {
|
|
3285
|
+
): {
|
|
3286
|
+
readonly request: ZLinkMessage | TRequest | undefined;
|
|
3287
|
+
readonly signal: AbortSignal | undefined;
|
|
3288
|
+
} {
|
|
3261
3289
|
if (isAbortSignal(requestOrSignal)) {
|
|
3262
3290
|
return { request: undefined, signal: requestOrSignal };
|
|
3263
3291
|
}
|
|
@@ -3283,10 +3311,12 @@ function instanceMaterializationKey(
|
|
|
3283
3311
|
}
|
|
3284
3312
|
|
|
3285
3313
|
function isAbortSignal(value: unknown): value is AbortSignal {
|
|
3286
|
-
return
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3314
|
+
return (
|
|
3315
|
+
typeof value === 'object' &&
|
|
3316
|
+
value !== null &&
|
|
3317
|
+
typeof (value as { aborted?: unknown }).aborted === 'boolean' &&
|
|
3318
|
+
typeof (value as { addEventListener?: unknown }).addEventListener === 'function'
|
|
3319
|
+
);
|
|
3290
3320
|
}
|
|
3291
3321
|
|
|
3292
3322
|
function instanceActivationOutcome(error: unknown): string {
|
|
@@ -3295,9 +3325,10 @@ function instanceActivationOutcome(error: unknown): string {
|
|
|
3295
3325
|
if (error.kind === ZLinkFrameworkErrorKind.DeadlineExceeded) return 'timed_out';
|
|
3296
3326
|
if (error.kind === ZLinkFrameworkErrorKind.AlreadyExists) return 'conflict';
|
|
3297
3327
|
if (
|
|
3298
|
-
error.kind === ZLinkFrameworkErrorKind.InvalidOperation
|
|
3299
|
-
|
|
3300
|
-
)
|
|
3328
|
+
error.kind === ZLinkFrameworkErrorKind.InvalidOperation ||
|
|
3329
|
+
error.kind === ZLinkFrameworkErrorKind.Unavailable
|
|
3330
|
+
)
|
|
3331
|
+
return 'fenced';
|
|
3301
3332
|
}
|
|
3302
3333
|
return 'failed';
|
|
3303
3334
|
}
|