@zlink-systems/framework 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Channels/IZLinkFanoutClient.d.ts +0 -6
- package/dist/contracts/Common/CoreTypes.d.ts +6 -0
- package/dist/contracts/Common/CoreTypes.js +7 -0
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/index.js +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
- package/dist/contracts/Configuration/InternalDefaults.js +9 -1
- package/dist/contracts/Configuration/Registration.d.ts +13 -2
- package/dist/contracts/Configuration/Registration.js +58 -36
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
- package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
- package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
- package/dist/contracts/Handlers/JsonContract.js +10 -4
- package/dist/contracts/Locations/Authority.d.ts +1 -1
- package/dist/contracts/Locations/Authority.js +3 -2
- package/dist/contracts/Locations/Options.js +1 -1
- package/dist/contracts/Locations/Stores.d.ts +12 -0
- package/dist/contracts/Locations/Stores.js +9 -0
- package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
- package/dist/contracts/Spots/Contracts.d.ts +1 -1
- package/dist/internal.d.ts +5 -0
- package/dist/internal.js +16 -1
- package/dist/nest-integration.d.ts +4 -2
- package/dist/nest-integration.js +14 -4
- package/dist/runtime/abort.d.ts +1 -0
- package/dist/runtime/abort.js +8 -5
- package/dist/runtime/activation-admission.d.ts +28 -0
- package/dist/runtime/activation-admission.js +57 -0
- package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
- package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
- package/dist/runtime/actors/actor-client.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +42 -143
- package/dist/runtime/actors/actor-context.d.ts +3 -5
- package/dist/runtime/actors/actor-context.js +19 -17
- package/dist/runtime/actors/actor-handoff.d.ts +13 -7
- package/dist/runtime/actors/actor-handoff.js +36 -25
- package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
- package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
- package/dist/runtime/actors/actor-local-native-join.js +85 -123
- package/dist/runtime/actors/actor-native-lookup.js +2 -8
- package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
- package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
- package/dist/runtime/actors/actor-remote-joiner.d.ts +3 -3
- package/dist/runtime/actors/actor-remote-joiner.js +11 -17
- package/dist/runtime/actors/actor-remote-wire.js +5 -3
- package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
- package/dist/runtime/actors/actor-request-deadline.js +31 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
- package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +19 -0
- package/dist/runtime/actors/deferred-join-completion.js +21 -0
- package/dist/runtime/actors/index.d.ts +10 -8
- package/dist/runtime/actors/index.js +101 -73
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
- package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
- package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
- package/dist/runtime/admission.d.ts +7 -1
- package/dist/runtime/admission.js +11 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
- package/dist/runtime/backend/contracts/index.d.ts +8 -33
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +3 -26
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
- package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +7 -4
- package/dist/runtime/backend/node/node-backend-adapter-support.js +28 -34
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +11 -6
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +51 -19
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +21 -19
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +171 -111
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
- package/dist/runtime/backend/raw-binding-port.d.ts +13 -1
- package/dist/runtime/backend/runtime-values.d.ts +4 -1
- package/dist/runtime/backend/runtime-values.js +2 -0
- package/dist/runtime/channels/channel-clients.d.ts +20 -9
- package/dist/runtime/channels/channel-clients.js +68 -60
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.js +47 -29
- package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
- package/dist/runtime/channels/channel-outbound-operations.js +9 -18
- package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
- package/dist/runtime/channels/channel-receive-loops.js +27 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
- package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
- package/dist/runtime/channels/channel-runtime-manager.js +4 -12
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +30 -32
- package/dist/runtime/channels/channel-socket-registry.js +296 -235
- package/dist/runtime/channels/channel-transports.d.ts +11 -20
- package/dist/runtime/channels/channel-transports.js +68 -47
- package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/client-server-location-runtime.js +10 -11
- package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
- package/dist/runtime/channels/client-server-service-wire.js +32 -11
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
- package/dist/runtime/channels/fanout-location-runtime.js +133 -81
- package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
- package/dist/runtime/channels/spot-direct-envelope.js +4 -3
- package/dist/runtime/channels/spot-node-route-transport.js +3 -2
- package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
- package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
- package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
- package/dist/runtime/diagnostics/flow-context.js +16 -2
- package/dist/runtime/diagnostics/index.d.ts +4 -2
- package/dist/runtime/diagnostics/index.js +14 -4
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
- package/dist/runtime/diagnostics/message-flow.js +10 -19
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
- package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
- package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
- package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
- package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
- package/dist/runtime/disposal.d.ts +5 -0
- package/dist/runtime/disposal.js +22 -0
- package/dist/runtime/execution/index.d.ts +22 -9
- package/dist/runtime/execution/index.js +107 -37
- package/dist/runtime/execution/serial-execution-queue.d.ts +12 -7
- package/dist/runtime/execution/serial-execution-queue.js +99 -26
- package/dist/runtime/execution/state-lane.d.ts +8 -1
- package/dist/runtime/execution/state-lane.js +118 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
- package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
- package/dist/runtime/foundation/event-loop-resources.js +6 -119
- package/dist/runtime/foundation/listener-records.d.ts +11 -0
- package/dist/runtime/foundation/listener-records.js +20 -0
- package/dist/runtime/foundation/operation-identity.d.ts +2 -0
- package/dist/runtime/foundation/operation-identity.js +9 -5
- package/dist/runtime/foundation/operation-registry.d.ts +5 -7
- package/dist/runtime/foundation/operation-registry.js +34 -44
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +18 -26
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +122 -469
- package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
- package/dist/runtime/foundation/runtime-state-projections.js +8 -0
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +30 -12
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +22 -3
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
- package/dist/runtime/foundation/service-liveness-registry.js +2 -1
- package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
- package/dist/runtime/foundation/service-maintenance-runtime.js +23 -8
- package/dist/runtime/foundation/service-metadata-codec.js +3 -3
- package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
- package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
- package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +19 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
- package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -19
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +10 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +28 -24
- package/dist/runtime/foundation/service-stateful-runtime.js +297 -244
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +12 -7
- package/dist/runtime/foundation/service-stateful-wire-codec.js +240 -143
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -3
- package/dist/runtime/foundation/service-topology-registry.js +22 -61
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
- package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
- package/dist/runtime/foundation/service-wire-codec.js +10 -8
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
- package/dist/runtime/framework-errors-internal.d.ts +2 -1
- package/dist/runtime/framework-errors-internal.js +343 -122
- package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
- package/dist/runtime/handlers/handler-instance-scope.js +61 -74
- package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
- package/dist/runtime/host/actor-packet-relay.js +48 -91
- package/dist/runtime/host/actor-placement-coordinator.js +7 -5
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
- package/dist/runtime/host/actor-transfer-runtime.d.ts +28 -28
- package/dist/runtime/host/actor-transfer-runtime.js +210 -256
- package/dist/runtime/host/application-job-queue.js +16 -33
- package/dist/runtime/host/bound-session-relay.js +1 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
- package/dist/runtime/host/index.d.ts +19 -14
- package/dist/runtime/host/index.js +234 -175
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
- package/dist/runtime/host/instance-activation-authority.js +17 -45
- package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
- package/dist/runtime/host/location-runtime-owner.js +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
- package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
- package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
- package/dist/runtime/host/remote-bound-session-relay.js +11 -23
- package/dist/runtime/host/route-mesh-runtime.d.ts +14 -10
- package/dist/runtime/host/route-mesh-runtime.js +178 -257
- package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
- package/dist/runtime/host/runtime-shutdown.js +18 -21
- package/dist/runtime/host/service-relocation-control.js +6 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +71 -38
- package/dist/runtime/host/service-relocation-host-runtime.js +816 -651
- package/dist/runtime/host/spot-address-transport.d.ts +2 -3
- package/dist/runtime/host/spot-address-transport.js +34 -136
- package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
- package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -7
- package/dist/runtime/host/spot-runtime-options-factory.js +53 -21
- package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +14 -6
- package/dist/runtime/host/user-spot-creation-coordinator.js +96 -95
- package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
- package/dist/runtime/locations/authority-key-codec.js +4 -3
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
- package/dist/runtime/locations/creation-operation-id.js +6 -4
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
- package/dist/runtime/locations/in-memory-authority-store.js +31 -15
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +17 -14
- package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-provider-location-store.js +79 -27
- package/dist/runtime/locations/key-codec.js +3 -2
- package/dist/runtime/locations/lease-tracker.d.ts +3 -5
- package/dist/runtime/locations/lease-tracker.js +7 -11
- package/dist/runtime/locations/lifecycle.d.ts +5 -10
- package/dist/runtime/locations/lifecycle.js +4 -33
- package/dist/runtime/locations/location-store-failure.d.ts +2 -0
- package/dist/runtime/locations/location-store-failure.js +7 -0
- package/dist/runtime/locations/location-store-pages.d.ts +3 -0
- package/dist/runtime/locations/location-store-pages.js +13 -0
- package/dist/runtime/locations/location-store-repository.d.ts +5 -7
- package/dist/runtime/locations/location-store-repository.js +303 -332
- package/dist/runtime/locations/relocation-blob.js +18 -5
- package/dist/runtime/locations/resolvers.d.ts +5 -5
- package/dist/runtime/locations/resolvers.js +44 -30
- package/dist/runtime/locations/runtime.d.ts +5 -4
- package/dist/runtime/locations/runtime.js +123 -92
- package/dist/runtime/locations/spot-location-claims.d.ts +8 -2
- package/dist/runtime/locations/spot-location-claims.js +40 -23
- package/dist/runtime/messaging/payload-codec.js +26 -20
- package/dist/runtime/messaging/submission-result.d.ts +3 -0
- package/dist/runtime/messaging/submission-result.js +48 -0
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +2 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +17 -8
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +6 -3
- package/dist/runtime/spots/index.d.ts +29 -29
- package/dist/runtime/spots/index.js +441 -313
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -4
- package/dist/runtime/spots/spot-activation-registry.js +27 -60
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
- package/dist/runtime/spots/spot-activation-state.js +4 -17
- package/dist/runtime/spots/spot-activation.d.ts +10 -9
- package/dist/runtime/spots/spot-activation.js +103 -81
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
- package/dist/runtime/spots/spot-actor-join-dispatch.js +5 -55
- package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
- package/dist/runtime/spots/spot-actor-membership.d.ts +7 -5
- package/dist/runtime/spots/spot-actor-membership.js +44 -53
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
- package/dist/runtime/spots/spot-context.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-entry-activation.js +9 -21
- package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
- package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
- package/dist/runtime/spots/spot-manager-public.js +6 -5
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +22 -21
- package/dist/runtime/spots/spot-node-runtime-manager.js +73 -82
- package/dist/runtime/spots/spot-outbound.d.ts +4 -3
- package/dist/runtime/spots/spot-outbound.js +10 -37
- package/dist/runtime/spots/spot-remote-codec.js +5 -3
- package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
- package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
- package/dist/runtime/spots/spot-route-replies.js +3 -1
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -2
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -7
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +1 -70
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
- package/dist/runtime/spots/spot-runtime-ports.d.ts +4 -20
- package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
- package/dist/runtime/spots/spot-serial-executor.js +9 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +29 -6
- package/dist/runtime/spots/spot-serial-turn-executor.js +89 -13
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +17 -32
- package/dist/runtime/streams/actor-session-binding-registry.js +145 -367
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +2 -6
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +12 -19
- package/dist/runtime/streams/index.d.ts +15 -14
- package/dist/runtime/streams/index.js +38 -39
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +17 -8
- package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
- package/dist/runtime/streams/protocol.d.ts +6 -33
- package/dist/runtime/streams/protocol.js +38 -110
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
- package/dist/runtime/streams/session-actor-coordinator.js +12 -4
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +5 -4
- package/dist/runtime/streams/session-context.d.ts +6 -6
- package/dist/runtime/streams/session-context.js +22 -4
- package/dist/runtime/streams/session-requests.js +2 -1
- package/dist/runtime/streams/session-serial-executor.js +2 -2
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
- package/dist/runtime/streams/stream-frame-factory.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
- package/dist/runtime/streams/stream-session-runtime.js +25 -33
- package/dist/runtime/workers/index.d.ts +2 -2
- package/dist/runtime/workers/index.js +5 -4
- package/package.json +3 -3
- package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
- package/src/contracts/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Configuration/InternalDefaults.ts +12 -0
- package/src/contracts/Configuration/Registration.ts +92 -48
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Handlers/JsonContract.ts +14 -4
- package/src/contracts/Locations/Authority.ts +7 -3
- package/src/contracts/Locations/Options.ts +1 -1
- package/src/contracts/Locations/Stores.ts +14 -0
- package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
- package/src/contracts/Spots/Contracts.ts +1 -1
- package/src/internal.ts +15 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +72 -0
- package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
- package/src/runtime/actors/actor-client.ts +77 -204
- package/src/runtime/actors/actor-context.ts +45 -39
- package/src/runtime/actors/actor-handoff.ts +55 -45
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +174 -215
- package/src/runtime/actors/actor-native-lookup.ts +2 -9
- package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
- package/src/runtime/actors/actor-remote-joiner.ts +15 -36
- package/src/runtime/actors/actor-remote-wire.ts +5 -3
- package/src/runtime/actors/actor-request-deadline.ts +49 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
- package/src/runtime/actors/actor-runtime-state.ts +85 -247
- package/src/runtime/actors/actor-source-transfer.ts +5 -18
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +44 -0
- package/src/runtime/actors/index.ts +122 -88
- package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
- package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
- package/src/runtime/admission.ts +13 -2
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +15 -42
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -28
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
- package/src/runtime/backend/node/node-backend-adapter-support.ts +32 -35
- package/src/runtime/backend/node/node-event-loop-poller.ts +16 -8
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +58 -23
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +252 -162
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -4
- package/src/runtime/backend/raw-binding-port.ts +14 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +132 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +58 -29
- package/src/runtime/channels/channel-outbound-operations.ts +10 -31
- package/src/runtime/channels/channel-receive-loops.ts +39 -7
- package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
- package/src/runtime/channels/channel-runtime-manager.ts +8 -15
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +369 -262
- package/src/runtime/channels/channel-transports.ts +161 -115
- package/src/runtime/channels/client-server-location-runtime.ts +17 -17
- package/src/runtime/channels/client-server-service-wire.ts +40 -12
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
- package/src/runtime/channels/fanout-location-runtime.ts +175 -106
- package/src/runtime/channels/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +5 -2
- package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
- package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
- package/src/runtime/diagnostics/flow-context.ts +16 -2
- package/src/runtime/diagnostics/index.ts +27 -17
- package/src/runtime/diagnostics/message-flow.ts +15 -25
- package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
- package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
- package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
- package/src/runtime/disposal.ts +19 -0
- package/src/runtime/execution/index.ts +116 -38
- package/src/runtime/execution/serial-execution-queue.ts +179 -34
- package/src/runtime/execution/state-lane.ts +142 -4
- package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
- package/src/runtime/foundation/event-loop-resources.ts +5 -122
- package/src/runtime/foundation/listener-records.ts +21 -0
- package/src/runtime/foundation/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +170 -571
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +41 -13
- package/src/runtime/foundation/service-discovery-registry.ts +32 -3
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
- package/src/runtime/foundation/service-liveness-registry.ts +2 -1
- package/src/runtime/foundation/service-maintenance-runtime.ts +30 -19
- package/src/runtime/foundation/service-metadata-codec.ts +2 -2
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
- package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
- package/src/runtime/foundation/service-relocation-object-owner.ts +23 -7
- package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
- package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -25
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +435 -327
- package/src/runtime/foundation/service-stateful-wire-codec.ts +329 -199
- package/src/runtime/foundation/service-topology-registry.ts +30 -79
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
- package/src/runtime/foundation/service-wire-codec.ts +15 -8
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
- package/src/runtime/framework-errors-internal.ts +380 -134
- package/src/runtime/handlers/handler-instance-scope.ts +68 -95
- package/src/runtime/host/actor-packet-relay.ts +57 -147
- package/src/runtime/host/actor-placement-coordinator.ts +8 -5
- package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
- package/src/runtime/host/actor-transfer-runtime.ts +266 -418
- package/src/runtime/host/application-job-queue.ts +28 -34
- package/src/runtime/host/bound-session-relay.ts +1 -2
- package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
- package/src/runtime/host/index.ts +408 -312
- package/src/runtime/host/instance-activation-authority.ts +89 -109
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
- package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
- package/src/runtime/host/remote-bound-session-relay.ts +12 -44
- package/src/runtime/host/route-mesh-runtime.ts +236 -275
- package/src/runtime/host/runtime-shutdown.ts +17 -21
- package/src/runtime/host/service-relocation-control.ts +14 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +1161 -904
- package/src/runtime/host/spot-address-transport.ts +73 -195
- package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
- package/src/runtime/host/spot-runtime-options-factory.ts +92 -30
- package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
- package/src/runtime/host/user-spot-creation-coordinator.ts +182 -163
- package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
- package/src/runtime/locations/authority-key-codec.ts +7 -3
- package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
- package/src/runtime/locations/creation-operation-id.ts +6 -3
- package/src/runtime/locations/domain-store-contract.ts +12 -3
- package/src/runtime/locations/in-memory-authority-store.ts +44 -15
- package/src/runtime/locations/in-memory-location-store.ts +50 -39
- package/src/runtime/locations/in-memory-provider-location-store.ts +110 -31
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +16 -45
- package/src/runtime/locations/location-store-failure.ts +4 -0
- package/src/runtime/locations/location-store-pages.ts +18 -0
- package/src/runtime/locations/location-store-repository.ts +450 -478
- package/src/runtime/locations/relocation-blob.ts +17 -6
- package/src/runtime/locations/resolvers.ts +90 -58
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +54 -26
- package/src/runtime/messaging/payload-codec.ts +35 -24
- package/src/runtime/messaging/submission-result.ts +57 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +27 -10
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +6 -3
- package/src/runtime/spots/index.ts +687 -437
- package/src/runtime/spots/spot-activation-registry.ts +42 -71
- package/src/runtime/spots/spot-activation-state.ts +4 -16
- package/src/runtime/spots/spot-activation.ts +167 -115
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +25 -79
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
- package/src/runtime/spots/spot-actor-membership.ts +107 -75
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
- package/src/runtime/spots/spot-context.ts +3 -3
- package/src/runtime/spots/spot-entry-activation.ts +13 -33
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +29 -21
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +145 -140
- package/src/runtime/spots/spot-outbound.ts +47 -68
- package/src/runtime/spots/spot-remote-codec.ts +7 -3
- package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
- package/src/runtime/spots/spot-route-replies.ts +6 -4
- package/src/runtime/spots/spot-routed-actor-admission.ts +13 -6
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -77
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +10 -43
- package/src/runtime/spots/spot-serial-executor.ts +10 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +120 -13
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +182 -560
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +1 -19
- package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
- package/src/runtime/streams/bound-session-service.ts +23 -37
- package/src/runtime/streams/index.ts +102 -88
- package/src/runtime/streams/managed-stream.ts +29 -10
- package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
- package/src/runtime/streams/protocol.ts +34 -88
- package/src/runtime/streams/session-actor-coordinator.ts +17 -5
- package/src/runtime/streams/session-calls.ts +6 -5
- package/src/runtime/streams/session-context.ts +54 -10
- package/src/runtime/streams/session-requests.ts +2 -1
- package/src/runtime/streams/session-serial-executor.ts +2 -2
- package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
- package/src/runtime/streams/stream-frame-factory.ts +2 -3
- package/src/runtime/streams/stream-session-runtime.ts +57 -59
- package/src/runtime/workers/index.ts +13 -12
- package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
- package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
- package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
- package/dist/runtime/actors/post-commit-actor-location.js +0 -72
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
- package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
- package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
- package/src/runtime/actors/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dispatchReasonFromError } from '../diagnostics/dispatch-error-details';
|
|
1
2
|
import type {
|
|
2
3
|
ActorRef,
|
|
3
4
|
RoutingId,
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
ZLinkMessage,
|
|
33
34
|
ZLinkFrameworkException,
|
|
34
35
|
ZLinkFrameworkErrorKind,
|
|
36
|
+
ZLinkFrameworkRuntimeState,
|
|
35
37
|
ZLinkSpotCloseReason,
|
|
36
38
|
ZLinkSpotKind
|
|
37
39
|
} from '../../contracts';
|
|
@@ -48,6 +50,7 @@ import {
|
|
|
48
50
|
runWithFlow,
|
|
49
51
|
type ZLinkRuntimeEventPublisher
|
|
50
52
|
} from '../diagnostics';
|
|
53
|
+
import { diagnosticTextOrAbsent } from '../diagnostics/diagnostic-text';
|
|
51
54
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
52
55
|
import { SubmitResult } from '../backend/runtime-values';
|
|
53
56
|
import {
|
|
@@ -59,10 +62,10 @@ import {
|
|
|
59
62
|
} from '../foundation/service-runtime-contracts';
|
|
60
63
|
import { zlinkMetadataByteLength, zlinkSerialWorkOptions } from '../execution/serial-work-size';
|
|
61
64
|
import { ZLinkConfigurationException } from '../configuration';
|
|
65
|
+
import { releaseApplicationJobPermitBeforeHandler } from '../application-jobs/application-job-queue-scope';
|
|
62
66
|
import {
|
|
63
67
|
ZLinkFrameworkInternalErrorKind,
|
|
64
68
|
createInternalFrameworkException,
|
|
65
|
-
internalFrameworkErrorKind,
|
|
66
69
|
internalFrameworkWireReply
|
|
67
70
|
} from '../framework-errors-internal';
|
|
68
71
|
import type { ZLinkBackendSpot, ZLinkBackendSpotNode } from '../backend/contracts';
|
|
@@ -72,7 +75,7 @@ import { ZLinkWorkerRuntime } from '../workers';
|
|
|
72
75
|
import {
|
|
73
76
|
type ZLinkActorHandoffPrefixAdmission,
|
|
74
77
|
type ZLinkActorHandoffPrefixRecord,
|
|
75
|
-
type
|
|
78
|
+
type ZLinkDeferredJoinCompletion,
|
|
76
79
|
type ZLinkRemoteBoundSessionTarget
|
|
77
80
|
} from '../actors';
|
|
78
81
|
import type { ZLinkLocationLifecycle } from '../locations';
|
|
@@ -130,9 +133,9 @@ export {
|
|
|
130
133
|
} from './spot-handler-registry';
|
|
131
134
|
export { ZLinkRuntimeSpotPublisherTransport } from './spot-publisher-transport';
|
|
132
135
|
import { ZLinkSpotActivationRegistry } from './spot-activation-registry';
|
|
133
|
-
import {
|
|
136
|
+
import type { ZLinkSpotActivation } from './spot-activation-state';
|
|
134
137
|
import { ZLinkSpotActivationLifecycle, type ZLinkNativeSpotAuthority } from './spot-activation';
|
|
135
|
-
import { ZLinkSpotActorMembership
|
|
138
|
+
import { ZLinkSpotActorMembership } from './spot-actor-membership';
|
|
136
139
|
import { ZLinkFormalRemoteActorTransferRegistry } from './formal-remote-actor-transfer-registry';
|
|
137
140
|
import {
|
|
138
141
|
ZLinkFormalRemoteActorAdmissionRegistry,
|
|
@@ -145,6 +148,7 @@ import type {
|
|
|
145
148
|
ZLinkSpotBoundSessionRuntime
|
|
146
149
|
} from './spot-runtime-ports';
|
|
147
150
|
import type { ZLinkRuntimeAdmissionGate } from '../admission';
|
|
151
|
+
import type { ZLinkActivationAdmission } from '../activation-admission';
|
|
148
152
|
import type { ZLinkDetachedTaskRunner } from './spot-actor-join-dispatch';
|
|
149
153
|
import type { ZLinkLocalSpotCreateResult } from './spot-manager-internal-contracts';
|
|
150
154
|
export type { ZLinkLocalSpotCreateResult } from './spot-manager-internal-contracts';
|
|
@@ -203,6 +207,11 @@ export interface ZLinkSpotManagerOptions {
|
|
|
203
207
|
actor: ZLinkActor,
|
|
204
208
|
handoffBacklog?: readonly ZLinkActorHandoffPacket[]
|
|
205
209
|
) => Promise<void>;
|
|
210
|
+
readonly executeEntryActor?: <T>(
|
|
211
|
+
meshName: string,
|
|
212
|
+
actorId: string,
|
|
213
|
+
operation: () => Promise<T>
|
|
214
|
+
) => Promise<T>;
|
|
206
215
|
readonly actorCountProvider?: (spotId: RoutingId) => number;
|
|
207
216
|
readonly userSpotExecutionMode?: (
|
|
208
217
|
meshName: string,
|
|
@@ -216,7 +225,6 @@ export interface ZLinkSpotManagerOptions {
|
|
|
216
225
|
readonly actorRef?: ActorRef;
|
|
217
226
|
readonly spotId?: RoutingId;
|
|
218
227
|
};
|
|
219
|
-
readonly actorBindingGenerationObserver?: (actorId: string, generation: bigint) => void;
|
|
220
228
|
readonly channelClient?: ZLinkChannelClient;
|
|
221
229
|
readonly fanoutClient?: ZLinkFanoutClient;
|
|
222
230
|
readonly spotPublisherClient?: ZLinkSpotPublisherClient;
|
|
@@ -224,9 +232,9 @@ export interface ZLinkSpotManagerOptions {
|
|
|
224
232
|
readonly routedTransport?: ZLinkSpotRoutedTransport;
|
|
225
233
|
readonly addressTransport?: import('./spot-outbound').ZLinkSpotAddressTransport;
|
|
226
234
|
readonly spotRouterChannelIdForMesh?: (meshName: string) => string;
|
|
227
|
-
readonly channelMeshNameForChannel?: (channelName: string) => string | undefined;
|
|
228
235
|
readonly providerResolver?: ZLinkProviderResolver;
|
|
229
236
|
readonly dispatchErrors?: ZLinkDispatchErrorReporter;
|
|
237
|
+
readonly closeErrorSink?: import('../diagnostics/dispatch-error-port').ZLinkDispatchErrorSink;
|
|
230
238
|
readonly runtimeEventPublisher?: ZLinkRuntimeEventPublisher;
|
|
231
239
|
readonly workerRuntime?: ZLinkWorkerRuntime;
|
|
232
240
|
readonly messageSerializers?: ReadonlyMap<string, ZLinkMessageSerializer>;
|
|
@@ -238,12 +246,28 @@ export interface ZLinkSpotManagerOptions {
|
|
|
238
246
|
) => Promise<void>;
|
|
239
247
|
readonly beginInstanceIdleClosingAuthority?: (
|
|
240
248
|
meshName: string,
|
|
241
|
-
spotId: RoutingId
|
|
242
|
-
|
|
249
|
+
spotId: RoutingId,
|
|
250
|
+
onCommitted: () => void
|
|
251
|
+
) => Promise<
|
|
252
|
+
import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
|
|
253
|
+
>;
|
|
243
254
|
readonly beginInstanceClosingAuthority?: (
|
|
244
255
|
meshName: string,
|
|
245
|
-
spotId: RoutingId
|
|
246
|
-
|
|
256
|
+
spotId: RoutingId,
|
|
257
|
+
onCommitted: () => void,
|
|
258
|
+
objectGeneration: bigint
|
|
259
|
+
) => Promise<
|
|
260
|
+
import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
|
|
261
|
+
>;
|
|
262
|
+
/** Moves a local User Spot incarnation's authority to Closing for a context Close. */
|
|
263
|
+
readonly beginUserClosingAuthority?: (
|
|
264
|
+
meshName: string,
|
|
265
|
+
spotId: RoutingId,
|
|
266
|
+
objectGeneration: bigint,
|
|
267
|
+
onCommitted: () => void
|
|
268
|
+
) => Promise<
|
|
269
|
+
import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
|
|
270
|
+
>;
|
|
247
271
|
readonly instanceSpotApplicationTargetProvider?: (
|
|
248
272
|
meshName: string,
|
|
249
273
|
spotId: RoutingId
|
|
@@ -261,7 +285,6 @@ export interface ZLinkSpotManagerOptions {
|
|
|
261
285
|
spotId: RoutingId,
|
|
262
286
|
authority?: ZLinkNativeSpotAuthority
|
|
263
287
|
) => ZLinkBackendSpot | undefined;
|
|
264
|
-
readonly createReceived?: () => import('../backend').ZLinkBackendReceived;
|
|
265
288
|
readonly createTopicMessage?: () => import('../backend').ZLinkBackendTopicMessage;
|
|
266
289
|
readonly nativeSpotNodeProvider?: (meshName: string) => ZLinkBackendSpotNode | undefined;
|
|
267
290
|
readonly actorResolver?: (actorId: string) => ZLinkActor | undefined;
|
|
@@ -274,15 +297,33 @@ export interface ZLinkSpotManagerOptions {
|
|
|
274
297
|
readonly ownerLeaseGeneration: bigint;
|
|
275
298
|
}) => Promise<{ readonly actorType: string }>;
|
|
276
299
|
readonly actorLifecycleResolver?: (actorId: string) => ZLinkActor | undefined;
|
|
277
|
-
readonly detachedTaskRunner
|
|
300
|
+
readonly detachedTaskRunner: ZLinkDetachedTaskRunner;
|
|
278
301
|
readonly actorTransferRuntime?: ZLinkSpotActorTransferRuntime;
|
|
279
302
|
readonly boundSessionRuntime?: ZLinkSpotBoundSessionRuntime;
|
|
280
303
|
readonly actorHandoffRuntime?: ZLinkSpotActorHandoffRuntime;
|
|
281
304
|
readonly metrics?: import('../diagnostics').ZLinkRuntimeMetrics;
|
|
282
305
|
readonly admission?: ZLinkRuntimeAdmissionGate;
|
|
283
|
-
readonly
|
|
284
|
-
|
|
285
|
-
|
|
306
|
+
readonly statefulExecution?: {
|
|
307
|
+
readonly admissionOpen: () => boolean;
|
|
308
|
+
readonly hostState: () => ZLinkFrameworkRuntimeState;
|
|
309
|
+
};
|
|
310
|
+
readonly activationAdmission?: ZLinkActivationAdmission;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
interface ZLinkTargetSpotCloseOperation {
|
|
314
|
+
readonly activation: ZLinkSpotActivation;
|
|
315
|
+
readonly reason: ZLinkSpotCloseReason;
|
|
316
|
+
readonly beginAuthority: (
|
|
317
|
+
onCommitted: () => void
|
|
318
|
+
) => Promise<
|
|
319
|
+
import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
|
|
320
|
+
>;
|
|
321
|
+
authority?: import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority;
|
|
322
|
+
authorityDecision?: Promise<void>;
|
|
323
|
+
ready?: Promise<boolean>;
|
|
324
|
+
canExecuteApplication?(
|
|
325
|
+
record: import('../execution/serial-execution-queue').ZLinkSerialWorkRecord<unknown>
|
|
326
|
+
): boolean;
|
|
286
327
|
}
|
|
287
328
|
|
|
288
329
|
export class DefaultZLinkSpotManager {
|
|
@@ -306,27 +347,7 @@ export class DefaultZLinkSpotManager {
|
|
|
306
347
|
string,
|
|
307
348
|
Map<string, Promise<ZLinkSpotActivation>>
|
|
308
349
|
>();
|
|
309
|
-
private readonly
|
|
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
|
-
>();
|
|
329
|
-
private readonly pendingInstanceCloses = new Map<string, Promise<boolean>>();
|
|
350
|
+
private readonly closeOperations = new Map<string, ZLinkTargetSpotCloseOperation>();
|
|
330
351
|
private readonly pendingInstanceTerminals = new Map<string, number>();
|
|
331
352
|
private readonly pendingInstanceTerminalGenerations = new Map<string, Map<string, number>>();
|
|
332
353
|
private readonly deferredInstanceAuthorityReleases = new Map<string, Set<bigint>>();
|
|
@@ -337,6 +358,9 @@ export class DefaultZLinkSpotManager {
|
|
|
337
358
|
private readonly options: ZLinkSpotManagerOptions,
|
|
338
359
|
timerClock?: import('./spot-timer').ZLinkTimerClock
|
|
339
360
|
) {
|
|
361
|
+
if ((options.detachedTaskRunner as unknown) === undefined) {
|
|
362
|
+
throw new ZLinkConfigurationException('Spot manager requires a detached task runner.');
|
|
363
|
+
}
|
|
340
364
|
this.activations = new ZLinkSpotActivationRegistry(options.metrics);
|
|
341
365
|
this.factories = new Set(options.spotFactories);
|
|
342
366
|
this.workerRuntime = options.workerRuntime ?? new ZLinkWorkerRuntime();
|
|
@@ -347,7 +371,7 @@ export class DefaultZLinkSpotManager {
|
|
|
347
371
|
nodeGenerationProvider: options.nodeGenerationProvider
|
|
348
372
|
});
|
|
349
373
|
this.routedSpotPackets = new ZLinkRoutedSpotPacketDispatch({
|
|
350
|
-
resolveActivation: (spotId) => this.
|
|
374
|
+
resolveActivation: (spotId) => this.resolveApplicationActivation(spotId),
|
|
351
375
|
claimApplicationWork:
|
|
352
376
|
options.admission === undefined
|
|
353
377
|
? undefined
|
|
@@ -392,12 +416,12 @@ export class DefaultZLinkSpotManager {
|
|
|
392
416
|
spotRouterChannelIdForMesh: options.spotRouterChannelIdForMesh,
|
|
393
417
|
providerResolver: options.providerResolver,
|
|
394
418
|
dispatchErrors: options.dispatchErrors,
|
|
419
|
+
closeErrorSink: options.closeErrorSink,
|
|
395
420
|
runtimeEventPublisher: options.runtimeEventPublisher,
|
|
396
421
|
workerRuntime: this.workerRuntime,
|
|
397
422
|
messageSerializers: options.messageSerializers,
|
|
398
423
|
locationClaim: this.locationClaim,
|
|
399
424
|
createNativeSpot: options.createNativeSpot,
|
|
400
|
-
createReceived: options.createReceived,
|
|
401
425
|
createTopicMessage: options.createTopicMessage,
|
|
402
426
|
nativeSpotNodeProvider: options.nativeSpotNodeProvider,
|
|
403
427
|
actorResolver: options.actorResolver,
|
|
@@ -406,11 +430,11 @@ export class DefaultZLinkSpotManager {
|
|
|
406
430
|
boundSessionRuntime: options.boundSessionRuntime,
|
|
407
431
|
actorHandoffRuntime: options.actorHandoffRuntime,
|
|
408
432
|
admission: options.admission,
|
|
409
|
-
statefulExecutionAllowed: options.
|
|
433
|
+
statefulExecutionAllowed: options.statefulExecution?.admissionOpen,
|
|
410
434
|
leaveActor: (spotId, actor, signal, meshName) =>
|
|
411
435
|
this.actorMembership.leaveActor(spotId, actor, signal, meshName),
|
|
412
|
-
|
|
413
|
-
this.
|
|
436
|
+
requestContextClose: (activation, objectGeneration, signal) =>
|
|
437
|
+
this.closeFromContext(activation, objectGeneration, signal),
|
|
414
438
|
registerActivation: (activation) => {
|
|
415
439
|
this.activations.register(activation);
|
|
416
440
|
this.scheduleIdleSweep();
|
|
@@ -470,14 +494,6 @@ export class DefaultZLinkSpotManager {
|
|
|
470
494
|
return this.activations.list(meshName).length;
|
|
471
495
|
}
|
|
472
496
|
|
|
473
|
-
instanceActivationConcurrency(meshName: string): {
|
|
474
|
-
readonly active: number;
|
|
475
|
-
readonly limit: number;
|
|
476
|
-
} {
|
|
477
|
-
const limit = this.options.activationConcurrencyLimitProvider?.(meshName) ?? 128;
|
|
478
|
-
return { active: this.instanceActivationGates.get(meshName)?.active ?? 0, limit };
|
|
479
|
-
}
|
|
480
|
-
|
|
481
497
|
resolveRelocationActivation(
|
|
482
498
|
meshName: string,
|
|
483
499
|
spotId: RoutingId
|
|
@@ -548,7 +564,7 @@ export class DefaultZLinkSpotManager {
|
|
|
548
564
|
await awaitWithAbort(existing, signal);
|
|
549
565
|
return;
|
|
550
566
|
}
|
|
551
|
-
const release = await this.
|
|
567
|
+
const release = await this.options.activationAdmission?.acquire(meshName, signal);
|
|
552
568
|
try {
|
|
553
569
|
await this.materializeInstanceCore(
|
|
554
570
|
meshName,
|
|
@@ -559,7 +575,7 @@ export class DefaultZLinkSpotManager {
|
|
|
559
575
|
signal
|
|
560
576
|
);
|
|
561
577
|
} finally {
|
|
562
|
-
release();
|
|
578
|
+
release?.();
|
|
563
579
|
}
|
|
564
580
|
}
|
|
565
581
|
|
|
@@ -590,7 +606,8 @@ export class DefaultZLinkSpotManager {
|
|
|
590
606
|
// explicit Instance intent arriving at that boundary must wait for the
|
|
591
607
|
// old resources to be released before materializing the replacement.
|
|
592
608
|
// This is lifecycle convergence; it does not resubmit application work.
|
|
593
|
-
const
|
|
609
|
+
const closeOperation = this.closeOperations.get(key);
|
|
610
|
+
const pendingClose = closeOperation?.ready;
|
|
594
611
|
if (pendingClose !== undefined) {
|
|
595
612
|
await awaitWithAbort(pendingClose, signal);
|
|
596
613
|
continue;
|
|
@@ -687,94 +704,50 @@ export class DefaultZLinkSpotManager {
|
|
|
687
704
|
}
|
|
688
705
|
}
|
|
689
706
|
|
|
690
|
-
private async acquireInstanceActivation(
|
|
691
|
-
meshName: string,
|
|
692
|
-
signal?: AbortSignal
|
|
693
|
-
): Promise<() => void> {
|
|
694
|
-
let gate = this.instanceActivationGates.get(meshName);
|
|
695
|
-
if (gate === undefined) {
|
|
696
|
-
gate = {
|
|
697
|
-
meshName,
|
|
698
|
-
limit: this.options.activationConcurrencyLimitProvider?.(meshName) ?? 128,
|
|
699
|
-
active: 0,
|
|
700
|
-
waiters: [],
|
|
701
|
-
waiterHead: 0
|
|
702
|
-
};
|
|
703
|
-
this.instanceActivationGates.set(meshName, gate);
|
|
704
|
-
}
|
|
705
|
-
if (signal?.aborted === true) throw signal.reason;
|
|
706
|
-
if (gate.active < gate.limit) {
|
|
707
|
-
gate.active += 1;
|
|
708
|
-
this.options.onInstanceActivationConcurrencyChanged?.(meshName);
|
|
709
|
-
return () => this.releaseInstanceActivation(gate!);
|
|
710
|
-
}
|
|
711
|
-
return new Promise<() => void>((resolve, reject) => {
|
|
712
|
-
const waiter = { resolve, reject, signal, abort: undefined as (() => void) | undefined };
|
|
713
|
-
const slot = gate!.waiters.length;
|
|
714
|
-
waiter.abort = () => {
|
|
715
|
-
if (gate!.waiters[slot] === waiter) gate!.waiters[slot] = undefined;
|
|
716
|
-
reject(signal?.reason);
|
|
717
|
-
};
|
|
718
|
-
signal?.addEventListener('abort', waiter.abort, { once: true });
|
|
719
|
-
gate!.waiters.push(waiter);
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
private releaseInstanceActivation(gate: {
|
|
724
|
-
readonly meshName: string;
|
|
725
|
-
readonly limit: number;
|
|
726
|
-
active: number;
|
|
727
|
-
readonly waiters: Array<
|
|
728
|
-
| {
|
|
729
|
-
resolve: (release: () => void) => void;
|
|
730
|
-
reject: (error: unknown) => void;
|
|
731
|
-
signal?: AbortSignal;
|
|
732
|
-
abort?: () => void;
|
|
733
|
-
}
|
|
734
|
-
| undefined
|
|
735
|
-
>;
|
|
736
|
-
waiterHead: number;
|
|
737
|
-
}): void {
|
|
738
|
-
while (gate.waiterHead < gate.waiters.length) {
|
|
739
|
-
const waiter = gate.waiters[gate.waiterHead];
|
|
740
|
-
gate.waiters[gate.waiterHead] = undefined;
|
|
741
|
-
gate.waiterHead += 1;
|
|
742
|
-
if (gate.waiterHead >= gate.waiters.length) {
|
|
743
|
-
gate.waiters.length = 0;
|
|
744
|
-
gate.waiterHead = 0;
|
|
745
|
-
}
|
|
746
|
-
if (waiter === undefined) continue;
|
|
747
|
-
if (waiter.abort !== undefined) waiter.signal?.removeEventListener('abort', waiter.abort);
|
|
748
|
-
waiter.resolve(() => this.releaseInstanceActivation(gate));
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
gate.waiters.length = 0;
|
|
752
|
-
gate.waiterHead = 0;
|
|
753
|
-
gate.active -= 1;
|
|
754
|
-
this.options.onInstanceActivationConcurrencyChanged?.(gate.meshName);
|
|
755
|
-
}
|
|
756
|
-
|
|
757
707
|
isInstanceMaterialized(meshName: string, instanceType: string, spotId: RoutingId): boolean {
|
|
758
|
-
const activation = this.
|
|
708
|
+
const activation = this.resolveApplicationActivation(spotId, meshName);
|
|
759
709
|
return (
|
|
760
710
|
activation !== undefined &&
|
|
761
711
|
activation.spotType === this.requireInstanceFactory(meshName, instanceType)
|
|
762
712
|
);
|
|
763
713
|
}
|
|
764
714
|
|
|
715
|
+
private resolveApplicationActivation(
|
|
716
|
+
spotId: RoutingId,
|
|
717
|
+
meshName?: string
|
|
718
|
+
): ZLinkSpotActivation | undefined {
|
|
719
|
+
const current =
|
|
720
|
+
meshName === undefined
|
|
721
|
+
? this.activations.resolveUnique(spotId)
|
|
722
|
+
: this.activations.resolve(meshName, spotId);
|
|
723
|
+
if (current !== undefined) return current;
|
|
724
|
+
if (meshName !== undefined)
|
|
725
|
+
return this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.activation;
|
|
726
|
+
for (const operation of this.closeOperations.values()) {
|
|
727
|
+
if (String(operation.activation.spotId) === String(spotId)) return operation.activation;
|
|
728
|
+
}
|
|
729
|
+
return undefined;
|
|
730
|
+
}
|
|
731
|
+
|
|
765
732
|
isInstanceMaterializing(meshName: string, spotId: RoutingId): boolean {
|
|
766
733
|
const prefix = instanceMaterializationPrefix(meshName, spotId);
|
|
767
|
-
return (
|
|
734
|
+
return (
|
|
735
|
+
(this.pendingInstanceMaterializationsByPrefix.get(prefix)?.size ?? 0) > 0 ||
|
|
736
|
+
this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.authority !== undefined
|
|
737
|
+
);
|
|
768
738
|
}
|
|
769
739
|
|
|
770
|
-
|
|
771
|
-
const key = `${meshName}\0${String(spotId)}`;
|
|
740
|
+
isSpotClosing(meshName: string, spotId: RoutingId): boolean {
|
|
772
741
|
return (
|
|
773
|
-
this.
|
|
774
|
-
this.activations.
|
|
742
|
+
this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.authority !== undefined ||
|
|
743
|
+
this.activations.activationForClose(meshName, spotId)?.executionBarrier.isCloseSealed === true
|
|
775
744
|
);
|
|
776
745
|
}
|
|
777
746
|
|
|
747
|
+
pendingSpotCloseDecision(meshName: string, spotId: RoutingId): Promise<void> | undefined {
|
|
748
|
+
return this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.authorityDecision;
|
|
749
|
+
}
|
|
750
|
+
|
|
778
751
|
async discardInstance(meshName: string, spotId: RoutingId): Promise<void> {
|
|
779
752
|
const activation = this.activations.resolve(meshName, spotId);
|
|
780
753
|
if (activation === undefined) return;
|
|
@@ -835,7 +808,7 @@ export class DefaultZLinkSpotManager {
|
|
|
835
808
|
}
|
|
836
809
|
this.pendingInstanceTerminals.delete(key);
|
|
837
810
|
this.pendingInstanceTerminalGenerations.delete(key);
|
|
838
|
-
const pendingClose = this.
|
|
811
|
+
const pendingClose = this.closeOperations.get(key)?.ready;
|
|
839
812
|
if (pendingClose !== undefined) {
|
|
840
813
|
this.deferInstanceAuthorityRelease(key, objectGeneration);
|
|
841
814
|
await pendingClose;
|
|
@@ -950,20 +923,6 @@ export class DefaultZLinkSpotManager {
|
|
|
950
923
|
) {
|
|
951
924
|
continue;
|
|
952
925
|
}
|
|
953
|
-
let durableClosing: { restoreReady(): Promise<void> } | undefined;
|
|
954
|
-
try {
|
|
955
|
-
durableClosing = await (this.options.beginInstanceIdleClosingAuthority?.(
|
|
956
|
-
activation.meshName,
|
|
957
|
-
activation.spotId
|
|
958
|
-
) ?? Promise.resolve({ restoreReady: async () => undefined }));
|
|
959
|
-
} catch (error) {
|
|
960
|
-
activation.abortIdleEviction();
|
|
961
|
-
throw error;
|
|
962
|
-
}
|
|
963
|
-
if (durableClosing === undefined) {
|
|
964
|
-
activation.abortIdleEviction();
|
|
965
|
-
continue;
|
|
966
|
-
}
|
|
967
926
|
const close = this.closeWithReason(
|
|
968
927
|
activation.meshName,
|
|
969
928
|
activation.spotId,
|
|
@@ -973,25 +932,17 @@ export class DefaultZLinkSpotManager {
|
|
|
973
932
|
const run = async () => {
|
|
974
933
|
try {
|
|
975
934
|
const closed = await close;
|
|
976
|
-
if (!closed)
|
|
977
|
-
await durableClosing.restoreReady();
|
|
978
|
-
activation.abortIdleEviction();
|
|
979
|
-
}
|
|
935
|
+
if (!closed) activation.abortIdleEviction();
|
|
980
936
|
} catch (error) {
|
|
981
|
-
if (
|
|
982
|
-
|
|
983
|
-
}
|
|
984
|
-
activation.abortIdleEviction();
|
|
937
|
+
if (!this.isSpotClosing(activation.meshName, activation.spotId))
|
|
938
|
+
activation.abortIdleEviction();
|
|
985
939
|
throw error;
|
|
986
940
|
}
|
|
987
941
|
};
|
|
988
|
-
this.options.detachedTaskRunner
|
|
942
|
+
this.options.detachedTaskRunner.runDetached(
|
|
989
943
|
`instance idle eviction ${String(activation.spotId)}`,
|
|
990
944
|
run
|
|
991
945
|
);
|
|
992
|
-
if (this.options.detachedTaskRunner === undefined) {
|
|
993
|
-
void run().catch(() => undefined);
|
|
994
|
-
}
|
|
995
946
|
}
|
|
996
947
|
} finally {
|
|
997
948
|
this.idleSweepRunning = false;
|
|
@@ -1085,8 +1036,9 @@ export class DefaultZLinkSpotManager {
|
|
|
1085
1036
|
requireMeshName(meshName);
|
|
1086
1037
|
const args = normalizeSpotCreateArgs(requestOrSignal, signal);
|
|
1087
1038
|
throwIfAborted(args.signal);
|
|
1039
|
+
this.options.admission?.requireRequest('SPOT create', meshName);
|
|
1088
1040
|
const operation = this.activations.getOrBegin(meshName, spotType, spotId, async () => {
|
|
1089
|
-
this.options.
|
|
1041
|
+
const release = await this.options.activationAdmission?.acquire(meshName, args.signal);
|
|
1090
1042
|
const ownedRequest =
|
|
1091
1043
|
args.request === undefined
|
|
1092
1044
|
? RuntimeMessage.from(Buffer.alloc(0))
|
|
@@ -1102,6 +1054,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1102
1054
|
);
|
|
1103
1055
|
} finally {
|
|
1104
1056
|
ownedRequest.close();
|
|
1057
|
+
release?.();
|
|
1105
1058
|
}
|
|
1106
1059
|
});
|
|
1107
1060
|
return await awaitWithAbort(operation.ready, args.signal);
|
|
@@ -1109,12 +1062,16 @@ export class DefaultZLinkSpotManager {
|
|
|
1109
1062
|
|
|
1110
1063
|
async find(meshName: string, spotId: RoutingId): Promise<ZLinkSpotInfo | null> {
|
|
1111
1064
|
requireMeshName(meshName);
|
|
1112
|
-
return this.activations.has(meshName, spotId)
|
|
1065
|
+
return this.activations.has(meshName, spotId) && !this.isSpotClosing(meshName, spotId)
|
|
1066
|
+
? { spotId }
|
|
1067
|
+
: null;
|
|
1113
1068
|
}
|
|
1114
1069
|
|
|
1115
1070
|
async list(meshName: string): Promise<readonly ZLinkSpotInfo[]> {
|
|
1116
1071
|
requireMeshName(meshName);
|
|
1117
|
-
return this.activations
|
|
1072
|
+
return this.activations
|
|
1073
|
+
.list(meshName)
|
|
1074
|
+
.filter(({ spotId }) => !this.isSpotClosing(meshName, spotId));
|
|
1118
1075
|
}
|
|
1119
1076
|
|
|
1120
1077
|
async drainForShutdown(meshName: string, signal?: AbortSignal, deadline?: Date): Promise<void> {
|
|
@@ -1143,120 +1100,289 @@ export class DefaultZLinkSpotManager {
|
|
|
1143
1100
|
return await this.closeWithReason(meshName, spotId, signal, ZLinkSpotCloseReason.ExplicitClose);
|
|
1144
1101
|
}
|
|
1145
1102
|
|
|
1103
|
+
async closeUserWithAuthority(
|
|
1104
|
+
meshName: string,
|
|
1105
|
+
spotId: RoutingId,
|
|
1106
|
+
beginAuthority: (
|
|
1107
|
+
onCommitted: () => void
|
|
1108
|
+
) => Promise<import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority>,
|
|
1109
|
+
signal?: AbortSignal
|
|
1110
|
+
): Promise<boolean> {
|
|
1111
|
+
return await this.closeWithReason(
|
|
1112
|
+
meshName,
|
|
1113
|
+
spotId,
|
|
1114
|
+
signal,
|
|
1115
|
+
ZLinkSpotCloseReason.ExplicitClose,
|
|
1116
|
+
undefined,
|
|
1117
|
+
beginAuthority
|
|
1118
|
+
);
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
private closeFromContext(
|
|
1122
|
+
activation: ZLinkSpotActivation,
|
|
1123
|
+
objectGeneration: bigint,
|
|
1124
|
+
signal?: AbortSignal
|
|
1125
|
+
): Promise<boolean> {
|
|
1126
|
+
const { meshName, spotId } = activation;
|
|
1127
|
+
const operation = this.closeOperations.get(`${meshName}\0${String(spotId)}`);
|
|
1128
|
+
const current = operation?.activation ?? this.activations.resolve(meshName, spotId);
|
|
1129
|
+
if (current === undefined) {
|
|
1130
|
+
return Promise.resolve(false);
|
|
1131
|
+
}
|
|
1132
|
+
if (current !== activation || current.objectGeneration !== objectGeneration) {
|
|
1133
|
+
return Promise.reject(
|
|
1134
|
+
createInternalFrameworkException(
|
|
1135
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
1136
|
+
`Spot '${String(spotId)}' generation is stale.`
|
|
1137
|
+
)
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
const beginUserAuthority =
|
|
1141
|
+
activation.domain.kind === 'user' && this.options.beginUserClosingAuthority !== undefined
|
|
1142
|
+
? (onCommitted: () => void) =>
|
|
1143
|
+
this.options.beginUserClosingAuthority!(meshName, spotId, objectGeneration, onCommitted)
|
|
1144
|
+
: undefined;
|
|
1145
|
+
return this.closeWithReason(
|
|
1146
|
+
meshName,
|
|
1147
|
+
spotId,
|
|
1148
|
+
signal,
|
|
1149
|
+
ZLinkSpotCloseReason.ExplicitClose,
|
|
1150
|
+
undefined,
|
|
1151
|
+
beginUserAuthority
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1146
1155
|
private async closeWithReason(
|
|
1147
1156
|
meshName: string,
|
|
1148
1157
|
spotId: RoutingId,
|
|
1149
1158
|
signal?: AbortSignal,
|
|
1150
1159
|
reason = ZLinkSpotCloseReason.ExplicitClose,
|
|
1151
|
-
deadline?: Date
|
|
1160
|
+
deadline?: Date,
|
|
1161
|
+
beginUserAuthority?: (
|
|
1162
|
+
onCommitted: () => void
|
|
1163
|
+
) => Promise<
|
|
1164
|
+
import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
|
|
1165
|
+
>
|
|
1152
1166
|
): Promise<boolean> {
|
|
1153
1167
|
requireMeshName(meshName);
|
|
1154
1168
|
const key = `${meshName}\0${String(spotId)}`;
|
|
1155
|
-
|
|
1156
|
-
if (
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1169
|
+
let operation = this.closeOperations.get(key);
|
|
1170
|
+
if (operation === undefined) {
|
|
1171
|
+
const activation = this.activations.resolve(meshName, spotId);
|
|
1172
|
+
if (activation === undefined) return false;
|
|
1173
|
+
if (
|
|
1174
|
+
activation.domain.kind === 'user' &&
|
|
1175
|
+
reason === ZLinkSpotCloseReason.ExplicitClose &&
|
|
1176
|
+
beginUserAuthority === undefined
|
|
1177
|
+
) {
|
|
1178
|
+
throw createInternalFrameworkException(
|
|
1179
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
1180
|
+
`User Spot '${String(spotId)}' Close requires its authority owner.`
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
const domain = activation.domain;
|
|
1184
|
+
const beginAuthority =
|
|
1185
|
+
beginUserAuthority ??
|
|
1186
|
+
(domain.kind === 'instance' &&
|
|
1187
|
+
reason === ZLinkSpotCloseReason.ExplicitClose &&
|
|
1188
|
+
this.options.beginInstanceClosingAuthority !== undefined
|
|
1189
|
+
? (onCommitted) =>
|
|
1190
|
+
this.options.beginInstanceClosingAuthority!(
|
|
1191
|
+
meshName,
|
|
1192
|
+
spotId,
|
|
1193
|
+
onCommitted,
|
|
1194
|
+
domain.objectGeneration
|
|
1195
|
+
)
|
|
1196
|
+
: domain.kind === 'instance' &&
|
|
1197
|
+
reason === ZLinkSpotCloseReason.IdleEvicted &&
|
|
1198
|
+
this.options.beginInstanceIdleClosingAuthority !== undefined
|
|
1199
|
+
? (onCommitted) =>
|
|
1200
|
+
this.options.beginInstanceIdleClosingAuthority!(meshName, spotId, onCommitted)
|
|
1201
|
+
: async (onCommitted) => {
|
|
1202
|
+
onCommitted();
|
|
1203
|
+
return { release: async () => undefined };
|
|
1204
|
+
});
|
|
1205
|
+
operation = {
|
|
1206
|
+
activation,
|
|
1207
|
+
reason,
|
|
1208
|
+
beginAuthority
|
|
1209
|
+
};
|
|
1210
|
+
if (reason === ZLinkSpotCloseReason.ExplicitClose) {
|
|
1211
|
+
operation.canExecuteApplication = (record) => {
|
|
1212
|
+
const context = record.context as
|
|
1213
|
+
import('./spot-serial-turn-executor').ZLinkSpotApplicationTurnContext | undefined;
|
|
1214
|
+
return context === undefined;
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
this.closeOperations.set(key, operation);
|
|
1168
1218
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
(target) => this.activationLifecycle.closeAfterSeal(target, seal, signal, reason, deadline),
|
|
1177
|
-
(target) => this.activationLifecycle.resourcesReleased(target),
|
|
1178
|
-
reason
|
|
1219
|
+
if (operation.ready === undefined) {
|
|
1220
|
+
const active = operation;
|
|
1221
|
+
const run = active.activation.serial.executeControlLifecycleOperation(
|
|
1222
|
+
() => this.runCloseOperation(meshName, spotId, active, signal, deadline),
|
|
1223
|
+
active.canExecuteApplication === undefined
|
|
1224
|
+
? undefined
|
|
1225
|
+
: (active as import('../execution/serial-execution-queue').ZLinkSerialLifecycleContext)
|
|
1179
1226
|
);
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1227
|
+
active.ready = run.finally(() => {
|
|
1228
|
+
active.ready = undefined;
|
|
1229
|
+
if (this.closeOperations.get(key) === active) {
|
|
1230
|
+
this.closeOperations.delete(key);
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
return await operation.ready!;
|
|
1235
|
+
}
|
|
1185
1236
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1237
|
+
private async runCloseOperation(
|
|
1238
|
+
meshName: string,
|
|
1239
|
+
spotId: RoutingId,
|
|
1240
|
+
operation: ZLinkTargetSpotCloseOperation,
|
|
1241
|
+
signal?: AbortSignal,
|
|
1242
|
+
deadline?: Date
|
|
1243
|
+
): Promise<boolean> {
|
|
1244
|
+
const seal = await this.beginCloseAuthority(meshName, spotId, operation, signal);
|
|
1245
|
+
if (seal === undefined) return false;
|
|
1246
|
+
if (seal !== true) {
|
|
1247
|
+
await this.activationLifecycle.sealForClose(operation.activation, seal);
|
|
1248
|
+
} else {
|
|
1249
|
+
await operation.activation.executionBarrier.waitForStartedTurns(signal);
|
|
1250
|
+
}
|
|
1251
|
+
const closingFailure = await this.activationLifecycle.cleanupClosedActivation(
|
|
1252
|
+
operation.activation,
|
|
1253
|
+
operation.reason,
|
|
1254
|
+
deadline
|
|
1255
|
+
);
|
|
1256
|
+
this.activations.finishClose(meshName, spotId);
|
|
1257
|
+
const intentRecords: unknown[] = [];
|
|
1258
|
+
operation.activation.serial.visitPendingApplication((record) => {
|
|
1259
|
+
const context = record.context as
|
|
1260
|
+
import('./spot-serial-turn-executor').ZLinkSpotApplicationTurnContext | undefined;
|
|
1261
|
+
if (context?.replay !== undefined) intentRecords.push(record);
|
|
1262
|
+
});
|
|
1263
|
+
const hasIntent = intentRecords.length > 0;
|
|
1264
|
+
// Spot messaging §7 step 3: with no Instance intent message waiting, the
|
|
1265
|
+
// release decision also ends this Instance incarnation's admission in this turn.
|
|
1266
|
+
if (!hasIntent && operation.activation.domain.kind === 'instance')
|
|
1267
|
+
operation.activation.serial.closeAdmission();
|
|
1268
|
+
const hostState = this.options.statefulExecution?.hostState();
|
|
1269
|
+
const intentFailure = !hasIntent
|
|
1270
|
+
? undefined
|
|
1271
|
+
: hostState === ZLinkFrameworkRuntimeState.Draining
|
|
1272
|
+
? createInternalFrameworkException(
|
|
1273
|
+
ZLinkFrameworkInternalErrorKind.RuntimeShutdown,
|
|
1274
|
+
'Instance intent cannot continue while the host is draining.'
|
|
1275
|
+
)
|
|
1276
|
+
: hostState === ZLinkFrameworkRuntimeState.Relocating ||
|
|
1277
|
+
hostState === ZLinkFrameworkRuntimeState.Relocated ||
|
|
1278
|
+
this.options.statefulExecution?.admissionOpen() === false ||
|
|
1279
|
+
(operation.activation.executionBarrier.isSealed &&
|
|
1280
|
+
!operation.activation.executionBarrier.isCloseSealed)
|
|
1281
|
+
? createInternalFrameworkException(
|
|
1282
|
+
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
1283
|
+
'Instance intent cannot continue on an unavailable or relocating owner.'
|
|
1284
|
+
)
|
|
1190
1285
|
: undefined;
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1286
|
+
if (
|
|
1287
|
+
operation.reason === ZLinkSpotCloseReason.ExplicitClose &&
|
|
1288
|
+
hasIntent &&
|
|
1289
|
+
intentFailure === undefined &&
|
|
1290
|
+
operation.authority?.reincarnate !== undefined
|
|
1291
|
+
) {
|
|
1292
|
+
try {
|
|
1293
|
+
await operation.authority.reincarnate(async (authority) => {
|
|
1294
|
+
await this.activationLifecycle.materializeInstance(
|
|
1295
|
+
meshName,
|
|
1296
|
+
authority.stableType,
|
|
1297
|
+
operation.activation.spotType as Type<ZLinkInstanceSpot>,
|
|
1298
|
+
spotId,
|
|
1299
|
+
authority.objectGeneration,
|
|
1300
|
+
signal,
|
|
1301
|
+
operation.activation
|
|
1302
|
+
);
|
|
1303
|
+
});
|
|
1304
|
+
// The new incarnation shares this serial owner and admits membership work again.
|
|
1305
|
+
operation.activation.serial.setLifecycleAdmissionClosed(false);
|
|
1306
|
+
} catch (error) {
|
|
1307
|
+
const initialized = this.activations.resolve(meshName, spotId);
|
|
1308
|
+
if (initialized !== undefined && initialized !== operation.activation) {
|
|
1309
|
+
await this.activationLifecycle.cleanupFailedIncarnation(initialized);
|
|
1215
1310
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1311
|
+
this.activations.finishClose(meshName, spotId);
|
|
1312
|
+
operation.activation.serial.visitPendingApplication((record) => {
|
|
1313
|
+
const context = record.context as
|
|
1314
|
+
import('./spot-serial-turn-executor').ZLinkSpotApplicationTurnContext | undefined;
|
|
1315
|
+
if (context?.replay !== undefined) record.operation = () => context.replay!(error);
|
|
1316
|
+
});
|
|
1317
|
+
operation.activation.serial.closeAdmission();
|
|
1318
|
+
throw error;
|
|
1319
|
+
}
|
|
1320
|
+
} else {
|
|
1321
|
+
await operation.authority?.release();
|
|
1322
|
+
operation.activation.serial.closeAdmission();
|
|
1323
|
+
if (!operation.activation.executionBarrier.isSealed) {
|
|
1324
|
+
const closed = operation.activation.sealExecution('close');
|
|
1325
|
+
operation.activation.commitExecutionSeal(closed);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
if (operation.reason === ZLinkSpotCloseReason.ExplicitClose) {
|
|
1329
|
+
operation.activation.serial.visitPendingApplication((record) => {
|
|
1330
|
+
const context = record.context as
|
|
1331
|
+
import('./spot-serial-turn-executor').ZLinkSpotApplicationTurnContext | undefined;
|
|
1332
|
+
if (context?.replay !== undefined) {
|
|
1333
|
+
record.operation =
|
|
1334
|
+
intentFailure === undefined ? context.replay : () => context.replay!(intentFailure);
|
|
1222
1335
|
}
|
|
1223
1336
|
});
|
|
1224
|
-
this.pendingInstanceCloses.set(key, trackedClosePromise);
|
|
1225
|
-
if (currentTurn) {
|
|
1226
|
-
// The current turn must return before its terminal completion can
|
|
1227
|
-
// release the activation recovery fence and allow the durable close
|
|
1228
|
-
// CAS. The registered close gate prevents a second admission while
|
|
1229
|
-
// that detached close finishes.
|
|
1230
|
-
this.options.detachedTaskRunner?.runDetached(
|
|
1231
|
-
`instance spot close ${String(spotId)}`,
|
|
1232
|
-
async () => {
|
|
1233
|
-
await trackedClosePromise;
|
|
1234
|
-
}
|
|
1235
|
-
);
|
|
1236
|
-
if (this.options.detachedTaskRunner === undefined) {
|
|
1237
|
-
void trackedClosePromise.catch(() => undefined);
|
|
1238
|
-
}
|
|
1239
|
-
return true;
|
|
1240
|
-
}
|
|
1241
|
-
return await trackedClosePromise;
|
|
1242
1337
|
}
|
|
1338
|
+
this.closeOperations.delete(`${meshName}\0${String(spotId)}`);
|
|
1339
|
+
// An OnClosing failure never changes a Close result; host shutdown alone
|
|
1340
|
+
// reports it as its teardown outcome after cleanup has finished.
|
|
1341
|
+
if (closingFailure !== undefined && operation.reason === ZLinkSpotCloseReason.HostShutdown) {
|
|
1342
|
+
throw closingFailure;
|
|
1343
|
+
}
|
|
1344
|
+
return true;
|
|
1345
|
+
}
|
|
1243
1346
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1347
|
+
private async beginCloseAuthority(
|
|
1348
|
+
meshName: string,
|
|
1349
|
+
spotId: RoutingId,
|
|
1350
|
+
operation: ZLinkTargetSpotCloseOperation,
|
|
1351
|
+
signal?: AbortSignal
|
|
1352
|
+
): Promise<import('../execution').ZLinkExecutionBarrierSeal | true | undefined> {
|
|
1353
|
+
// Spot messaging §4 step 12 with §7 step 1: a Close of any reason begins its
|
|
1354
|
+
// Closing CAS only after the first terminal record of an activated message.
|
|
1355
|
+
await this.options.instanceSpotApplicationQuiescenceProvider?.(meshName, spotId, signal);
|
|
1356
|
+
if (!operation.activation.canClose(operation.reason)) return undefined;
|
|
1357
|
+
if (operation.activation.executionBarrier.isSealed) {
|
|
1358
|
+
throw createInternalFrameworkException(
|
|
1359
|
+
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
1360
|
+
`Spot '${String(spotId)}' is sealed for relocation.`,
|
|
1361
|
+
true
|
|
1362
|
+
);
|
|
1247
1363
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1364
|
+
let seal: import('../execution').ZLinkExecutionBarrierSeal | true | undefined;
|
|
1365
|
+
const authorityPromise = Promise.resolve().then(() =>
|
|
1366
|
+
operation.beginAuthority(() => {
|
|
1367
|
+
if (operation.reason === ZLinkSpotCloseReason.ExplicitClose) {
|
|
1368
|
+
operation.activation.serial.setLifecycleAdmissionClosed(true);
|
|
1369
|
+
seal = true;
|
|
1370
|
+
} else {
|
|
1371
|
+
seal = operation.activation.sealExecution('close');
|
|
1255
1372
|
}
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1373
|
+
})
|
|
1374
|
+
);
|
|
1375
|
+
operation.authorityDecision = authorityPromise.then(
|
|
1376
|
+
() => undefined,
|
|
1377
|
+
() => undefined
|
|
1378
|
+
);
|
|
1379
|
+
const authority = await authorityPromise;
|
|
1380
|
+
if (authority === undefined) return undefined;
|
|
1381
|
+
operation.authority = authority;
|
|
1382
|
+
if (seal === undefined) {
|
|
1383
|
+
throw new Error(`Spot '${String(spotId)}' Closing authority did not confirm its commit.`);
|
|
1258
1384
|
}
|
|
1259
|
-
return
|
|
1385
|
+
return seal;
|
|
1260
1386
|
}
|
|
1261
1387
|
|
|
1262
1388
|
async executeOnSpot<TSpot extends ZLinkSpot, TResult>(
|
|
@@ -1286,10 +1412,6 @@ export class DefaultZLinkSpotManager {
|
|
|
1286
1412
|
return this.activations.resolveUnique(spotId) !== undefined;
|
|
1287
1413
|
}
|
|
1288
1414
|
|
|
1289
|
-
canCloseUserSpot(meshName: string, spotId: RoutingId): boolean {
|
|
1290
|
-
return this.activations.canClose(meshName, spotId);
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
1415
|
beginUserSpotPublication(meshName: string, spotId: RoutingId): void {
|
|
1294
1416
|
this.activations.stage(meshName, spotId);
|
|
1295
1417
|
}
|
|
@@ -1326,15 +1448,19 @@ export class DefaultZLinkSpotManager {
|
|
|
1326
1448
|
spotId: RoutingId,
|
|
1327
1449
|
actor: ZLinkActor,
|
|
1328
1450
|
request: Message,
|
|
1329
|
-
commit: (
|
|
1330
|
-
spot: ZLinkSpot
|
|
1331
|
-
) => Promise<ZLinkActorJoinRollback | void> | ZLinkActorJoinRollback | void,
|
|
1451
|
+
commit: (spot: ZLinkSpot) => Promise<void> | void,
|
|
1332
1452
|
signal?: AbortSignal,
|
|
1333
1453
|
leaveSource?: () => Promise<void>,
|
|
1334
1454
|
contentType = 'application/json'
|
|
1335
1455
|
): Promise<ZLinkSpotActorJoinResult> {
|
|
1336
1456
|
const meshName = this.activations.resolveUnique(spotId)?.meshName;
|
|
1337
1457
|
this.options.admission?.requireRequest('Actor join admission', meshName);
|
|
1458
|
+
if (meshName !== undefined && this.isSpotClosing(meshName, spotId)) {
|
|
1459
|
+
throw createInternalFrameworkException(
|
|
1460
|
+
ZLinkFrameworkInternalErrorKind.RequestRejected,
|
|
1461
|
+
`Spot '${String(spotId)}' is closing.`
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1338
1464
|
return await this.actorMembership.admitActorJoin(
|
|
1339
1465
|
spotId,
|
|
1340
1466
|
actor,
|
|
@@ -1562,14 +1688,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1562
1688
|
record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
|
|
1563
1689
|
);
|
|
1564
1690
|
} catch (error) {
|
|
1565
|
-
requireMeshSpotReply(
|
|
1566
|
-
record.reply(
|
|
1567
|
-
encodeChannelErrorReplyParts(
|
|
1568
|
-
envelope.header,
|
|
1569
|
-
error instanceof Error ? error.message : String(error)
|
|
1570
|
-
)
|
|
1571
|
-
)
|
|
1572
|
-
);
|
|
1691
|
+
requireMeshSpotReply(record.reply(encodeChannelErrorReplyParts(envelope.header, error)));
|
|
1573
1692
|
}
|
|
1574
1693
|
}
|
|
1575
1694
|
|
|
@@ -1580,7 +1699,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1580
1699
|
let target = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
|
|
1581
1700
|
if (target === undefined) return;
|
|
1582
1701
|
for (;;) {
|
|
1583
|
-
const current = this.
|
|
1702
|
+
const current = this.resolveApplicationActivation(spotId, meshName);
|
|
1584
1703
|
if (
|
|
1585
1704
|
current !== undefined &&
|
|
1586
1705
|
current.objectGeneration === target.objectGeneration &&
|
|
@@ -1634,7 +1753,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1634
1753
|
);
|
|
1635
1754
|
try {
|
|
1636
1755
|
await this.ensureInstanceApplicationActivation(meshName, spotId);
|
|
1637
|
-
const activation = this.
|
|
1756
|
+
const activation = this.resolveApplicationActivation(spotId, meshName);
|
|
1638
1757
|
if (activation === undefined || activation.domain.kind !== 'instance') {
|
|
1639
1758
|
throw new ZLinkConfigurationException(
|
|
1640
1759
|
`MeshNode Instance Spot target '${String(spotId)}' is not active.`
|
|
@@ -1659,12 +1778,39 @@ export class DefaultZLinkSpotManager {
|
|
|
1659
1778
|
channelName: envelope.header.channelName,
|
|
1660
1779
|
contentType: envelope.header.contentType,
|
|
1661
1780
|
awaitFirstHandlerTurn: record.kind === ReceiveKind.InstanceSpotActivation,
|
|
1781
|
+
activationRecord: record,
|
|
1782
|
+
onOneWayError:
|
|
1783
|
+
this.options.dispatchErrors?.captureEnabled() === true
|
|
1784
|
+
? (error: unknown) =>
|
|
1785
|
+
this.reportInstanceDispatchFailure(
|
|
1786
|
+
meshName,
|
|
1787
|
+
spotId,
|
|
1788
|
+
record,
|
|
1789
|
+
envelope,
|
|
1790
|
+
false,
|
|
1791
|
+
error
|
|
1792
|
+
)
|
|
1793
|
+
: undefined,
|
|
1662
1794
|
workOptions: zlinkSerialWorkOptions(
|
|
1663
1795
|
envelope.payload.byteLength,
|
|
1664
1796
|
record.applicationMetadata?.byteLength ??
|
|
1665
1797
|
zlinkMetadataByteLength(envelope.header.metadata)
|
|
1666
1798
|
)
|
|
1667
1799
|
};
|
|
1800
|
+
// Spot messaging §7 step 3: an Instance intent request that reaches an
|
|
1801
|
+
// incarnation whose Close ended admission is refused before admission
|
|
1802
|
+
// with the owner fence terminal, so its caller re-reads authority.
|
|
1803
|
+
const instanceIntent =
|
|
1804
|
+
record.activationRecord?.activation === 'missing' ||
|
|
1805
|
+
(record.activationRecord?.activation === 'ready' &&
|
|
1806
|
+
record.activationRecord.instanceIntent);
|
|
1807
|
+
const refusal = activation.serial.applicationAdmissionRefusal(instanceIntent === true);
|
|
1808
|
+
if (request && refusal !== undefined && record.replyFailure !== undefined) {
|
|
1809
|
+
this.reportInstanceDispatchFailure(meshName, spotId, record, envelope, request, refusal);
|
|
1810
|
+
const terminal = internalFrameworkWireReply(refusal);
|
|
1811
|
+
requireMeshSpotReply(record.replyFailure(terminal.terminalResult, terminal.failureCode));
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1668
1814
|
this.traceInstanceMessage(
|
|
1669
1815
|
ZLinkMessageFlowOutcome.Admitted,
|
|
1670
1816
|
meshName,
|
|
@@ -1729,7 +1875,8 @@ export class DefaultZLinkSpotManager {
|
|
|
1729
1875
|
target?.stableType
|
|
1730
1876
|
);
|
|
1731
1877
|
} catch (error) {
|
|
1732
|
-
|
|
1878
|
+
this.reportInstanceDispatchFailure(meshName, spotId, record, envelope, request, error);
|
|
1879
|
+
const reason = dispatchReasonFromError(error);
|
|
1733
1880
|
if (!request) {
|
|
1734
1881
|
this.traceInstanceMessage(
|
|
1735
1882
|
ZLinkMessageFlowOutcome.Dropped,
|
|
@@ -1743,36 +1890,42 @@ export class DefaultZLinkSpotManager {
|
|
|
1743
1890
|
);
|
|
1744
1891
|
return;
|
|
1745
1892
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
messageKind: ZLinkDispatchMessageKind.Request,
|
|
1749
|
-
packetName: envelope.packetName,
|
|
1750
|
-
channelName: envelope.header.channelName,
|
|
1751
|
-
meshName,
|
|
1752
|
-
correlationId: envelope.header.correlationId ?? undefined,
|
|
1753
|
-
sourceRid: record.sourceNodeRid === null ? undefined : String(record.sourceNodeRid),
|
|
1754
|
-
spotId: String(spotId),
|
|
1755
|
-
instanceSpotType: this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId)
|
|
1756
|
-
?.stableType,
|
|
1757
|
-
activationState: 'closing',
|
|
1758
|
-
flowId: envelope.header.flowId,
|
|
1759
|
-
flowOrigin: envelope.header.flowOrigin,
|
|
1760
|
-
reason,
|
|
1761
|
-
action: ZLinkDispatchErrorAction.ReplyError,
|
|
1762
|
-
error
|
|
1763
|
-
});
|
|
1764
|
-
requireMeshSpotReply(
|
|
1765
|
-
record.reply(
|
|
1766
|
-
encodeChannelErrorReplyParts(
|
|
1767
|
-
envelope.header,
|
|
1768
|
-
error instanceof Error ? error.message : String(error)
|
|
1769
|
-
)
|
|
1770
|
-
)
|
|
1771
|
-
);
|
|
1893
|
+
|
|
1894
|
+
requireMeshSpotReply(record.reply(encodeChannelErrorReplyParts(envelope.header, error)));
|
|
1772
1895
|
}
|
|
1773
1896
|
});
|
|
1774
1897
|
}
|
|
1775
1898
|
|
|
1899
|
+
private reportInstanceDispatchFailure(
|
|
1900
|
+
meshName: string,
|
|
1901
|
+
spotId: RoutingId,
|
|
1902
|
+
record: ReceiveRecord,
|
|
1903
|
+
envelope: ReturnType<typeof decodeChannelEnvelope>,
|
|
1904
|
+
request: boolean,
|
|
1905
|
+
error: unknown
|
|
1906
|
+
): void {
|
|
1907
|
+
const reporter = this.options.dispatchErrors;
|
|
1908
|
+
if (reporter?.captureEnabled() !== true) return;
|
|
1909
|
+
reporter.report({
|
|
1910
|
+
surface: ZLinkDispatchErrorSurface.InstanceSpot,
|
|
1911
|
+
messageKind: request ? ZLinkDispatchMessageKind.Request : ZLinkDispatchMessageKind.Send,
|
|
1912
|
+
packetName: envelope.packetName,
|
|
1913
|
+
channelName: envelope.header.channelName,
|
|
1914
|
+
meshName,
|
|
1915
|
+
correlationId: envelope.header.correlationId ?? undefined,
|
|
1916
|
+
sourceRid: record.sourceNodeRid === null ? undefined : String(record.sourceNodeRid),
|
|
1917
|
+
spotId: String(spotId),
|
|
1918
|
+
instanceSpotType: this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId)
|
|
1919
|
+
?.stableType,
|
|
1920
|
+
activationState: 'closing',
|
|
1921
|
+
flowId: envelope.header.flowId,
|
|
1922
|
+
flowOrigin: envelope.header.flowOrigin,
|
|
1923
|
+
reason: dispatchReasonFromError(error),
|
|
1924
|
+
action: request ? ZLinkDispatchErrorAction.ReplyError : ZLinkDispatchErrorAction.Drop,
|
|
1925
|
+
error
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1776
1929
|
private traceInstanceMessage(
|
|
1777
1930
|
outcome: ZLinkMessageFlowOutcome,
|
|
1778
1931
|
meshName: string,
|
|
@@ -1825,9 +1978,6 @@ export class DefaultZLinkSpotManager {
|
|
|
1825
1978
|
throw new ZLinkConfigurationException('MeshNode Actor record is missing its Actor owner.');
|
|
1826
1979
|
}
|
|
1827
1980
|
const request = record.kind === ReceiveKind.ActorRequest;
|
|
1828
|
-
if (record.sourceBindingGeneration > 0n) {
|
|
1829
|
-
this.options.actorBindingGenerationObserver?.(actor.actorId, record.sourceBindingGeneration);
|
|
1830
|
-
}
|
|
1831
1981
|
const resolvedOwner = this.options.actorDispatchOwnerResolver?.(actor.actorId);
|
|
1832
1982
|
const resolvedActorRef = resolvedOwner?.actorRef ?? {
|
|
1833
1983
|
actorId: actor.actorId,
|
|
@@ -1918,10 +2068,7 @@ export class DefaultZLinkSpotManager {
|
|
|
1918
2068
|
record.reply(
|
|
1919
2069
|
this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Error, {
|
|
1920
2070
|
message: error instanceof Error ? error.message : String(error),
|
|
1921
|
-
kind:
|
|
1922
|
-
error instanceof ZLinkFrameworkException
|
|
1923
|
-
? error.kind
|
|
1924
|
-
: ZLinkFrameworkErrorKind.InternalFailure
|
|
2071
|
+
kind: spotActorFailureKind(error)
|
|
1925
2072
|
})
|
|
1926
2073
|
)
|
|
1927
2074
|
);
|
|
@@ -1932,6 +2079,54 @@ export class DefaultZLinkSpotManager {
|
|
|
1932
2079
|
meshName: string,
|
|
1933
2080
|
owner: ReadyRecord,
|
|
1934
2081
|
record: ReceiveRecord
|
|
2082
|
+
): Promise<void> {
|
|
2083
|
+
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
2084
|
+
const activation = spotId === null ? undefined : this.activations.resolve(meshName, spotId);
|
|
2085
|
+
const replyState = { targetCommitPublished: false };
|
|
2086
|
+
try {
|
|
2087
|
+
if (
|
|
2088
|
+
record.kindData?.kind === 'actorControl' &&
|
|
2089
|
+
record.kindData.canonicalActorJoin !== undefined
|
|
2090
|
+
) {
|
|
2091
|
+
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
2092
|
+
if (
|
|
2093
|
+
spotId !== null && entrySpotId !== undefined && String(spotId) === String(entrySpotId)
|
|
2094
|
+
? this.options.dispatchEntryActorJoin === undefined
|
|
2095
|
+
: activation === undefined
|
|
2096
|
+
) {
|
|
2097
|
+
throw createInternalFrameworkException(
|
|
2098
|
+
ZLinkFrameworkInternalErrorKind.RouteNotConnected,
|
|
2099
|
+
`Spot '${String(spotId)}' is not active on this node.`
|
|
2100
|
+
);
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
if (activation?.domain.kind === 'user') {
|
|
2104
|
+
await activation.serial.executeLifecycleOperation(() =>
|
|
2105
|
+
this.dispatchMeshActorJoinCore(meshName, owner, record, replyState)
|
|
2106
|
+
);
|
|
2107
|
+
return;
|
|
2108
|
+
}
|
|
2109
|
+
await this.dispatchMeshActorJoinCore(meshName, owner, record, replyState);
|
|
2110
|
+
} catch (error) {
|
|
2111
|
+
if (replyState.targetCommitPublished || record.replyFailure === undefined) throw error;
|
|
2112
|
+
const failure =
|
|
2113
|
+
error instanceof ZLinkFrameworkException
|
|
2114
|
+
? error
|
|
2115
|
+
: createInternalFrameworkException(
|
|
2116
|
+
ZLinkFrameworkInternalErrorKind.RequestFailed,
|
|
2117
|
+
'Actor Join target admission failed.',
|
|
2118
|
+
error
|
|
2119
|
+
);
|
|
2120
|
+
const terminal = internalFrameworkWireReply(failure);
|
|
2121
|
+
requireMeshSpotReply(record.replyFailure(terminal.terminalResult, terminal.failureCode));
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
private async dispatchMeshActorJoinCore(
|
|
2126
|
+
meshName: string,
|
|
2127
|
+
owner: ReadyRecord,
|
|
2128
|
+
record: ReceiveRecord,
|
|
2129
|
+
replyState: { targetCommitPublished: boolean }
|
|
1935
2130
|
): Promise<void> {
|
|
1936
2131
|
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
1937
2132
|
const control = record.kindData;
|
|
@@ -1996,14 +2191,10 @@ export class DefaultZLinkSpotManager {
|
|
|
1996
2191
|
admissionRecord = provisional.record;
|
|
1997
2192
|
canonicalAdmissionCreated = provisional.created;
|
|
1998
2193
|
try {
|
|
2194
|
+
releaseApplicationJobPermitBeforeHandler();
|
|
1999
2195
|
canonicalActorType = (await resolver({ actorId, ...control.canonicalActorJoin })).actorType;
|
|
2000
2196
|
} catch (error) {
|
|
2001
2197
|
this.formalRemoteActorAdmissions.fail(control.canonicalActorJoin.handoffId, error);
|
|
2002
|
-
if (error instanceof ZLinkFrameworkException && record.replyFailure !== undefined) {
|
|
2003
|
-
const terminal = internalFrameworkWireReply(error);
|
|
2004
|
-
requireMeshSpotReply(record.replyFailure(terminal.terminalResult, terminal.failureCode));
|
|
2005
|
-
return;
|
|
2006
|
-
}
|
|
2007
2198
|
throw error;
|
|
2008
2199
|
}
|
|
2009
2200
|
}
|
|
@@ -2027,12 +2218,11 @@ export class DefaultZLinkSpotManager {
|
|
|
2027
2218
|
let ownedCallbackRequest: Message | undefined;
|
|
2028
2219
|
let materialized = false;
|
|
2029
2220
|
let reply: Message | undefined;
|
|
2030
|
-
let
|
|
2221
|
+
let deferredJoinCompletion: ZLinkDeferredJoinCompletion | undefined;
|
|
2031
2222
|
let preparedTransferState: Message | undefined;
|
|
2032
2223
|
let admissionOutcome: ZLinkFormalRemoteActorAdmissionResult | undefined;
|
|
2033
2224
|
let accepted = false;
|
|
2034
2225
|
let committedAdmissionReplay = isRemoteCommit && admissionRecord?.state === 'committed';
|
|
2035
|
-
let targetCommitPublished: boolean | undefined;
|
|
2036
2226
|
const actorJoinIsCurrent = (): boolean =>
|
|
2037
2227
|
(record.deadlineUnixMs === undefined || record.deadlineUnixMs > BigInt(Date.now())) &&
|
|
2038
2228
|
(record.isPending?.() ?? true);
|
|
@@ -2093,14 +2283,12 @@ export class DefaultZLinkSpotManager {
|
|
|
2093
2283
|
if (canonicalAdmissionCreated) {
|
|
2094
2284
|
if (targetsEntrySpot) {
|
|
2095
2285
|
admissionOutcome = {
|
|
2096
|
-
accepted:
|
|
2286
|
+
accepted: true,
|
|
2097
2287
|
actorRef
|
|
2098
2288
|
};
|
|
2099
|
-
} else if (activation === undefined) {
|
|
2100
|
-
admissionOutcome = { accepted: false, actorRef };
|
|
2101
2289
|
} else {
|
|
2102
|
-
const response: ZLinkSpotActorJoinResult = await activation
|
|
2103
|
-
activation
|
|
2290
|
+
const response: ZLinkSpotActorJoinResult = await activation!.serial.execute(async () =>
|
|
2291
|
+
activation!.spot.onActorJoin(
|
|
2104
2292
|
actorRef.actorId,
|
|
2105
2293
|
wrapFrameworkPayloadMessage(
|
|
2106
2294
|
callbackRequest!,
|
|
@@ -2176,8 +2364,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2176
2364
|
transferRequest.completionOperationId !== undefined &&
|
|
2177
2365
|
this.options.actorTransferRuntime !== undefined
|
|
2178
2366
|
) {
|
|
2179
|
-
|
|
2180
|
-
|
|
2367
|
+
deferredJoinCompletion =
|
|
2368
|
+
this.options.actorTransferRuntime.prepareDeferredJoinAccepted(
|
|
2181
2369
|
actorId,
|
|
2182
2370
|
transferRequest.completionOperationId,
|
|
2183
2371
|
actorRef,
|
|
@@ -2187,7 +2375,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2187
2375
|
admissionOutcome = {
|
|
2188
2376
|
accepted: this.options.dispatchEntryActorJoin !== undefined,
|
|
2189
2377
|
actorRef,
|
|
2190
|
-
...(
|
|
2378
|
+
...(deferredJoinCompletion === undefined ? {} : { deferredJoinCompletion })
|
|
2191
2379
|
};
|
|
2192
2380
|
} else if (activation === undefined) {
|
|
2193
2381
|
admissionOutcome = { accepted: false, actorRef };
|
|
@@ -2220,8 +2408,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2220
2408
|
transferRequest.completionOperationId !== undefined &&
|
|
2221
2409
|
this.options.actorTransferRuntime !== undefined
|
|
2222
2410
|
) {
|
|
2223
|
-
|
|
2224
|
-
|
|
2411
|
+
deferredJoinCompletion =
|
|
2412
|
+
this.options.actorTransferRuntime.prepareDeferredJoinAccepted(
|
|
2225
2413
|
actorId,
|
|
2226
2414
|
transferRequest.completionOperationId,
|
|
2227
2415
|
actorRef,
|
|
@@ -2240,7 +2428,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2240
2428
|
admissionOutcome = {
|
|
2241
2429
|
accepted: response.accepted,
|
|
2242
2430
|
actorRef,
|
|
2243
|
-
...(
|
|
2431
|
+
...(deferredJoinCompletion === undefined ? {} : { deferredJoinCompletion }),
|
|
2244
2432
|
...(encodedReply === undefined
|
|
2245
2433
|
? {}
|
|
2246
2434
|
: {
|
|
@@ -2277,7 +2465,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2277
2465
|
if ('error' in admissionOutcome) {
|
|
2278
2466
|
throw admissionOutcome.error;
|
|
2279
2467
|
}
|
|
2280
|
-
|
|
2468
|
+
deferredJoinCompletion = admissionOutcome.deferredJoinCompletion;
|
|
2281
2469
|
}
|
|
2282
2470
|
if (
|
|
2283
2471
|
actor === undefined &&
|
|
@@ -2361,7 +2549,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2361
2549
|
transferRequest?.completionOperationId !== undefined &&
|
|
2362
2550
|
this.options.actorTransferRuntime !== undefined
|
|
2363
2551
|
) {
|
|
2364
|
-
|
|
2552
|
+
deferredJoinCompletion = this.options.actorTransferRuntime.prepareDeferredJoinAccepted(
|
|
2365
2553
|
actorId,
|
|
2366
2554
|
transferRequest.completionOperationId,
|
|
2367
2555
|
actorRef,
|
|
@@ -2424,21 +2612,6 @@ export class DefaultZLinkSpotManager {
|
|
|
2424
2612
|
return;
|
|
2425
2613
|
}
|
|
2426
2614
|
}
|
|
2427
|
-
if (
|
|
2428
|
-
accepted &&
|
|
2429
|
-
transferRequest !== undefined &&
|
|
2430
|
-
this.options.actorTransferRuntime !== undefined &&
|
|
2431
|
-
!isRemoteAdmission
|
|
2432
|
-
) {
|
|
2433
|
-
// A lightweight Core actor-join notification can create the Actor
|
|
2434
|
-
// before the formal transfer request reaches this branch. Preserve
|
|
2435
|
-
// the full relocation fence in that race so a later Session bind
|
|
2436
|
-
// refresh cannot erase the seal or accepted journal.
|
|
2437
|
-
this.options.actorTransferRuntime.rememberRoutedActorTransferTarget(
|
|
2438
|
-
actorId,
|
|
2439
|
-
transferRequest.remoteBoundSessionTarget
|
|
2440
|
-
);
|
|
2441
|
-
}
|
|
2442
2615
|
if (
|
|
2443
2616
|
accepted &&
|
|
2444
2617
|
actor !== undefined &&
|
|
@@ -2451,7 +2624,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2451
2624
|
spotId,
|
|
2452
2625
|
transferId: transferRequest.transferId,
|
|
2453
2626
|
handoffBacklog: transferRequest.handoffBacklog,
|
|
2454
|
-
|
|
2627
|
+
deferredJoinCompletion,
|
|
2628
|
+
sealedSession: transferRequest.remoteBoundSessionTarget
|
|
2455
2629
|
});
|
|
2456
2630
|
if (isRemoteCommit && admissionRecord !== undefined) {
|
|
2457
2631
|
this.formalRemoteActorAdmissions.markCommitted(transferRequest.transferId, actor);
|
|
@@ -2471,7 +2645,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2471
2645
|
// Core commits the target membership while it accepts this reply.
|
|
2472
2646
|
// From this call onward a later callback/transport failure is
|
|
2473
2647
|
// post-commit and must not roll the materialized Actor back.
|
|
2474
|
-
targetCommitPublished = true;
|
|
2648
|
+
replyState.targetCommitPublished = true;
|
|
2475
2649
|
}
|
|
2476
2650
|
requireMeshSpotReply(joinReplyResult);
|
|
2477
2651
|
return true;
|
|
@@ -2496,60 +2670,85 @@ export class DefaultZLinkSpotManager {
|
|
|
2496
2670
|
if (!replyActorJoin()) return;
|
|
2497
2671
|
const commitEntryTransfer = async (): Promise<void> => {
|
|
2498
2672
|
try {
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
pendingTransfer.transferId
|
|
2504
|
-
);
|
|
2505
|
-
}
|
|
2506
|
-
const sourceLeaveSubmitted = await pendingTransfer.sourceLeaveSubmitted;
|
|
2507
|
-
if (!sourceLeaveSubmitted) {
|
|
2508
|
-
throw new Error(
|
|
2509
|
-
`Actor '${entryActor.context.actorId}' source authority commit failed before leave submission.`
|
|
2510
|
-
);
|
|
2511
|
-
}
|
|
2512
|
-
const handoffResults = await replayActorHandoffBacklog(
|
|
2513
|
-
pendingTransfer.handoffBacklog,
|
|
2514
|
-
async (parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) => {
|
|
2515
|
-
if (this.options.dispatchEntryActorPacket === undefined) {
|
|
2516
|
-
throw new Error(
|
|
2517
|
-
'Entry Spot saved handoff replay requires its Actor packet runtime.'
|
|
2518
|
-
);
|
|
2519
|
-
}
|
|
2520
|
-
return await this.options.dispatchEntryActorPacket(
|
|
2673
|
+
try {
|
|
2674
|
+
await this.options.dispatchEntryActorJoin?.(meshName, entryActor, []);
|
|
2675
|
+
} finally {
|
|
2676
|
+
this.formalRemoteTransfers.completeTargetLifecycle(
|
|
2521
2677
|
entryActor.context.actorId,
|
|
2522
|
-
|
|
2523
|
-
returnResponse,
|
|
2524
|
-
remoteBoundSessionTarget,
|
|
2525
|
-
fallbackActorRef
|
|
2678
|
+
pendingTransfer.transferId
|
|
2526
2679
|
);
|
|
2527
|
-
}
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2680
|
+
}
|
|
2681
|
+
const sourceLeaveSubmitted = await pendingTransfer.sourceLeaveSubmitted;
|
|
2682
|
+
if (!sourceLeaveSubmitted) {
|
|
2683
|
+
throw new Error(
|
|
2684
|
+
`Actor '${entryActor.context.actorId}' source authority commit failed before leave submission.`
|
|
2685
|
+
);
|
|
2686
|
+
}
|
|
2687
|
+
const handoffResults = await replayActorHandoffBacklog(
|
|
2688
|
+
pendingTransfer.handoffBacklog,
|
|
2689
|
+
async (parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) => {
|
|
2690
|
+
if (this.options.dispatchEntryActorPacket === undefined) {
|
|
2691
|
+
throw new Error(
|
|
2692
|
+
'Entry Spot saved handoff replay requires its Actor packet runtime.'
|
|
2693
|
+
);
|
|
2694
|
+
}
|
|
2695
|
+
return await this.options.dispatchEntryActorPacket(
|
|
2696
|
+
entryActor.context.actorId,
|
|
2697
|
+
parts,
|
|
2698
|
+
returnResponse,
|
|
2699
|
+
remoteBoundSessionTarget,
|
|
2700
|
+
fallbackActorRef
|
|
2701
|
+
);
|
|
2702
|
+
},
|
|
2703
|
+
(index) =>
|
|
2704
|
+
this.options.runtimeEventPublisher?.publish({
|
|
2705
|
+
sourceName: 'zlink.framework.actor-handoff',
|
|
2706
|
+
timestamp: new Date(),
|
|
2707
|
+
marker: 'backlog_enqueued',
|
|
2708
|
+
actorId: entryActor.context.actorId,
|
|
2709
|
+
index
|
|
2710
|
+
})
|
|
2711
|
+
);
|
|
2712
|
+
const failedHandoff = handoffResults.find((result) => !result.ok);
|
|
2713
|
+
if (failedHandoff !== undefined) {
|
|
2714
|
+
throw new Error(
|
|
2715
|
+
`Actor '${entryActor.context.actorId}' saved Entry handoff packet ` +
|
|
2716
|
+
`${failedHandoff.index} failed: ${diagnosticTextOrAbsent(failedHandoff.error)}.`
|
|
2717
|
+
);
|
|
2718
|
+
}
|
|
2719
|
+
} catch (error) {
|
|
2720
|
+
const completion = pendingTransfer.deferredJoinCompletion;
|
|
2721
|
+
if (completion !== undefined) {
|
|
2722
|
+
await this.options.actorTransferRuntime?.deliverDeferredJoinCompletion(
|
|
2723
|
+
{
|
|
2724
|
+
...completion,
|
|
2725
|
+
status: 'failed',
|
|
2726
|
+
kind: spotActorFailureKind(error)
|
|
2727
|
+
},
|
|
2728
|
+
entryActor,
|
|
2729
|
+
completion.actor,
|
|
2730
|
+
(operation) =>
|
|
2731
|
+
this.options.executeEntryActor!(meshName, entryActor.context.actorId, operation)
|
|
2732
|
+
);
|
|
2733
|
+
}
|
|
2734
|
+
throw error;
|
|
2735
|
+
}
|
|
2736
|
+
const completion = pendingTransfer.deferredJoinCompletion;
|
|
2737
|
+
if (completion !== undefined) {
|
|
2738
|
+
await this.options.actorTransferRuntime?.deliverDeferredJoinCompletion(
|
|
2739
|
+
completion,
|
|
2740
|
+
entryActor,
|
|
2741
|
+
completion.actor,
|
|
2742
|
+
(operation) =>
|
|
2743
|
+
this.options.executeEntryActor!(meshName, entryActor.context.actorId, operation)
|
|
2542
2744
|
);
|
|
2543
2745
|
}
|
|
2544
2746
|
this.formalRemoteTransfers.delete(entryActor.context.actorId);
|
|
2545
2747
|
};
|
|
2546
|
-
this.options.detachedTaskRunner
|
|
2748
|
+
this.options.detachedTaskRunner.runDetached(
|
|
2547
2749
|
`actor Entry Spot transfer ${entryActor.context.actorId}`,
|
|
2548
2750
|
commitEntryTransfer
|
|
2549
2751
|
);
|
|
2550
|
-
if (this.options.detachedTaskRunner === undefined) {
|
|
2551
|
-
void commitEntryTransfer().catch(() => undefined);
|
|
2552
|
-
}
|
|
2553
2752
|
}
|
|
2554
2753
|
} else {
|
|
2555
2754
|
if (!replyActorJoin()) return;
|
|
@@ -2558,13 +2757,10 @@ export class DefaultZLinkSpotManager {
|
|
|
2558
2757
|
if (control.canonicalActorJoin !== undefined) {
|
|
2559
2758
|
this.formalRemoteActorAdmissions.fail(control.canonicalActorJoin.handoffId, error);
|
|
2560
2759
|
}
|
|
2561
|
-
if (
|
|
2562
|
-
await this.options.actorTransferRuntime?.discardDeferredJoinAccepted(deferredJoinRoot);
|
|
2563
|
-
}
|
|
2564
|
-
if (targetCommitPublished !== true) {
|
|
2760
|
+
if (!replyState.targetCommitPublished) {
|
|
2565
2761
|
this.formalRemoteTransfers.delete(actorId);
|
|
2566
2762
|
}
|
|
2567
|
-
if (materialized && targetCommitPublished
|
|
2763
|
+
if (materialized && !replyState.targetCommitPublished) {
|
|
2568
2764
|
await this.options.actorTransferRuntime?.rollbackRoutedActor(actor!);
|
|
2569
2765
|
}
|
|
2570
2766
|
throw error;
|
|
@@ -2580,6 +2776,42 @@ export class DefaultZLinkSpotManager {
|
|
|
2580
2776
|
meshName: string,
|
|
2581
2777
|
owner: ReadyRecord,
|
|
2582
2778
|
record: ReceiveRecord
|
|
2779
|
+
): Promise<void> {
|
|
2780
|
+
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
2781
|
+
const activation = spotId === null ? undefined : this.activations.resolve(meshName, spotId);
|
|
2782
|
+
if (activation?.domain.kind === 'user') {
|
|
2783
|
+
const transfer = { terminal: undefined as Promise<void> | undefined };
|
|
2784
|
+
const operation = activation.serial.executeLifecycleOperation(async () => {
|
|
2785
|
+
await this.dispatchMeshSpotControlCore(meshName, owner, record, (terminal) => {
|
|
2786
|
+
transfer.terminal = terminal;
|
|
2787
|
+
});
|
|
2788
|
+
await transfer.terminal;
|
|
2789
|
+
});
|
|
2790
|
+
const control = record.kindData;
|
|
2791
|
+
const actorId = control?.kind === 'actorControl' ? control.currentActor?.actorId : undefined;
|
|
2792
|
+
if (
|
|
2793
|
+
control?.kind === 'actorControl' &&
|
|
2794
|
+
control.lifecycleKind === ActorLifecycleKind.Joined &&
|
|
2795
|
+
actorId !== undefined &&
|
|
2796
|
+
this.formalRemoteTransfers.get(actorId) !== undefined
|
|
2797
|
+
) {
|
|
2798
|
+
this.options.detachedTaskRunner.runDetached(
|
|
2799
|
+
`actor transfer target commit ${actorId}`,
|
|
2800
|
+
async () => await operation
|
|
2801
|
+
);
|
|
2802
|
+
return;
|
|
2803
|
+
}
|
|
2804
|
+
await operation;
|
|
2805
|
+
return;
|
|
2806
|
+
}
|
|
2807
|
+
await this.dispatchMeshSpotControlCore(meshName, owner, record);
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
private async dispatchMeshSpotControlCore(
|
|
2811
|
+
meshName: string,
|
|
2812
|
+
owner: ReadyRecord,
|
|
2813
|
+
record: ReceiveRecord,
|
|
2814
|
+
onDetachedTerminal?: (terminal: Promise<void>) => void
|
|
2583
2815
|
): Promise<void> {
|
|
2584
2816
|
const spotId = owner.spotId as unknown as RoutingId | null;
|
|
2585
2817
|
const control = record.kindData;
|
|
@@ -2664,8 +2896,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2664
2896
|
await activation.spot.onJoinedActor(actor);
|
|
2665
2897
|
};
|
|
2666
2898
|
const completePublicJoin = async (): Promise<void> => {
|
|
2667
|
-
const
|
|
2668
|
-
if (
|
|
2899
|
+
const deferredJoinCompletion = pendingTransfer?.deferredJoinCompletion;
|
|
2900
|
+
if (deferredJoinCompletion !== undefined) {
|
|
2669
2901
|
const currentRef =
|
|
2670
2902
|
this.options.actorTransferRuntime === undefined
|
|
2671
2903
|
? null
|
|
@@ -2675,8 +2907,8 @@ export class DefaultZLinkSpotManager {
|
|
|
2675
2907
|
`Actor '${actor.context.actorId}' has no target ref for deferred Join completion.`
|
|
2676
2908
|
);
|
|
2677
2909
|
}
|
|
2678
|
-
await this.options.actorTransferRuntime?.
|
|
2679
|
-
|
|
2910
|
+
await this.options.actorTransferRuntime?.deliverDeferredJoinCompletion(
|
|
2911
|
+
deferredJoinCompletion,
|
|
2680
2912
|
actor,
|
|
2681
2913
|
currentRef,
|
|
2682
2914
|
(operation) =>
|
|
@@ -2710,7 +2942,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2710
2942
|
if (failedHandoff !== undefined) {
|
|
2711
2943
|
throw new Error(
|
|
2712
2944
|
`Actor '${actor.context.actorId}' saved handoff packet ` +
|
|
2713
|
-
`${failedHandoff.index} failed: ${failedHandoff.error
|
|
2945
|
+
`${failedHandoff.index} failed: ${diagnosticTextOrAbsent(failedHandoff.error)}.`
|
|
2714
2946
|
);
|
|
2715
2947
|
}
|
|
2716
2948
|
// Spec 15 §4.2 relocation temporary queue: arrivals parked at
|
|
@@ -2724,13 +2956,17 @@ export class DefaultZLinkSpotManager {
|
|
|
2724
2956
|
// the Session binding aggregate after this boundary.
|
|
2725
2957
|
this.formalRemoteTransfers.delete(actor.context.actorId);
|
|
2726
2958
|
}
|
|
2959
|
+
const sealedSession = pendingTransfer?.sealedSession;
|
|
2727
2960
|
const updateBoundSessionRoute = async (): Promise<void> => {
|
|
2728
|
-
await this.options.actorTransferRuntime?.publishRoutedActorOwnership(
|
|
2961
|
+
await this.options.actorTransferRuntime?.publishRoutedActorOwnership(
|
|
2962
|
+
actor,
|
|
2963
|
+
sealedSession
|
|
2964
|
+
);
|
|
2729
2965
|
await this.options.actorTransferRuntime?.openRoutedActorSession(actor);
|
|
2730
2966
|
};
|
|
2731
|
-
// Session routing is an independent post-Ready branch.
|
|
2732
|
-
//
|
|
2733
|
-
if (pendingTransfer !== undefined
|
|
2967
|
+
// Session routing is an independent post-Ready branch. The Session
|
|
2968
|
+
// owner submits current-binding pushes while the route seal remains installed.
|
|
2969
|
+
if (pendingTransfer !== undefined) {
|
|
2734
2970
|
this.options.detachedTaskRunner.runDetached(
|
|
2735
2971
|
`actor transfer Session route ${actor.context.actorId}`,
|
|
2736
2972
|
updateBoundSessionRoute
|
|
@@ -2760,12 +2996,14 @@ export class DefaultZLinkSpotManager {
|
|
|
2760
2996
|
// them only after the lifecycle turn above has been released.
|
|
2761
2997
|
await completeTargetReady();
|
|
2762
2998
|
};
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2999
|
+
const terminal = resume();
|
|
3000
|
+
if (onDetachedTerminal !== undefined) {
|
|
3001
|
+
onDetachedTerminal(terminal);
|
|
3002
|
+
} else {
|
|
3003
|
+
this.options.detachedTaskRunner.runDetached(
|
|
3004
|
+
`actor transfer target commit ${actor.context.actorId}`,
|
|
3005
|
+
async () => await terminal
|
|
3006
|
+
);
|
|
2769
3007
|
}
|
|
2770
3008
|
return;
|
|
2771
3009
|
}
|
|
@@ -2832,43 +3070,64 @@ export class DefaultZLinkSpotManager {
|
|
|
2832
3070
|
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
2833
3071
|
const targetsEntry =
|
|
2834
3072
|
entrySpotId !== undefined && String(admission.admission.spotId) === String(entrySpotId);
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
3073
|
+
const activation = targetsEntry
|
|
3074
|
+
? undefined
|
|
3075
|
+
: this.activations.resolve(meshName, admission.admission.spotId);
|
|
3076
|
+
let lifecycleFailure: { readonly error: unknown } | undefined;
|
|
3077
|
+
try {
|
|
3078
|
+
if (targetsEntry) {
|
|
3079
|
+
await this.options.dispatchEntryActorJoin?.(meshName, actor, []);
|
|
3080
|
+
} else {
|
|
3081
|
+
if (activation === undefined) {
|
|
3082
|
+
throw new Error(`Actor Join relocation '${relocationId}' target Spot is not active.`);
|
|
3083
|
+
}
|
|
3084
|
+
await activation.serial.execute(() => activation.spot.onJoinedActor(actor));
|
|
2841
3085
|
}
|
|
2842
|
-
|
|
3086
|
+
} catch (error) {
|
|
3087
|
+
lifecycleFailure = { error };
|
|
2843
3088
|
}
|
|
2844
|
-
|
|
2845
|
-
|
|
3089
|
+
if (lifecycleFailure === undefined) {
|
|
3090
|
+
const sourceLeave = submitSourceLeave(admission.admission.actorRef.nodeRid);
|
|
3091
|
+
this.options.detachedTaskRunner.runDetached(
|
|
3092
|
+
`actor Join source leave ${actor.context.actorId}`,
|
|
3093
|
+
() => sourceLeave
|
|
3094
|
+
);
|
|
3095
|
+
}
|
|
3096
|
+
if (
|
|
3097
|
+
outcome.deferredJoinCompletion !== undefined &&
|
|
3098
|
+
this.options.actorTransferRuntime !== undefined
|
|
3099
|
+
) {
|
|
2846
3100
|
const submitMailbox = targetsEntry
|
|
2847
3101
|
? <T>(operation: () => Promise<T>): Promise<T> => operation()
|
|
2848
3102
|
: <T>(operation: () => Promise<T>): Promise<T> => {
|
|
2849
|
-
const activation = this.activations.resolve(meshName, admission.admission.spotId);
|
|
2850
3103
|
if (activation === undefined) {
|
|
2851
3104
|
throw new Error(`Actor Join relocation '${relocationId}' target mailbox is missing.`);
|
|
2852
3105
|
}
|
|
2853
3106
|
return activation.executeActor(actor.context.actorId, operation);
|
|
2854
3107
|
};
|
|
2855
|
-
await this.options.actorTransferRuntime.
|
|
2856
|
-
|
|
3108
|
+
await this.options.actorTransferRuntime.deliverDeferredJoinCompletion(
|
|
3109
|
+
lifecycleFailure === undefined
|
|
3110
|
+
? outcome.deferredJoinCompletion
|
|
3111
|
+
: {
|
|
3112
|
+
...outcome.deferredJoinCompletion,
|
|
3113
|
+
status: 'failed',
|
|
3114
|
+
kind: spotActorFailureKind(lifecycleFailure.error)
|
|
3115
|
+
},
|
|
2857
3116
|
actor,
|
|
2858
3117
|
actorRef,
|
|
2859
3118
|
submitMailbox,
|
|
2860
3119
|
signal
|
|
2861
3120
|
);
|
|
2862
3121
|
}
|
|
3122
|
+
if (lifecycleFailure !== undefined) throw lifecycleFailure.error;
|
|
2863
3123
|
this.formalRemoteActorAdmissions.markCommitted(relocationId, actor);
|
|
2864
3124
|
return true;
|
|
2865
3125
|
}
|
|
2866
3126
|
|
|
2867
3127
|
async restoreCanonicalActorJoinRecovery(
|
|
2868
3128
|
recovery: CanonicalActorJoinRecovery,
|
|
2869
|
-
signal?: AbortSignal
|
|
2870
|
-
|
|
2871
|
-
): Promise<ZLinkDeferredJoinAcceptedRoot | undefined> {
|
|
3129
|
+
signal?: AbortSignal
|
|
3130
|
+
): Promise<void> {
|
|
2872
3131
|
throwIfAborted(signal);
|
|
2873
3132
|
const admission = this.formalRemoteActorAdmissions.get(recovery.request.handoffId);
|
|
2874
3133
|
if (admission === undefined) {
|
|
@@ -2930,24 +3189,24 @@ export class DefaultZLinkSpotManager {
|
|
|
2930
3189
|
}
|
|
2931
3190
|
// Command 28 carries a present reply in one outer framework-multipart
|
|
2932
3191
|
// part. The accepted target admission still owns the inner typed content
|
|
2933
|
-
// type, which the
|
|
3192
|
+
// type, which the process-local completion keeps for application decode.
|
|
2934
3193
|
const admittedContentType =
|
|
2935
3194
|
admittedReply.byteLength === 0 ? recovery.replyContentType : outcome.replyContentType;
|
|
2936
3195
|
const transfer = this.options.actorTransferRuntime;
|
|
2937
3196
|
if (transfer === undefined) {
|
|
2938
3197
|
throw new Error('Canonical Actor Join recovery requires the Actor transfer runtime.');
|
|
2939
3198
|
}
|
|
2940
|
-
const deferred =
|
|
3199
|
+
const deferred = transfer.prepareDeferredJoinAccepted(
|
|
2941
3200
|
recovery.request.actorId,
|
|
2942
3201
|
recovery.operationId,
|
|
2943
3202
|
admitted.actorRef,
|
|
2944
3203
|
recovery.reply,
|
|
2945
|
-
admittedContentType
|
|
2946
|
-
|
|
2947
|
-
|
|
3204
|
+
admittedContentType
|
|
3205
|
+
);
|
|
3206
|
+
this.formalRemoteActorAdmissions.attachDeferredJoinCompletion(
|
|
3207
|
+
recovery.request.handoffId,
|
|
3208
|
+
deferred
|
|
2948
3209
|
);
|
|
2949
|
-
this.formalRemoteActorAdmissions.attachDeferredJoinRoot(recovery.request.handoffId, deferred);
|
|
2950
|
-
return deferred;
|
|
2951
3210
|
}
|
|
2952
3211
|
|
|
2953
3212
|
private encodeMeshActorReply(
|
|
@@ -3096,19 +3355,10 @@ export class DefaultZLinkSpotManager {
|
|
|
3096
3355
|
}
|
|
3097
3356
|
}
|
|
3098
3357
|
|
|
3099
|
-
function
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
kind === ZLinkFrameworkInternalErrorKind.SpotGenerationStale ||
|
|
3104
|
-
kind === ZLinkFrameworkInternalErrorKind.SpotMoving ||
|
|
3105
|
-
kind === ZLinkFrameworkInternalErrorKind.SpotRouteNotFound ||
|
|
3106
|
-
kind === ZLinkFrameworkInternalErrorKind.RequestTargetNotFound
|
|
3107
|
-
) {
|
|
3108
|
-
return ZLinkDispatchErrorReason.StaleTarget;
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
return ZLinkDispatchErrorReason.HandlerException;
|
|
3358
|
+
function spotActorFailureKind(error: unknown): ZLinkFrameworkErrorKind {
|
|
3359
|
+
return error instanceof ZLinkFrameworkException
|
|
3360
|
+
? error.kind
|
|
3361
|
+
: ZLinkFrameworkErrorKind.InternalFailure;
|
|
3112
3362
|
}
|
|
3113
3363
|
|
|
3114
3364
|
interface ZLinkFormalRemoteTransferRequest {
|