@zlink-systems/framework 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/CoreTypes.d.ts +6 -0
- package/dist/contracts/Common/CoreTypes.js +7 -0
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/index.js +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
- package/dist/contracts/Configuration/InternalDefaults.js +9 -1
- package/dist/contracts/Configuration/Registration.d.ts +13 -2
- package/dist/contracts/Configuration/Registration.js +58 -36
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
- package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
- package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
- package/dist/contracts/Handlers/JsonContract.js +10 -4
- package/dist/contracts/Locations/Authority.d.ts +1 -1
- package/dist/contracts/Locations/Authority.js +3 -2
- package/dist/contracts/Locations/Options.js +1 -1
- package/dist/contracts/Locations/Stores.d.ts +12 -0
- package/dist/contracts/Locations/Stores.js +9 -0
- package/dist/contracts/Spots/Contracts.d.ts +1 -1
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +15 -1
- package/dist/nest-integration.d.ts +4 -2
- package/dist/nest-integration.js +14 -4
- package/dist/runtime/abort.d.ts +1 -0
- package/dist/runtime/abort.js +8 -5
- package/dist/runtime/activation-admission.d.ts +1 -2
- package/dist/runtime/activation-admission.js +2 -6
- package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
- package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
- package/dist/runtime/actors/actor-client.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +42 -143
- package/dist/runtime/actors/actor-context.d.ts +3 -5
- package/dist/runtime/actors/actor-context.js +13 -11
- package/dist/runtime/actors/actor-handoff.d.ts +4 -4
- package/dist/runtime/actors/actor-handoff.js +8 -8
- package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
- package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
- package/dist/runtime/actors/actor-local-native-join.js +83 -105
- package/dist/runtime/actors/actor-native-lookup.js +2 -8
- package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
- package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
- package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
- package/dist/runtime/actors/actor-remote-joiner.js +5 -9
- package/dist/runtime/actors/actor-remote-wire.js +5 -3
- package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
- package/dist/runtime/actors/actor-request-deadline.js +31 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
- package/dist/runtime/actors/deferred-join-completion.js +1 -0
- package/dist/runtime/actors/index.d.ts +9 -7
- package/dist/runtime/actors/index.js +87 -69
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
- package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
- package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
- package/dist/runtime/admission.d.ts +2 -0
- package/dist/runtime/admission.js +7 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
- package/dist/runtime/backend/contracts/index.d.ts +6 -23
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +1 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -6
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.js +40 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +3 -2
- package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/runtime-values.d.ts +4 -1
- package/dist/runtime/backend/runtime-values.js +2 -0
- package/dist/runtime/channels/channel-clients.d.ts +20 -8
- package/dist/runtime/channels/channel-clients.js +68 -52
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.js +47 -29
- package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
- package/dist/runtime/channels/channel-outbound-operations.js +9 -10
- package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
- package/dist/runtime/channels/channel-receive-loops.js +27 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
- package/dist/runtime/channels/channel-runtime-manager.js +5 -2
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
- package/dist/runtime/channels/channel-socket-registry.js +248 -174
- package/dist/runtime/channels/channel-transports.d.ts +11 -17
- package/dist/runtime/channels/channel-transports.js +68 -47
- package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/client-server-location-runtime.js +10 -11
- package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
- package/dist/runtime/channels/client-server-service-wire.js +32 -11
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
- package/dist/runtime/channels/fanout-location-runtime.js +130 -72
- package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
- package/dist/runtime/channels/spot-direct-envelope.js +4 -3
- package/dist/runtime/channels/spot-node-route-transport.js +3 -2
- package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
- package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
- package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
- package/dist/runtime/diagnostics/flow-context.js +16 -2
- package/dist/runtime/diagnostics/index.d.ts +4 -2
- package/dist/runtime/diagnostics/index.js +14 -4
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
- package/dist/runtime/diagnostics/message-flow.js +10 -19
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
- package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
- package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
- package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
- package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
- package/dist/runtime/disposal.d.ts +5 -0
- package/dist/runtime/disposal.js +22 -0
- package/dist/runtime/execution/index.d.ts +12 -9
- package/dist/runtime/execution/index.js +58 -14
- package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
- package/dist/runtime/execution/serial-execution-queue.js +54 -15
- package/dist/runtime/execution/state-lane.d.ts +8 -1
- package/dist/runtime/execution/state-lane.js +118 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
- package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
- package/dist/runtime/foundation/event-loop-resources.js +6 -119
- package/dist/runtime/foundation/operation-identity.d.ts +2 -0
- package/dist/runtime/foundation/operation-identity.js +9 -5
- package/dist/runtime/foundation/operation-registry.d.ts +5 -7
- package/dist/runtime/foundation/operation-registry.js +34 -44
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +62 -83
- package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
- package/dist/runtime/foundation/runtime-state-projections.js +8 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +22 -3
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
- package/dist/runtime/foundation/service-liveness-registry.js +2 -1
- package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
- package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
- package/dist/runtime/foundation/service-metadata-codec.js +3 -3
- package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
- package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
- package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
- package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +10 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
- package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
- package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
- package/dist/runtime/foundation/service-topology-registry.js +17 -32
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
- package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
- package/dist/runtime/foundation/service-wire-codec.js +10 -8
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
- package/dist/runtime/framework-errors-internal.d.ts +2 -1
- package/dist/runtime/framework-errors-internal.js +343 -122
- package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
- package/dist/runtime/handlers/handler-instance-scope.js +61 -74
- package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
- package/dist/runtime/host/actor-packet-relay.js +48 -91
- package/dist/runtime/host/actor-placement-coordinator.js +7 -5
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
- package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
- package/dist/runtime/host/actor-transfer-runtime.js +143 -176
- package/dist/runtime/host/application-job-queue.js +16 -33
- package/dist/runtime/host/bound-session-relay.js +1 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
- package/dist/runtime/host/index.d.ts +14 -13
- package/dist/runtime/host/index.js +190 -157
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
- package/dist/runtime/host/instance-activation-authority.js +17 -45
- package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
- package/dist/runtime/host/location-runtime-owner.js +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
- package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
- package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
- package/dist/runtime/host/remote-bound-session-relay.js +7 -20
- package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
- package/dist/runtime/host/route-mesh-runtime.js +171 -252
- package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
- package/dist/runtime/host/runtime-shutdown.js +18 -21
- package/dist/runtime/host/service-relocation-control.js +6 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
- package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
- package/dist/runtime/host/spot-address-transport.d.ts +2 -3
- package/dist/runtime/host/spot-address-transport.js +34 -136
- package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
- package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
- package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
- package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
- package/dist/runtime/locations/authority-key-codec.js +4 -3
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
- package/dist/runtime/locations/creation-operation-id.js +6 -4
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
- package/dist/runtime/locations/in-memory-authority-store.js +31 -15
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +17 -14
- package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
- package/dist/runtime/locations/key-codec.js +3 -2
- package/dist/runtime/locations/lease-tracker.d.ts +3 -5
- package/dist/runtime/locations/lease-tracker.js +7 -11
- package/dist/runtime/locations/lifecycle.d.ts +4 -9
- package/dist/runtime/locations/lifecycle.js +2 -31
- package/dist/runtime/locations/location-store-failure.d.ts +2 -0
- package/dist/runtime/locations/location-store-failure.js +7 -0
- package/dist/runtime/locations/location-store-pages.d.ts +3 -0
- package/dist/runtime/locations/location-store-pages.js +13 -0
- package/dist/runtime/locations/location-store-repository.d.ts +5 -7
- package/dist/runtime/locations/location-store-repository.js +303 -332
- package/dist/runtime/locations/relocation-blob.js +18 -5
- package/dist/runtime/locations/resolvers.d.ts +5 -5
- package/dist/runtime/locations/resolvers.js +37 -28
- package/dist/runtime/locations/runtime.d.ts +5 -4
- package/dist/runtime/locations/runtime.js +123 -92
- package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
- package/dist/runtime/locations/spot-location-claims.js +42 -1
- package/dist/runtime/messaging/payload-codec.js +26 -20
- package/dist/runtime/messaging/submission-result.d.ts +3 -0
- package/dist/runtime/messaging/submission-result.js +48 -0
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
- package/dist/runtime/spots/index.d.ts +14 -20
- package/dist/runtime/spots/index.js +302 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
- package/dist/runtime/spots/spot-activation-registry.js +14 -50
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +2 -2
- package/dist/runtime/spots/spot-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-activation.js +49 -32
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
- package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
- package/dist/runtime/spots/spot-actor-membership.js +22 -45
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
- package/dist/runtime/spots/spot-context.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +9 -20
- package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
- package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
- package/dist/runtime/spots/spot-manager-public.js +5 -4
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
- package/dist/runtime/spots/spot-outbound.d.ts +4 -3
- package/dist/runtime/spots/spot-outbound.js +9 -8
- package/dist/runtime/spots/spot-remote-codec.js +5 -3
- package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
- package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
- package/dist/runtime/spots/spot-route-replies.js +3 -1
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
- package/dist/runtime/spots/spot-serial-executor.js +2 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
- package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +11 -1
- package/dist/runtime/streams/index.d.ts +14 -15
- package/dist/runtime/streams/index.js +20 -21
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +17 -8
- package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
- package/dist/runtime/streams/protocol.d.ts +6 -33
- package/dist/runtime/streams/protocol.js +38 -110
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
- package/dist/runtime/streams/session-actor-coordinator.js +12 -4
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +5 -4
- package/dist/runtime/streams/session-context.d.ts +6 -6
- package/dist/runtime/streams/session-context.js +22 -4
- package/dist/runtime/streams/session-requests.js +2 -1
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
- package/dist/runtime/streams/stream-frame-factory.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
- package/dist/runtime/streams/stream-session-runtime.js +25 -33
- package/dist/runtime/workers/index.d.ts +2 -2
- package/dist/runtime/workers/index.js +5 -4
- package/package.json +3 -3
- package/src/contracts/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Configuration/InternalDefaults.ts +12 -0
- package/src/contracts/Configuration/Registration.ts +92 -48
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Handlers/JsonContract.ts +14 -4
- package/src/contracts/Locations/Authority.ts +7 -3
- package/src/contracts/Locations/Options.ts +1 -1
- package/src/contracts/Locations/Stores.ts +14 -0
- package/src/contracts/Spots/Contracts.ts +1 -1
- package/src/internal.ts +14 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +2 -8
- package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
- package/src/runtime/actors/actor-client.ts +77 -204
- package/src/runtime/actors/actor-context.ts +39 -33
- package/src/runtime/actors/actor-handoff.ts +24 -22
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +172 -174
- package/src/runtime/actors/actor-native-lookup.ts +2 -9
- package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
- package/src/runtime/actors/actor-remote-joiner.ts +9 -11
- package/src/runtime/actors/actor-remote-wire.ts +5 -3
- package/src/runtime/actors/actor-request-deadline.ts +49 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- package/src/runtime/actors/actor-runtime-state.ts +85 -247
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +10 -6
- package/src/runtime/actors/index.ts +100 -79
- package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
- package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
- package/src/runtime/admission.ts +8 -1
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +13 -29
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-support.ts +23 -6
- package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +41 -20
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +3 -2
- package/src/runtime/backend/raw-binding-port.ts +1 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +132 -85
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +58 -29
- package/src/runtime/channels/channel-outbound-operations.ts +10 -23
- package/src/runtime/channels/channel-receive-loops.ts +39 -7
- package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
- package/src/runtime/channels/channel-runtime-manager.ts +6 -2
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +301 -192
- package/src/runtime/channels/channel-transports.ts +161 -112
- package/src/runtime/channels/client-server-location-runtime.ts +17 -17
- package/src/runtime/channels/client-server-service-wire.ts +40 -12
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
- package/src/runtime/channels/fanout-location-runtime.ts +172 -91
- package/src/runtime/channels/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +5 -2
- package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
- package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
- package/src/runtime/diagnostics/flow-context.ts +16 -2
- package/src/runtime/diagnostics/index.ts +27 -17
- package/src/runtime/diagnostics/message-flow.ts +15 -25
- package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
- package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
- package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
- package/src/runtime/disposal.ts +19 -0
- package/src/runtime/execution/index.ts +60 -20
- package/src/runtime/execution/serial-execution-queue.ts +131 -18
- package/src/runtime/execution/state-lane.ts +142 -4
- package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
- package/src/runtime/foundation/event-loop-resources.ts +5 -122
- package/src/runtime/foundation/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +110 -111
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
- package/src/runtime/foundation/service-discovery-registry.ts +32 -3
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
- package/src/runtime/foundation/service-liveness-registry.ts +2 -1
- package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
- package/src/runtime/foundation/service-metadata-codec.ts +2 -2
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
- package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
- package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
- package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
- package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
- package/src/runtime/foundation/service-topology-registry.ts +23 -32
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
- package/src/runtime/foundation/service-wire-codec.ts +15 -8
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
- package/src/runtime/framework-errors-internal.ts +380 -134
- package/src/runtime/handlers/handler-instance-scope.ts +68 -95
- package/src/runtime/host/actor-packet-relay.ts +57 -147
- package/src/runtime/host/actor-placement-coordinator.ts +8 -5
- package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
- package/src/runtime/host/actor-transfer-runtime.ts +180 -260
- package/src/runtime/host/application-job-queue.ts +28 -34
- package/src/runtime/host/bound-session-relay.ts +1 -2
- package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
- package/src/runtime/host/index.ts +327 -296
- package/src/runtime/host/instance-activation-authority.ts +89 -109
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
- package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
- package/src/runtime/host/remote-bound-session-relay.ts +8 -41
- package/src/runtime/host/route-mesh-runtime.ts +228 -271
- package/src/runtime/host/runtime-shutdown.ts +17 -21
- package/src/runtime/host/service-relocation-control.ts +14 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
- package/src/runtime/host/spot-address-transport.ts +73 -195
- package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
- package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
- package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
- package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
- package/src/runtime/locations/authority-key-codec.ts +7 -3
- package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
- package/src/runtime/locations/creation-operation-id.ts +6 -3
- package/src/runtime/locations/domain-store-contract.ts +12 -3
- package/src/runtime/locations/in-memory-authority-store.ts +44 -15
- package/src/runtime/locations/in-memory-location-store.ts +50 -39
- package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +13 -43
- package/src/runtime/locations/location-store-failure.ts +4 -0
- package/src/runtime/locations/location-store-pages.ts +18 -0
- package/src/runtime/locations/location-store-repository.ts +450 -478
- package/src/runtime/locations/relocation-blob.ts +17 -6
- package/src/runtime/locations/resolvers.ts +75 -49
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +58 -1
- package/src/runtime/messaging/payload-codec.ts +35 -24
- package/src/runtime/messaging/submission-result.ts +57 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
- package/src/runtime/spots/index.ts +433 -229
- package/src/runtime/spots/spot-activation-registry.ts +30 -69
- package/src/runtime/spots/spot-activation-state.ts +2 -2
- package/src/runtime/spots/spot-activation.ts +67 -37
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
- package/src/runtime/spots/spot-actor-membership.ts +40 -72
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
- package/src/runtime/spots/spot-context.ts +3 -3
- package/src/runtime/spots/spot-entry-activation.ts +13 -30
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +21 -17
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
- package/src/runtime/spots/spot-outbound.ts +45 -23
- package/src/runtime/spots/spot-remote-codec.ts +7 -3
- package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
- package/src/runtime/spots/spot-route-replies.ts +6 -4
- package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +5 -27
- package/src/runtime/spots/spot-serial-executor.ts +2 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
- package/src/runtime/streams/bound-session-service.ts +21 -1
- package/src/runtime/streams/index.ts +76 -64
- package/src/runtime/streams/managed-stream.ts +29 -10
- package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
- package/src/runtime/streams/protocol.ts +34 -88
- package/src/runtime/streams/session-actor-coordinator.ts +17 -5
- package/src/runtime/streams/session-calls.ts +6 -5
- package/src/runtime/streams/session-context.ts +54 -10
- package/src/runtime/streams/session-requests.ts +2 -1
- package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
- package/src/runtime/streams/stream-frame-factory.ts +2 -3
- package/src/runtime/streams/stream-session-runtime.ts +57 -59
- package/src/runtime/workers/index.ts +13 -12
- package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
- package/dist/runtime/actors/post-commit-actor-location.js +0 -72
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
- package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
- package/src/runtime/actors/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import { ZlinkStreamContentType } from '@zlink-systems/stream-wire';
|
|
1
2
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
|
+
import { ZLinkFrameworkException } from '../../contracts';
|
|
4
|
+
import type { ZLinkAuthoritySnapshot } from '../locations/internal-location-contracts';
|
|
5
|
+
import { decodeServiceClosingSpotAuthority } from './service-authority-payload-codec';
|
|
6
|
+
import {
|
|
7
|
+
ZLinkRuntimeDispatchErrorAction as ZLinkDispatchErrorAction,
|
|
8
|
+
ZLinkRuntimeDispatchErrorReason as ZLinkDispatchErrorReason,
|
|
9
|
+
ZLinkDispatchErrorSurface,
|
|
10
|
+
ZLinkDispatchMessageKind,
|
|
11
|
+
ZLinkRuntimeMessageFlowOutcome as ZLinkMessageFlowOutcome
|
|
12
|
+
} from '../../contracts/Dispatch/ZLinkDispatchOptions';
|
|
2
13
|
import { awaitWithAbort } from '../abort';
|
|
14
|
+
import { shouldCompactBackingArray } from '../admission';
|
|
15
|
+
import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
|
|
16
|
+
import type { ZLinkDispatchErrorReporter } from '../channels/dispatch-error-reporter';
|
|
17
|
+
import { flowIfEnabled } from '../diagnostics/message-flow';
|
|
3
18
|
import { captureZLinkExecutionTurn } from '../execution';
|
|
4
19
|
import {
|
|
5
20
|
ZLinkFrameworkInternalErrorKind,
|
|
@@ -8,21 +23,26 @@ import {
|
|
|
8
23
|
internalFrameworkWireReply,
|
|
9
24
|
translateWireReplyDecodeError
|
|
10
25
|
} from '../framework-errors-internal';
|
|
11
|
-
import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
|
|
12
|
-
import type { ZLinkDispatchErrorReporter } from '../channels/dispatch-error-reporter';
|
|
13
26
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from '
|
|
20
|
-
import {
|
|
27
|
+
decodeActorJoin28,
|
|
28
|
+
encodeActorJoin28,
|
|
29
|
+
type ActorJoin28
|
|
30
|
+
} from '../protocol/service_wire_pilot_codec.generated';
|
|
31
|
+
import { canonicalActorJoinHandoffId, routingIdBytes } from './actor-join-recovery-codec';
|
|
32
|
+
import { OperationRegistry } from './operation-registry';
|
|
33
|
+
import {
|
|
34
|
+
MessageFollowSuppressionRegistry,
|
|
35
|
+
type MessageFollowSuppressionFence
|
|
36
|
+
} from './message-follow-suppression-registry';
|
|
37
|
+
import { ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE } from './operation-identity';
|
|
21
38
|
import type {
|
|
22
39
|
RawServiceIngressRecord,
|
|
23
40
|
RawServiceMeshRuntime,
|
|
24
41
|
RawServicePumpResult
|
|
25
42
|
} from './raw-service-mesh-runtime';
|
|
43
|
+
import type { ServiceInstanceActivationRecoveryEnvelope } from './service-instance-activation-recovery-codec';
|
|
44
|
+
import type { ServiceMailboxRecord } from './service-mailbox';
|
|
45
|
+
import { validateServiceMetadataFrame } from './service-metadata-codec';
|
|
26
46
|
import {
|
|
27
47
|
ActorLifecycleKind,
|
|
28
48
|
OperationKind,
|
|
@@ -31,13 +51,9 @@ import {
|
|
|
31
51
|
type ActorJoinCompletionPayload,
|
|
32
52
|
type ActorLocation,
|
|
33
53
|
type ReceiveKindData,
|
|
54
|
+
type ServiceStreamSessionBinding,
|
|
34
55
|
type StreamSessionActorAuthorityFence
|
|
35
56
|
} from './service-runtime-contracts';
|
|
36
|
-
import type { ServiceMailboxRecord } from './service-mailbox';
|
|
37
|
-
import {
|
|
38
|
-
MessageFollowSuppressionRegistry,
|
|
39
|
-
type MessageFollowSuppressionFence
|
|
40
|
-
} from './message-follow-suppression-registry';
|
|
41
57
|
import {
|
|
42
58
|
ServiceStaleGenerationError,
|
|
43
59
|
ServiceStatefulRegistry,
|
|
@@ -49,6 +65,8 @@ import {
|
|
|
49
65
|
type ServiceSpotState
|
|
50
66
|
} from './service-stateful-registry';
|
|
51
67
|
import {
|
|
68
|
+
M6bServiceWireCommand,
|
|
69
|
+
M6bServiceWireFlag,
|
|
52
70
|
decodeStatefulHeader,
|
|
53
71
|
decodeStatefulReply,
|
|
54
72
|
encodeActorCreateHeader,
|
|
@@ -66,17 +84,15 @@ import {
|
|
|
66
84
|
encodeStatefulReply,
|
|
67
85
|
encodeUserSpotCloseHeader,
|
|
68
86
|
encodeUserSpotCreateHeader,
|
|
69
|
-
M6bServiceWireCommand,
|
|
70
|
-
M6bServiceWireFlag,
|
|
71
87
|
sessionBindingFromWire,
|
|
88
|
+
type ServiceActorCreateRecord,
|
|
72
89
|
type ServiceActorRouteFence,
|
|
73
90
|
type ServiceBoundSessionActorAuthority,
|
|
74
|
-
type
|
|
75
|
-
type ServiceActorCreateRecord,
|
|
91
|
+
type ServiceDirectSpotRouteFence,
|
|
76
92
|
type ServiceInstanceActivationTarget,
|
|
77
93
|
type ServiceInstanceRouteFence,
|
|
78
94
|
type ServiceMessageFollowRoute,
|
|
79
|
-
type
|
|
95
|
+
type ServiceRetiredBoundSessionRouteFence,
|
|
80
96
|
type ServiceSpotRouteFence,
|
|
81
97
|
type ServiceStatefulReplyTail,
|
|
82
98
|
type ServiceStatefulWireRecord,
|
|
@@ -84,26 +100,21 @@ import {
|
|
|
84
100
|
type ServiceUserSpotCreateRecord
|
|
85
101
|
} from './service-stateful-wire-codec';
|
|
86
102
|
import {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} from '
|
|
91
|
-
import { canonicalActorJoinHandoffId, routingIdBytes } from './actor-join-recovery-codec';
|
|
92
|
-
|
|
103
|
+
SERVICE_WIRE_COMMAND_OFFSET,
|
|
104
|
+
SERVICE_WIRE_FLAGS_OFFSET
|
|
105
|
+
} from './service-wire-binary-primitives';
|
|
106
|
+
import { SERVICE_WIRE_MAGIC, SERVICE_WIRE_MAJOR } from './service-wire-constants.generated';
|
|
93
107
|
import {
|
|
108
|
+
ServiceWireProtocolError,
|
|
94
109
|
decodeApplicationPayload,
|
|
95
110
|
decodeApplicationPayloadView,
|
|
96
111
|
encodeApplicationPayload,
|
|
97
|
-
type ServiceApplicationPayload
|
|
98
|
-
ServiceWireProtocolError
|
|
112
|
+
type ServiceApplicationPayload
|
|
99
113
|
} from './service-wire-m6a-codec';
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
import { ZLinkFrameworkException } from '../../contracts';
|
|
104
|
-
import { ZLinkFrameworkRuntimeState } from '../../contracts/Locations';
|
|
114
|
+
const STATEFUL_OPERATION_RETRY_TICK_MS = 20;
|
|
115
|
+
|
|
116
|
+
const MAX_NODE_TIMER_DELAY_MS = 2_147_483_647;
|
|
105
117
|
|
|
106
|
-
const ACTOR_ROUTE_STALE = 21;
|
|
107
118
|
const SPOT_MOVING = 34;
|
|
108
119
|
const USER_SPOT_OPERATION_CAPACITY = 65_536;
|
|
109
120
|
const USER_SPOT_OPERATION_REPLAY_RETENTION_MS = 5 * 60_000;
|
|
@@ -170,7 +181,9 @@ export interface ServiceStatefulMailboxData {
|
|
|
170
181
|
readonly isPending?: () => boolean;
|
|
171
182
|
/** Carries the local operation deadline into the lifecycle dispatch lane. */
|
|
172
183
|
readonly deadlineUnixMs?: bigint;
|
|
184
|
+
readonly activationRecord?: Extract<ServiceStatefulWireRecord, { readonly kind: 'instanceSpot' }>;
|
|
173
185
|
readonly onTerminalCompletion?: () => void | Promise<void>;
|
|
186
|
+
readonly onHandlerTurnStarted?: () => void;
|
|
174
187
|
/** Decoded only by the canonical command-28 generator path. */
|
|
175
188
|
readonly canonicalApplicationPayload?: ServiceApplicationPayload;
|
|
176
189
|
readonly reply?: (
|
|
@@ -194,9 +207,8 @@ export interface ServiceCanonicalActorJoinCandidate {
|
|
|
194
207
|
|
|
195
208
|
export interface ServiceSessionDelivery {
|
|
196
209
|
readonly binding: ServiceSessionBinding;
|
|
197
|
-
readonly bindingIngress?: ServiceSessionBindingIngressPort;
|
|
198
210
|
/**
|
|
199
|
-
* Delivers the
|
|
211
|
+
* Delivers the M6A application frame after the binding fence has
|
|
200
212
|
* been validated. The stream adapter owns multipart decoding at that point.
|
|
201
213
|
*/
|
|
202
214
|
readonly deliver: (sessionRid: string, payloadFrame: Uint8Array) => Promise<boolean>;
|
|
@@ -231,7 +243,6 @@ export type ServiceInstanceApplicationTarget = ServiceInstanceApplicationIdentit
|
|
|
231
243
|
export interface ServiceInstanceApplicationLifecycle {
|
|
232
244
|
isMaterialized(target: ServiceInstanceApplicationIdentity): boolean;
|
|
233
245
|
isMaterializing?(target: ServiceInstanceApplicationIdentity): boolean;
|
|
234
|
-
isClosing?(target: ServiceInstanceApplicationIdentity): boolean;
|
|
235
246
|
isIdleEvicting?(target: ServiceInstanceApplicationIdentity): boolean;
|
|
236
247
|
beginIdleEviction?(target: ServiceInstanceApplicationIdentity): boolean;
|
|
237
248
|
materialize(target: ServiceInstanceApplicationIdentity, objectGeneration: bigint): Promise<void>;
|
|
@@ -261,8 +272,13 @@ export type ServiceInstanceAuthorityRead =
|
|
|
261
272
|
readonly kind: 'creating';
|
|
262
273
|
readonly objectGeneration: bigint;
|
|
263
274
|
readonly authorityOwnerGeneration: bigint;
|
|
275
|
+
readonly authority?: ZLinkAuthoritySnapshot;
|
|
264
276
|
}
|
|
265
|
-
| {
|
|
277
|
+
| {
|
|
278
|
+
readonly kind: 'ready';
|
|
279
|
+
readonly route: ServiceInstanceRouteFence;
|
|
280
|
+
readonly authority?: ZLinkAuthoritySnapshot;
|
|
281
|
+
};
|
|
266
282
|
|
|
267
283
|
export type ServiceInstanceAuthorityReserve =
|
|
268
284
|
| { readonly kind: 'reserved'; readonly reservation: ServiceInstanceActivationReservation }
|
|
@@ -298,7 +314,8 @@ export interface ServiceInstanceActivationAuthority {
|
|
|
298
314
|
export interface ServiceAsyncInstanceActivationAuthority {
|
|
299
315
|
read(target: ServiceInstanceActivationTarget): Promise<ServiceInstanceAuthorityRead>;
|
|
300
316
|
reserve(
|
|
301
|
-
activation: Omit<ServiceInstanceActivationRecoveryEnvelope, 'targetMeshName'
|
|
317
|
+
activation: Omit<ServiceInstanceActivationRecoveryEnvelope, 'targetMeshName'>,
|
|
318
|
+
signal?: AbortSignal
|
|
302
319
|
): Promise<ServiceInstanceAuthorityReserve>;
|
|
303
320
|
resume(
|
|
304
321
|
target: ServiceInstanceActivationTarget,
|
|
@@ -307,7 +324,8 @@ export interface ServiceAsyncInstanceActivationAuthority {
|
|
|
307
324
|
commit(
|
|
308
325
|
target: ServiceInstanceActivationTarget,
|
|
309
326
|
reservation: ServiceInstanceActivationReservation,
|
|
310
|
-
spot: ServiceSpotState
|
|
327
|
+
spot: ServiceSpotState,
|
|
328
|
+
deadlineUnixMs?: bigint
|
|
311
329
|
): Promise<{ readonly kind: 'committed' | 'lost'; readonly route: ServiceInstanceRouteFence }>;
|
|
312
330
|
complete(
|
|
313
331
|
target: ServiceInstanceActivationTarget,
|
|
@@ -364,7 +382,7 @@ export class ServiceStatefulRuntime {
|
|
|
364
382
|
|
|
365
383
|
readonly registry: ServiceStatefulRegistry;
|
|
366
384
|
|
|
367
|
-
private readonly operations
|
|
385
|
+
private readonly operations: ServiceTerminalOperationRegistry<ServiceStatefulResult>;
|
|
368
386
|
private readonly sessionDeliveries = new Map<string, ServiceSessionDelivery>();
|
|
369
387
|
/**
|
|
370
388
|
* A local Actor owner can replace its own session binding before the
|
|
@@ -376,7 +394,6 @@ export class ServiceStatefulRuntime {
|
|
|
376
394
|
private readonly subscriptions = new Map<string, Set<string>>();
|
|
377
395
|
private readonly instanceIntents = new Map<string, ServiceInstanceIntent>();
|
|
378
396
|
private readonly admittedInstanceOperations = new Map<string, bigint>();
|
|
379
|
-
private readonly pendingInstanceTerminals = new Map<string, number>();
|
|
380
397
|
private readonly pendingInstanceAuthorityTerminals = new Map<string, number>();
|
|
381
398
|
private readonly instanceApplicationWaiters = new Map<string, Set<() => void>>();
|
|
382
399
|
private readonly canonicalActorJoinHandoffs = new Map<bigint, string>();
|
|
@@ -406,11 +423,6 @@ export class ServiceStatefulRuntime {
|
|
|
406
423
|
readonly owner: string;
|
|
407
424
|
}) => void;
|
|
408
425
|
private dispatchErrors?: ZLinkDispatchErrorReporter;
|
|
409
|
-
private spotAdmissionProvider?: {
|
|
410
|
-
readonly isClosing: (spotId: string) => boolean;
|
|
411
|
-
readonly runtimeState: () => ZLinkFrameworkRuntimeState;
|
|
412
|
-
readonly awaitCloseDecision?: (spotId: string) => Promise<void> | undefined;
|
|
413
|
-
};
|
|
414
426
|
private dispatchErrorMeshName?: string;
|
|
415
427
|
private readonly admittedUserSpotOperations = new Map<
|
|
416
428
|
string,
|
|
@@ -424,7 +436,7 @@ export class ServiceStatefulRuntime {
|
|
|
424
436
|
private readonly pendingInstanceActivations = new Map<
|
|
425
437
|
string,
|
|
426
438
|
Promise<{
|
|
427
|
-
readonly spot: ServiceSpotState
|
|
439
|
+
readonly spot: Pick<ServiceSpotState, 'ref'>;
|
|
428
440
|
readonly route: ServiceInstanceRouteFence;
|
|
429
441
|
}>
|
|
430
442
|
>();
|
|
@@ -433,21 +445,17 @@ export class ServiceStatefulRuntime {
|
|
|
433
445
|
constructor(
|
|
434
446
|
private readonly raw: RawServiceMeshRuntime,
|
|
435
447
|
readonly nodeRid: string,
|
|
436
|
-
readonly nodeGeneration: bigint
|
|
448
|
+
readonly nodeGeneration: bigint,
|
|
449
|
+
onPendingOperationsChanged?: () => void
|
|
437
450
|
) {
|
|
451
|
+
this.operations = new ServiceTerminalOperationRegistry(
|
|
452
|
+
new OperationRegistry(undefined, onPendingOperationsChanged)
|
|
453
|
+
);
|
|
438
454
|
this.registry = new ServiceStatefulRegistry(nodeRid, nodeGeneration);
|
|
439
455
|
this.registry.createEntrySpot(nodeRid);
|
|
440
456
|
raw.setServiceIngress((record) => this.ingress(record));
|
|
441
457
|
}
|
|
442
458
|
|
|
443
|
-
setSpotAdmissionProvider(provider: {
|
|
444
|
-
readonly isClosing: (spotId: string) => boolean;
|
|
445
|
-
readonly runtimeState: () => ZLinkFrameworkRuntimeState;
|
|
446
|
-
readonly awaitCloseDecision?: (spotId: string) => Promise<void> | undefined;
|
|
447
|
-
}): void {
|
|
448
|
-
this.spotAdmissionProvider = provider;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
459
|
setMailboxDropHandler(
|
|
452
460
|
handler: (record: {
|
|
453
461
|
readonly kind: 'spot_multicast' | 'actor_control' | 'actor_binding';
|
|
@@ -890,6 +898,7 @@ export class ServiceStatefulRuntime {
|
|
|
890
898
|
...(envelope.replyRouteId === undefined ? {} : { replyRouteId: envelope.replyRouteId })
|
|
891
899
|
};
|
|
892
900
|
const applicationJobOwner = await this.raw.reserveLocalIngress();
|
|
901
|
+
const terminal = this.activationTerminalCompletion(target, route);
|
|
893
902
|
try {
|
|
894
903
|
const admitted = this.enqueueActivatedInstanceSpot(
|
|
895
904
|
{
|
|
@@ -915,11 +924,11 @@ export class ServiceStatefulRuntime {
|
|
|
915
924
|
Buffer.from(envelope.applicationPayloadFrame),
|
|
916
925
|
spot,
|
|
917
926
|
undefined,
|
|
918
|
-
|
|
927
|
+
terminal.onTerminalCompletion,
|
|
919
928
|
envelope.metadataFrame === undefined
|
|
920
929
|
? undefined
|
|
921
930
|
: validateServiceMetadataFrame(envelope.metadataFrame),
|
|
922
|
-
|
|
931
|
+
terminal.onHandlerTurnStarted,
|
|
923
932
|
this.instanceApplicationTarget(record, route.objectGeneration)
|
|
924
933
|
);
|
|
925
934
|
if (admitted !== 'application') {
|
|
@@ -1014,12 +1023,10 @@ export class ServiceStatefulRuntime {
|
|
|
1014
1023
|
return released;
|
|
1015
1024
|
}
|
|
1016
1025
|
|
|
1026
|
+
/** Resolves once every first terminal record of an activated Instance message is durable. */
|
|
1017
1027
|
waitForInstanceApplicationQuiescence(spotId: string, signal?: AbortSignal): Promise<void> {
|
|
1018
1028
|
const key = String(spotId);
|
|
1019
|
-
if (
|
|
1020
|
-
(this.pendingInstanceTerminals.get(key) ?? 0) === 0 &&
|
|
1021
|
-
(this.pendingInstanceAuthorityTerminals.get(key) ?? 0) === 0
|
|
1022
|
-
) {
|
|
1029
|
+
if ((this.pendingInstanceAuthorityTerminals.get(key) ?? 0) === 0) {
|
|
1023
1030
|
return Promise.resolve();
|
|
1024
1031
|
}
|
|
1025
1032
|
if (signal?.aborted === true) {
|
|
@@ -1282,11 +1289,11 @@ export class ServiceStatefulRuntime {
|
|
|
1282
1289
|
reporter.report({
|
|
1283
1290
|
surface: ZLinkDispatchErrorSurface.SpotRoute,
|
|
1284
1291
|
messageKind: ZLinkDispatchMessageKind.Send,
|
|
1285
|
-
reason:
|
|
1286
|
-
|
|
1287
|
-
this.raw.isPeerRouteReady(target.descriptor.nodeRoutingId)
|
|
1288
|
-
|
|
1289
|
-
|
|
1292
|
+
reason: this.closed
|
|
1293
|
+
? ZLinkDispatchErrorReason.Shutdown
|
|
1294
|
+
: this.raw.isPeerRouteReady(target.descriptor.nodeRoutingId)
|
|
1295
|
+
? ZLinkDispatchErrorReason.Backpressure
|
|
1296
|
+
: ZLinkDispatchErrorReason.StaleTarget,
|
|
1290
1297
|
action: ZLinkDispatchErrorAction.Drop,
|
|
1291
1298
|
meshName: this.dispatchErrorMeshName,
|
|
1292
1299
|
channelName,
|
|
@@ -1323,10 +1330,10 @@ export class ServiceStatefulRuntime {
|
|
|
1323
1330
|
const pending = this.operations.register(timeoutMs);
|
|
1324
1331
|
const target = this.acceptSpotAuthority(requested);
|
|
1325
1332
|
if (target === undefined) {
|
|
1326
|
-
this.operations.reply(
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1333
|
+
this.operations.reply(
|
|
1334
|
+
pending.id,
|
|
1335
|
+
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
|
|
1336
|
+
);
|
|
1330
1337
|
return pending;
|
|
1331
1338
|
}
|
|
1332
1339
|
const header = encodeSpotHeader('spotRequest', sourceSpotId, target, pending.id, {
|
|
@@ -1381,10 +1388,10 @@ export class ServiceStatefulRuntime {
|
|
|
1381
1388
|
const pending = this.operations.register(timeoutMs);
|
|
1382
1389
|
const route = this.tryActorFence(target);
|
|
1383
1390
|
if (route === undefined) {
|
|
1384
|
-
this.operations.reply(
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1391
|
+
this.operations.reply(
|
|
1392
|
+
pending.id,
|
|
1393
|
+
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
|
|
1394
|
+
);
|
|
1388
1395
|
return pending;
|
|
1389
1396
|
}
|
|
1390
1397
|
const header = encodeActorHeader(
|
|
@@ -1414,7 +1421,8 @@ export class ServiceStatefulRuntime {
|
|
|
1414
1421
|
route: ServiceInstanceRouteFence,
|
|
1415
1422
|
payload: ServiceApplicationPayload,
|
|
1416
1423
|
sourceSpotId?: string,
|
|
1417
|
-
metadataFrame?: Uint8Array
|
|
1424
|
+
metadataFrame?: Uint8Array,
|
|
1425
|
+
instanceIntent = false
|
|
1418
1426
|
): Promise<number> {
|
|
1419
1427
|
return this.submitOneWay(
|
|
1420
1428
|
route.targetNodeRid,
|
|
@@ -1428,7 +1436,8 @@ export class ServiceStatefulRuntime {
|
|
|
1428
1436
|
'send',
|
|
1429
1437
|
{ high: 0n, low: 0n },
|
|
1430
1438
|
undefined,
|
|
1431
|
-
metadataFrame !== undefined
|
|
1439
|
+
metadataFrame !== undefined,
|
|
1440
|
+
instanceIntent
|
|
1432
1441
|
),
|
|
1433
1442
|
encodeApplicationPayload(payload)
|
|
1434
1443
|
],
|
|
@@ -1488,7 +1497,8 @@ export class ServiceStatefulRuntime {
|
|
|
1488
1497
|
payload: ServiceApplicationPayload,
|
|
1489
1498
|
timeoutMs: number,
|
|
1490
1499
|
sourceSpotId?: string,
|
|
1491
|
-
metadataFrame?: Uint8Array
|
|
1500
|
+
metadataFrame?: Uint8Array,
|
|
1501
|
+
instanceIntent = false
|
|
1492
1502
|
): ServiceStatefulPendingOperation {
|
|
1493
1503
|
const pending = this.operations.register(timeoutMs);
|
|
1494
1504
|
this.submitRequest(
|
|
@@ -1502,9 +1512,10 @@ export class ServiceStatefulRuntime {
|
|
|
1502
1512
|
this.nodeRid,
|
|
1503
1513
|
sourceSpotId,
|
|
1504
1514
|
'request',
|
|
1505
|
-
{ high:
|
|
1515
|
+
{ high: ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE, low: pending.id },
|
|
1506
1516
|
pending.id,
|
|
1507
|
-
metadataFrame !== undefined
|
|
1517
|
+
metadataFrame !== undefined,
|
|
1518
|
+
instanceIntent
|
|
1508
1519
|
),
|
|
1509
1520
|
encodeApplicationPayload(payload)
|
|
1510
1521
|
],
|
|
@@ -1735,7 +1746,6 @@ export class ServiceStatefulRuntime {
|
|
|
1735
1746
|
timeoutMs: number,
|
|
1736
1747
|
deliver: ServiceSessionDelivery['deliver'],
|
|
1737
1748
|
onBindingReplaced?: ServiceSessionDelivery['onBindingReplaced'],
|
|
1738
|
-
bindingIngress?: ServiceSessionBindingIngressPort,
|
|
1739
1749
|
actorAuthority?: StreamSessionActorAuthorityFence
|
|
1740
1750
|
): ServiceStatefulPendingOperation {
|
|
1741
1751
|
const deadlineMs = performance.now() + timeoutMs;
|
|
@@ -1754,7 +1764,6 @@ export class ServiceStatefulRuntime {
|
|
|
1754
1764
|
const delivery: ServiceSessionDelivery = {
|
|
1755
1765
|
binding: localBinding,
|
|
1756
1766
|
deliver,
|
|
1757
|
-
...(bindingIngress === undefined ? {} : { bindingIngress }),
|
|
1758
1767
|
...(onBindingReplaced === undefined ? {} : { onBindingReplaced })
|
|
1759
1768
|
};
|
|
1760
1769
|
const deliveryKey = actorKey(actor);
|
|
@@ -1895,10 +1904,10 @@ export class ServiceStatefulRuntime {
|
|
|
1895
1904
|
delivery.binding.sessionRid !== sessionRid ||
|
|
1896
1905
|
delivery.binding.bindingGeneration !== expectedBindingGeneration
|
|
1897
1906
|
) {
|
|
1898
|
-
this.operations.reply(
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1907
|
+
this.operations.reply(
|
|
1908
|
+
pending.id,
|
|
1909
|
+
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
|
|
1910
|
+
);
|
|
1902
1911
|
return pending;
|
|
1903
1912
|
}
|
|
1904
1913
|
this.sessionDeliveries.delete(actorKey(actor));
|
|
@@ -1919,10 +1928,19 @@ export class ServiceStatefulRuntime {
|
|
|
1919
1928
|
return pending;
|
|
1920
1929
|
}
|
|
1921
1930
|
|
|
1922
|
-
sessionBindings(sessionRid: string): readonly
|
|
1931
|
+
sessionBindings(sessionRid: string): readonly ServiceStreamSessionBinding[] {
|
|
1923
1932
|
return [...this.sessionDeliveries.values()]
|
|
1924
1933
|
.map((value) => value.binding)
|
|
1925
|
-
.filter((binding) => binding.sessionRid === sessionRid)
|
|
1934
|
+
.filter((binding) => binding.sessionRid === sessionRid)
|
|
1935
|
+
.map((binding) => {
|
|
1936
|
+
const owner = requireSessionOwnerIdentity(binding);
|
|
1937
|
+
return {
|
|
1938
|
+
...binding,
|
|
1939
|
+
sessionOwnerNodeGeneration: owner.nodeGeneration,
|
|
1940
|
+
sessionOwnerId: owner.ownerId,
|
|
1941
|
+
sessionOwnerLeaseGeneration: owner.leaseGeneration
|
|
1942
|
+
};
|
|
1943
|
+
});
|
|
1926
1944
|
}
|
|
1927
1945
|
|
|
1928
1946
|
allSessionBindings(): readonly ServiceSessionBinding[] {
|
|
@@ -1963,8 +1981,9 @@ export class ServiceStatefulRuntime {
|
|
|
1963
1981
|
let binding: ServiceSessionBinding;
|
|
1964
1982
|
try {
|
|
1965
1983
|
binding = this.registry.validateBoundSession(actor, expectedBindingGeneration);
|
|
1966
|
-
} catch {
|
|
1967
|
-
return SubmitResult.
|
|
1984
|
+
} catch (error) {
|
|
1985
|
+
if (error instanceof ServiceStaleGenerationError) return SubmitResult.NotFound;
|
|
1986
|
+
throw error;
|
|
1968
1987
|
}
|
|
1969
1988
|
const actorFence = this.tryActorFence(actor);
|
|
1970
1989
|
if (actorFence === undefined) return SubmitResult.InvalidState;
|
|
@@ -1975,27 +1994,22 @@ export class ServiceStatefulRuntime {
|
|
|
1975
1994
|
]);
|
|
1976
1995
|
}
|
|
1977
1996
|
|
|
1997
|
+
expireOperations(nowMs: number, turnDeadlineMs: number): number {
|
|
1998
|
+
return this.operations.expire(nowMs, turnDeadlineMs);
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
get pendingOperationCount(): number {
|
|
2002
|
+
return this.operations.size;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
1978
2005
|
close(): void {
|
|
1979
2006
|
if (this.closed) return;
|
|
1980
2007
|
this.closed = true;
|
|
1981
2008
|
this.operations.close();
|
|
1982
|
-
const clearedActors = new Set<string>();
|
|
1983
|
-
for (const deliveries of [this.sessionDeliveries, this.retiredSessionDeliveries]) {
|
|
1984
|
-
for (const delivery of deliveries.values()) {
|
|
1985
|
-
const actorId = delivery.binding.actor.actorId;
|
|
1986
|
-
if (clearedActors.has(actorId)) continue;
|
|
1987
|
-
clearedActors.add(actorId);
|
|
1988
|
-
delivery.bindingIngress?.clearOutbound(
|
|
1989
|
-
actorId,
|
|
1990
|
-
new Error(`Actor '${actorId}' Session service closed with retained outbound delivery.`)
|
|
1991
|
-
);
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
2009
|
this.sessionDeliveries.clear();
|
|
1995
2010
|
this.retiredSessionDeliveries.clear();
|
|
1996
2011
|
this.appliedReplacementNotices.clear();
|
|
1997
2012
|
this.instanceIntents.clear();
|
|
1998
|
-
this.pendingInstanceTerminals.clear();
|
|
1999
2013
|
this.pendingInstanceAuthorityTerminals.clear();
|
|
2000
2014
|
for (const waiters of this.instanceApplicationWaiters.values()) {
|
|
2001
2015
|
for (const waiter of waiters) waiter();
|
|
@@ -2131,6 +2145,22 @@ export class ServiceStatefulRuntime {
|
|
|
2131
2145
|
kind === ZLinkFrameworkInternalErrorKind.SpotMoving ||
|
|
2132
2146
|
kind === ZLinkFrameworkInternalErrorKind.SpotGenerationStale
|
|
2133
2147
|
) {
|
|
2148
|
+
const reporter = this.dispatchErrors;
|
|
2149
|
+
if (decoded.kind === 'instanceSpot' && reporter?.captureEnabled() === true) {
|
|
2150
|
+
reporter.report({
|
|
2151
|
+
surface: ZLinkDispatchErrorSurface.InstanceSpot,
|
|
2152
|
+
messageKind: ZLinkDispatchMessageKind.Send,
|
|
2153
|
+
reason: ZLinkDispatchErrorReason.StaleTarget,
|
|
2154
|
+
action: ZLinkDispatchErrorAction.Drop,
|
|
2155
|
+
meshName: this.dispatchErrorMeshName,
|
|
2156
|
+
sourceRid: decoded.sourceNodeRid,
|
|
2157
|
+
spotId:
|
|
2158
|
+
decoded.activation === 'ready'
|
|
2159
|
+
? decoded.route.targetSpotId
|
|
2160
|
+
: decoded.target.targetSpotId,
|
|
2161
|
+
error
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2134
2164
|
return 'protocolError';
|
|
2135
2165
|
}
|
|
2136
2166
|
}
|
|
@@ -2198,8 +2228,6 @@ export class ServiceStatefulRuntime {
|
|
|
2198
2228
|
}
|
|
2199
2229
|
case 'spotSend':
|
|
2200
2230
|
case 'spotRequest': {
|
|
2201
|
-
await this.spotAdmissionProvider?.awaitCloseDecision?.(record.target.spot.spotId);
|
|
2202
|
-
this.requireDirectSpotAdmission(record.target.spot.spotId);
|
|
2203
2231
|
const followed = this.holdOrRelaySpotMessage(ingress, record);
|
|
2204
2232
|
if (followed !== undefined) return followed;
|
|
2205
2233
|
this.validateDirectSpotFence(record.target);
|
|
@@ -2387,11 +2415,6 @@ export class ServiceStatefulRuntime {
|
|
|
2387
2415
|
targetSpotId: record.route.targetSpotId,
|
|
2388
2416
|
stableType: intent.instanceType
|
|
2389
2417
|
};
|
|
2390
|
-
// A close seals execution only after the current application count reaches
|
|
2391
|
-
// zero. A new Instance message must wait for that close even while the old
|
|
2392
|
-
// activation is still materialized; otherwise it can be admitted after
|
|
2393
|
-
// the close quiescence check and be removed with the old activation.
|
|
2394
|
-
if (lifecycle.isClosing?.(applicationTarget) === true) return true;
|
|
2395
2418
|
return !lifecycle.isMaterialized(applicationTarget);
|
|
2396
2419
|
}
|
|
2397
2420
|
|
|
@@ -2399,11 +2422,11 @@ export class ServiceStatefulRuntime {
|
|
|
2399
2422
|
ingress: RawServiceIngressRecord,
|
|
2400
2423
|
record: Extract<ServiceStatefulWireRecord, { readonly kind: 'instanceSpot' }>,
|
|
2401
2424
|
payloadFrame: Buffer,
|
|
2402
|
-
spot: ServiceSpotState,
|
|
2425
|
+
spot: Pick<ServiceSpotState, 'ref'>,
|
|
2403
2426
|
localReply?: NonNullable<ServiceStatefulMailboxData['reply']>,
|
|
2404
2427
|
onTerminalCompletion?: NonNullable<ServiceStatefulMailboxData['onTerminalCompletion']>,
|
|
2405
2428
|
metadataFrame?: Buffer,
|
|
2406
|
-
|
|
2429
|
+
onHandlerTurnStarted?: () => void,
|
|
2407
2430
|
applicationTargetOverride?: ServiceInstanceApplicationTarget
|
|
2408
2431
|
): RawServicePumpResult {
|
|
2409
2432
|
let operationKey: string | undefined;
|
|
@@ -2433,10 +2456,6 @@ export class ServiceStatefulRuntime {
|
|
|
2433
2456
|
onTerminalCompletion === undefined
|
|
2434
2457
|
? undefined
|
|
2435
2458
|
: async () => {
|
|
2436
|
-
// The application turn has returned before authority cleanup starts.
|
|
2437
|
-
// Mark it quiescent first so a close requested by that turn can finish
|
|
2438
|
-
// its local cleanup and release the exact authority fence below.
|
|
2439
|
-
this.completeInstanceApplicationOperation(applicationTarget.targetSpotId);
|
|
2440
2459
|
try {
|
|
2441
2460
|
await onTerminalCompletion();
|
|
2442
2461
|
} finally {
|
|
@@ -2451,8 +2470,11 @@ export class ServiceStatefulRuntime {
|
|
|
2451
2470
|
...(record.operationKind === 'request' ? { correlation: record.replyRouteId } : {}),
|
|
2452
2471
|
...(record.sourceSpotId === undefined ? {} : { sourceSpotId: record.sourceSpotId }),
|
|
2453
2472
|
targetSpot: spot.ref,
|
|
2473
|
+
activationRecord: record,
|
|
2474
|
+
...(record.activation === 'missing' ? { deadlineUnixMs: record.deadlineUnixMs } : {}),
|
|
2454
2475
|
...(metadataFrame === undefined ? {} : { applicationMetadata: metadataFrame }),
|
|
2455
2476
|
...(terminalCompletion === undefined ? {} : { onTerminalCompletion: terminalCompletion }),
|
|
2477
|
+
...(onHandlerTurnStarted === undefined ? {} : { onHandlerTurnStarted }),
|
|
2456
2478
|
...(record.operationKind === 'request'
|
|
2457
2479
|
? {
|
|
2458
2480
|
reply:
|
|
@@ -2469,10 +2491,6 @@ export class ServiceStatefulRuntime {
|
|
|
2469
2491
|
this.admittedInstanceOperations.set(operationKey, record.deadlineUnixMs);
|
|
2470
2492
|
}
|
|
2471
2493
|
if (onTerminalCompletion !== undefined && result === 'application') {
|
|
2472
|
-
this.beginInstanceApplicationOperation(applicationTarget.targetSpotId);
|
|
2473
|
-
if (activationTerminal) {
|
|
2474
|
-
this.beginInstanceAuthorityOperation(applicationTarget.targetSpotId);
|
|
2475
|
-
}
|
|
2476
2494
|
this.instanceApplicationLifecycle?.beginTerminal(applicationTarget);
|
|
2477
2495
|
}
|
|
2478
2496
|
return result;
|
|
@@ -2496,15 +2514,16 @@ export class ServiceStatefulRuntime {
|
|
|
2496
2514
|
metadataFrame
|
|
2497
2515
|
);
|
|
2498
2516
|
if (this.closed) return;
|
|
2517
|
+
const terminal = this.activationTerminalCompletion(record.target, activation.route);
|
|
2499
2518
|
const admitted = this.enqueueActivatedInstanceSpot(
|
|
2500
2519
|
ingress,
|
|
2501
2520
|
record,
|
|
2502
2521
|
payloadFrame,
|
|
2503
2522
|
activation.spot,
|
|
2504
2523
|
localReply,
|
|
2505
|
-
|
|
2524
|
+
terminal.onTerminalCompletion,
|
|
2506
2525
|
metadataFrame,
|
|
2507
|
-
|
|
2526
|
+
terminal.onHandlerTurnStarted,
|
|
2508
2527
|
this.instanceApplicationTarget(record, activation.route.objectGeneration)
|
|
2509
2528
|
);
|
|
2510
2529
|
if (admitted !== 'application') {
|
|
@@ -2572,12 +2591,14 @@ export class ServiceStatefulRuntime {
|
|
|
2572
2591
|
const spot = this.requireInstanceActivation(ingress, refreshedRecord);
|
|
2573
2592
|
const admitted = this.enqueueActivatedInstanceSpot(
|
|
2574
2593
|
ingress,
|
|
2575
|
-
|
|
2594
|
+
record,
|
|
2576
2595
|
payloadFrame,
|
|
2577
2596
|
spot,
|
|
2578
2597
|
undefined,
|
|
2579
2598
|
this.instanceApplicationTerminalCompletion(this.instanceApplicationTarget(refreshedRecord)),
|
|
2580
|
-
metadataFrame
|
|
2599
|
+
metadataFrame,
|
|
2600
|
+
undefined,
|
|
2601
|
+
this.instanceApplicationTarget(refreshedRecord)
|
|
2581
2602
|
);
|
|
2582
2603
|
if (admitted !== 'application') {
|
|
2583
2604
|
throw new Error('Rematerialized Instance message was not admitted to the local queue.');
|
|
@@ -2589,23 +2610,39 @@ export class ServiceStatefulRuntime {
|
|
|
2589
2610
|
}
|
|
2590
2611
|
}
|
|
2591
2612
|
|
|
2613
|
+
/**
|
|
2614
|
+
* Spot messaging §4 step 12 with §7 step 1: a Close waits for the first terminal
|
|
2615
|
+
* record only of a message whose handler turn started before it; a message queued
|
|
2616
|
+
* behind that Close is not counted, so it cannot hold the Close it follows.
|
|
2617
|
+
*/
|
|
2592
2618
|
private activationTerminalCompletion(
|
|
2593
2619
|
target: ServiceInstanceActivationTarget,
|
|
2594
2620
|
route: ServiceInstanceRouteFence
|
|
2595
|
-
):
|
|
2621
|
+
): {
|
|
2622
|
+
readonly onTerminalCompletion: () => Promise<void>;
|
|
2623
|
+
readonly onHandlerTurnStarted: () => void;
|
|
2624
|
+
} {
|
|
2596
2625
|
let completion: Promise<void> | undefined;
|
|
2626
|
+
let started = false;
|
|
2597
2627
|
const applicationTarget: ServiceInstanceApplicationTarget = {
|
|
2598
2628
|
targetSpotId: target.targetSpotId,
|
|
2599
2629
|
stableType: target.stableType,
|
|
2600
2630
|
objectGeneration: route.objectGeneration
|
|
2601
2631
|
};
|
|
2602
|
-
|
|
2632
|
+
const onHandlerTurnStarted = (): void => {
|
|
2633
|
+
if (started || completion !== undefined) return;
|
|
2634
|
+
started = true;
|
|
2635
|
+
this.beginInstanceAuthorityOperation(target.targetSpotId);
|
|
2636
|
+
};
|
|
2637
|
+
const onTerminalCompletion = (): Promise<void> =>
|
|
2603
2638
|
(completion ??= (async () => {
|
|
2604
|
-
let authorityCompletionSignaled =
|
|
2639
|
+
let authorityCompletionSignaled = !started;
|
|
2605
2640
|
try {
|
|
2606
2641
|
const released = await this.asyncInstanceAuthority?.complete(target, route);
|
|
2607
|
-
|
|
2608
|
-
|
|
2642
|
+
if (!authorityCompletionSignaled) {
|
|
2643
|
+
this.completeInstanceAuthorityOperation(target.targetSpotId);
|
|
2644
|
+
authorityCompletionSignaled = true;
|
|
2645
|
+
}
|
|
2609
2646
|
if (released !== undefined) {
|
|
2610
2647
|
const authorityReleased =
|
|
2611
2648
|
(await this.instanceApplicationLifecycle?.completeTerminal(applicationTarget)) ??
|
|
@@ -2622,6 +2659,7 @@ export class ServiceStatefulRuntime {
|
|
|
2622
2659
|
}
|
|
2623
2660
|
}
|
|
2624
2661
|
})());
|
|
2662
|
+
return { onTerminalCompletion, onHandlerTurnStarted };
|
|
2625
2663
|
}
|
|
2626
2664
|
|
|
2627
2665
|
private instanceApplicationTerminalCompletion(
|
|
@@ -2666,11 +2704,6 @@ export class ServiceStatefulRuntime {
|
|
|
2666
2704
|
};
|
|
2667
2705
|
}
|
|
2668
2706
|
|
|
2669
|
-
private beginInstanceApplicationOperation(spotId: string): void {
|
|
2670
|
-
const key = String(spotId);
|
|
2671
|
-
this.pendingInstanceTerminals.set(key, (this.pendingInstanceTerminals.get(key) ?? 0) + 1);
|
|
2672
|
-
}
|
|
2673
|
-
|
|
2674
2707
|
private beginInstanceAuthorityOperation(spotId: string): void {
|
|
2675
2708
|
const key = String(spotId);
|
|
2676
2709
|
this.pendingInstanceAuthorityTerminals.set(
|
|
@@ -2679,17 +2712,6 @@ export class ServiceStatefulRuntime {
|
|
|
2679
2712
|
);
|
|
2680
2713
|
}
|
|
2681
2714
|
|
|
2682
|
-
private completeInstanceApplicationOperation(spotId: string): void {
|
|
2683
|
-
const key = String(spotId);
|
|
2684
|
-
const pending = this.pendingInstanceTerminals.get(key);
|
|
2685
|
-
if (pending === undefined || pending <= 1) {
|
|
2686
|
-
this.pendingInstanceTerminals.delete(key);
|
|
2687
|
-
this.completeInstanceApplicationWaitersIfQuiescent(key);
|
|
2688
|
-
return;
|
|
2689
|
-
}
|
|
2690
|
-
this.pendingInstanceTerminals.set(key, pending - 1);
|
|
2691
|
-
}
|
|
2692
|
-
|
|
2693
2715
|
private completeInstanceAuthorityOperation(spotId: string): void {
|
|
2694
2716
|
const key = String(spotId);
|
|
2695
2717
|
const pending = this.pendingInstanceAuthorityTerminals.get(key);
|
|
@@ -2702,11 +2724,7 @@ export class ServiceStatefulRuntime {
|
|
|
2702
2724
|
}
|
|
2703
2725
|
|
|
2704
2726
|
private completeInstanceApplicationWaitersIfQuiescent(key: string): void {
|
|
2705
|
-
if (
|
|
2706
|
-
(this.pendingInstanceTerminals.get(key) ?? 0) !== 0 ||
|
|
2707
|
-
(this.pendingInstanceAuthorityTerminals.get(key) ?? 0) !== 0
|
|
2708
|
-
)
|
|
2709
|
-
return;
|
|
2727
|
+
if ((this.pendingInstanceAuthorityTerminals.get(key) ?? 0) !== 0) return;
|
|
2710
2728
|
const waiters = this.instanceApplicationWaiters.get(key);
|
|
2711
2729
|
if (waiters === undefined) return;
|
|
2712
2730
|
this.instanceApplicationWaiters.delete(key);
|
|
@@ -2855,8 +2873,8 @@ export class ServiceStatefulRuntime {
|
|
|
2855
2873
|
// activation continuation can publish its in-memory intent. If the
|
|
2856
2874
|
// local ready projection already carries the exact object and owner
|
|
2857
2875
|
// fence from the received route, publish that validated projection
|
|
2858
|
-
// instead of
|
|
2859
|
-
//
|
|
2876
|
+
// instead of rejecting a following request while publication finishes.
|
|
2877
|
+
// An absent Ready projection cannot validate the received owner fence.
|
|
2860
2878
|
const local = this.registry.spot(record.route.targetSpotId);
|
|
2861
2879
|
if (
|
|
2862
2880
|
local?.kind === 'instance' &&
|
|
@@ -2869,7 +2887,7 @@ export class ServiceStatefulRuntime {
|
|
|
2869
2887
|
}
|
|
2870
2888
|
if (intent === undefined) {
|
|
2871
2889
|
throw createInternalFrameworkException(
|
|
2872
|
-
ZLinkFrameworkInternalErrorKind.
|
|
2890
|
+
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
2873
2891
|
`Instance Spot '${record.route.targetSpotId}' has no current Ready authority.`
|
|
2874
2892
|
);
|
|
2875
2893
|
}
|
|
@@ -2992,7 +3010,10 @@ export class ServiceStatefulRuntime {
|
|
|
2992
3010
|
>,
|
|
2993
3011
|
payloadFrame: Buffer,
|
|
2994
3012
|
metadataFrame?: Buffer
|
|
2995
|
-
): Promise<{
|
|
3013
|
+
): Promise<{
|
|
3014
|
+
readonly spot: Pick<ServiceSpotState, 'ref'>;
|
|
3015
|
+
readonly route: ServiceInstanceRouteFence;
|
|
3016
|
+
}> {
|
|
2996
3017
|
const key = instanceActivationKey(record);
|
|
2997
3018
|
const pending = this.pendingInstanceActivations.get(key);
|
|
2998
3019
|
if (pending !== undefined) return pending;
|
|
@@ -3014,7 +3035,10 @@ export class ServiceStatefulRuntime {
|
|
|
3014
3035
|
>,
|
|
3015
3036
|
payloadFrame: Buffer,
|
|
3016
3037
|
metadataFrame?: Buffer
|
|
3017
|
-
): Promise<{
|
|
3038
|
+
): Promise<{
|
|
3039
|
+
readonly spot: Pick<ServiceSpotState, 'ref'>;
|
|
3040
|
+
readonly route: ServiceInstanceRouteFence;
|
|
3041
|
+
}> {
|
|
3018
3042
|
const target = record.target;
|
|
3019
3043
|
if (
|
|
3020
3044
|
target.targetNodeRid !== this.nodeRid ||
|
|
@@ -3030,6 +3054,46 @@ export class ServiceStatefulRuntime {
|
|
|
3030
3054
|
|
|
3031
3055
|
const local = this.registry.spot(target.targetSpotId);
|
|
3032
3056
|
const current = await authority.read(target);
|
|
3057
|
+
if (
|
|
3058
|
+
current.kind === 'creating' &&
|
|
3059
|
+
current.authority?.allocation.state === 'active' &&
|
|
3060
|
+
this.instanceApplicationLifecycle?.isMaterializing?.(target) === true
|
|
3061
|
+
) {
|
|
3062
|
+
return {
|
|
3063
|
+
spot: { ref: { spotId: target.targetSpotId, generation: current.objectGeneration } },
|
|
3064
|
+
route: {
|
|
3065
|
+
targetSpotId: target.targetSpotId,
|
|
3066
|
+
targetNodeRid: this.nodeRid,
|
|
3067
|
+
targetNodeGeneration: this.nodeGeneration,
|
|
3068
|
+
objectGeneration: current.objectGeneration,
|
|
3069
|
+
authorityOwnerGeneration: current.authorityOwnerGeneration,
|
|
3070
|
+
ownerId: current.authority.ownerId,
|
|
3071
|
+
leaseGeneration: current.authority.ownerLeaseGeneration,
|
|
3072
|
+
storeVersion: current.authority.storeVersion.value
|
|
3073
|
+
}
|
|
3074
|
+
};
|
|
3075
|
+
}
|
|
3076
|
+
if (
|
|
3077
|
+
current.kind === 'ready' &&
|
|
3078
|
+
current.authority !== undefined &&
|
|
3079
|
+
decodeServiceClosingSpotAuthority(current.authority.payload) !== undefined
|
|
3080
|
+
) {
|
|
3081
|
+
if (current.route.targetNodeRid !== this.nodeRid) {
|
|
3082
|
+
throw new ServiceInstanceActivationRedirectError(current.route);
|
|
3083
|
+
}
|
|
3084
|
+
if (
|
|
3085
|
+
current.route.targetNodeGeneration !== this.nodeGeneration ||
|
|
3086
|
+
(local !== undefined &&
|
|
3087
|
+
!routeMatchesLocal(current.route, local, this.nodeRid, this.nodeGeneration)) ||
|
|
3088
|
+
(local === undefined && this.instanceApplicationLifecycle?.isMaterialized(target) !== true)
|
|
3089
|
+
) {
|
|
3090
|
+
throw new ServiceStaleGenerationError('spot', target.targetSpotId);
|
|
3091
|
+
}
|
|
3092
|
+
return {
|
|
3093
|
+
spot: { ref: { spotId: target.targetSpotId, generation: current.route.objectGeneration } },
|
|
3094
|
+
route: current.route
|
|
3095
|
+
};
|
|
3096
|
+
}
|
|
3033
3097
|
if (!this.acceptsLocalMissingInstancePlacement()) {
|
|
3034
3098
|
if (current.kind === 'ready' && current.route.targetNodeRid !== this.nodeRid) {
|
|
3035
3099
|
throw new ServiceInstanceActivationRedirectError(current.route);
|
|
@@ -3061,7 +3125,6 @@ export class ServiceStatefulRuntime {
|
|
|
3061
3125
|
}
|
|
3062
3126
|
if (local !== undefined) {
|
|
3063
3127
|
const lifecycle = this.instanceApplicationLifecycle;
|
|
3064
|
-
const closing = lifecycle?.isClosing?.(target) === true;
|
|
3065
3128
|
let materialized = lifecycle === undefined ? undefined : lifecycle.isMaterialized(target);
|
|
3066
3129
|
const materializing = lifecycle?.isMaterializing?.(target) === true;
|
|
3067
3130
|
if (local.kind !== 'instance' || local.stableType !== target.stableType) {
|
|
@@ -3071,10 +3134,8 @@ export class ServiceStatefulRuntime {
|
|
|
3071
3134
|
current.kind === 'creating' &&
|
|
3072
3135
|
local.ref.generation === current.objectGeneration &&
|
|
3073
3136
|
local.authorityOwnerGeneration === current.authorityOwnerGeneration;
|
|
3074
|
-
const replacesClosingProjection = current.kind === 'creating' && closing;
|
|
3075
3137
|
if (
|
|
3076
3138
|
current.kind === 'missing' &&
|
|
3077
|
-
!closing &&
|
|
3078
3139
|
!materializing &&
|
|
3079
3140
|
materialized === true &&
|
|
3080
3141
|
lifecycle !== undefined
|
|
@@ -3098,24 +3159,33 @@ export class ServiceStatefulRuntime {
|
|
|
3098
3159
|
// If disposal did not remove an orphaned materialization, keep fencing
|
|
3099
3160
|
// it instead of admitting work into two application generations.
|
|
3100
3161
|
if (
|
|
3101
|
-
(!joinsCreating &&
|
|
3102
|
-
(!joinsCreating &&
|
|
3162
|
+
(!joinsCreating && current.kind !== 'missing') ||
|
|
3163
|
+
(!joinsCreating && materialized !== false && !materializing)
|
|
3103
3164
|
) {
|
|
3104
3165
|
throw new ServiceStaleGenerationError('spot', target.targetSpotId);
|
|
3105
3166
|
}
|
|
3106
3167
|
}
|
|
3107
|
-
const
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3168
|
+
const deadline = operationDeadline(record.deadlineUnixMs);
|
|
3169
|
+
let reserved: ServiceInstanceAuthorityReserve;
|
|
3170
|
+
try {
|
|
3171
|
+
reserved = await authority.reserve(
|
|
3172
|
+
{
|
|
3173
|
+
target,
|
|
3174
|
+
sourceNodeRid: record.sourceNodeRid,
|
|
3175
|
+
sourceNodeGeneration: record.sourceNodeGeneration,
|
|
3176
|
+
...(record.sourceSpotId === undefined ? {} : { sourceSpotId: record.sourceSpotId }),
|
|
3177
|
+
operationKind: record.operationKind,
|
|
3178
|
+
operation: record.operation,
|
|
3179
|
+
...(record.replyRouteId === undefined ? {} : { replyRouteId: record.replyRouteId }),
|
|
3180
|
+
deadlineUnixMs: record.deadlineUnixMs,
|
|
3181
|
+
...(metadataFrame === undefined ? {} : { metadataFrame }),
|
|
3182
|
+
applicationPayloadFrame: payloadFrame
|
|
3183
|
+
},
|
|
3184
|
+
deadline.signal
|
|
3185
|
+
);
|
|
3186
|
+
} finally {
|
|
3187
|
+
deadline.close();
|
|
3188
|
+
}
|
|
3119
3189
|
if (reserved.kind === 'ready') {
|
|
3120
3190
|
throw new ServiceInstanceActivationRedirectError(reserved.route);
|
|
3121
3191
|
}
|
|
@@ -3140,7 +3210,12 @@ export class ServiceStatefulRuntime {
|
|
|
3140
3210
|
}
|
|
3141
3211
|
let committed: Awaited<ReturnType<ServiceAsyncInstanceActivationAuthority['commit']>>;
|
|
3142
3212
|
try {
|
|
3143
|
-
committed = await authority.commit(
|
|
3213
|
+
committed = await authority.commit(
|
|
3214
|
+
target,
|
|
3215
|
+
reserved.reservation,
|
|
3216
|
+
activation.spot,
|
|
3217
|
+
record.deadlineUnixMs
|
|
3218
|
+
);
|
|
3144
3219
|
} catch (error) {
|
|
3145
3220
|
if (activation.created) this.registry.closeSpot(activation.spot.ref);
|
|
3146
3221
|
await this.instanceApplicationLifecycle?.discard(target);
|
|
@@ -3632,7 +3707,15 @@ export class ServiceStatefulRuntime {
|
|
|
3632
3707
|
const accepted = this.raw.mailbox.tryEnqueue({
|
|
3633
3708
|
owner: `actor:${actor.actorId}\0${actor.generation}`,
|
|
3634
3709
|
domain: 'infrastructure',
|
|
3635
|
-
parts: [
|
|
3710
|
+
parts: [
|
|
3711
|
+
Buffer.from([
|
|
3712
|
+
SERVICE_WIRE_MAGIC[0],
|
|
3713
|
+
SERVICE_WIRE_MAGIC[1],
|
|
3714
|
+
SERVICE_WIRE_MAJOR,
|
|
3715
|
+
M6bServiceWireCommand.boundSessionBind,
|
|
3716
|
+
0
|
|
3717
|
+
])
|
|
3718
|
+
],
|
|
3636
3719
|
sourceRoutingId: binding.sessionOwnerNodeRid,
|
|
3637
3720
|
stateful: {
|
|
3638
3721
|
receiveKind: ReceiveKind.ActorBinding,
|
|
@@ -3680,39 +3763,10 @@ export class ServiceStatefulRuntime {
|
|
|
3680
3763
|
return 'protocolError';
|
|
3681
3764
|
}
|
|
3682
3765
|
const sessionRid = delivery.binding.sessionRid;
|
|
3683
|
-
let retainedPayload: Uint8Array | undefined = payloadFrame;
|
|
3684
|
-
let settled = false;
|
|
3685
|
-
const settle = () => {
|
|
3686
|
-
if (settled) return false;
|
|
3687
|
-
settled = true;
|
|
3688
|
-
retainedPayload = undefined;
|
|
3689
|
-
return true;
|
|
3690
|
-
};
|
|
3691
|
-
const operation = {
|
|
3692
|
-
deliver: async () => {
|
|
3693
|
-
if (settled || retainedPayload === undefined) return false;
|
|
3694
|
-
const delivered = await delivery.deliver(sessionRid, retainedPayload);
|
|
3695
|
-
if (delivered) settle();
|
|
3696
|
-
return delivered;
|
|
3697
|
-
},
|
|
3698
|
-
fail: (_error: unknown) => {
|
|
3699
|
-
settle();
|
|
3700
|
-
}
|
|
3701
|
-
};
|
|
3702
|
-
const decision = await delivery.bindingIngress?.retainOutbound(
|
|
3703
|
-
record.actor.actor.actorId,
|
|
3704
|
-
operation
|
|
3705
|
-
);
|
|
3706
|
-
if (decision === 'retained') return 'application';
|
|
3707
|
-
if (decision === 'rejected') {
|
|
3708
|
-
return 'protocolError';
|
|
3709
|
-
}
|
|
3710
3766
|
try {
|
|
3711
|
-
const delivered = await delivery.deliver(sessionRid,
|
|
3712
|
-
settle();
|
|
3767
|
+
const delivered = await delivery.deliver(sessionRid, payloadFrame);
|
|
3713
3768
|
if (!delivered) return 'protocolError';
|
|
3714
3769
|
} catch (error) {
|
|
3715
|
-
operation.fail(error);
|
|
3716
3770
|
// Remote command 36 is one-way: its source transport admission has
|
|
3717
3771
|
// already completed, so a later client delivery terminal is local to
|
|
3718
3772
|
// this session owner. Local fast paths still preserve the typed result.
|
|
@@ -3887,7 +3941,13 @@ export class ServiceStatefulRuntime {
|
|
|
3887
3941
|
control: ActorControlPayload,
|
|
3888
3942
|
onTerminalCompletion?: () => void | Promise<void>
|
|
3889
3943
|
): void {
|
|
3890
|
-
const header = Buffer.from([
|
|
3944
|
+
const header = Buffer.from([
|
|
3945
|
+
SERVICE_WIRE_MAGIC[0],
|
|
3946
|
+
SERVICE_WIRE_MAGIC[1],
|
|
3947
|
+
SERVICE_WIRE_MAJOR,
|
|
3948
|
+
M6bServiceWireCommand.actorJoined,
|
|
3949
|
+
0
|
|
3950
|
+
]);
|
|
3891
3951
|
let terminalAttempted = false;
|
|
3892
3952
|
void (async () => {
|
|
3893
3953
|
const applicationJobOwner = await this.raw.reserveLocalIngress();
|
|
@@ -3933,7 +3993,13 @@ export class ServiceStatefulRuntime {
|
|
|
3933
3993
|
): boolean {
|
|
3934
3994
|
const actor = binding.actor;
|
|
3935
3995
|
const sessionOwner = requireSessionOwnerIdentity(binding);
|
|
3936
|
-
const header = Buffer.from([
|
|
3996
|
+
const header = Buffer.from([
|
|
3997
|
+
SERVICE_WIRE_MAGIC[0],
|
|
3998
|
+
SERVICE_WIRE_MAGIC[1],
|
|
3999
|
+
SERVICE_WIRE_MAJOR,
|
|
4000
|
+
M6bServiceWireCommand.boundSessionBind,
|
|
4001
|
+
0
|
|
4002
|
+
]);
|
|
3937
4003
|
const applicationJob = requireApplicationJobOwner(ingress).takeInitial('infrastructure');
|
|
3938
4004
|
const accepted = this.raw.mailbox.tryEnqueue({
|
|
3939
4005
|
owner: `actor:${actor.actorId}\0${actor.generation}`,
|
|
@@ -4107,7 +4173,7 @@ export class ServiceStatefulRuntime {
|
|
|
4107
4173
|
handler: ServiceUserSpotOperationHandler,
|
|
4108
4174
|
record: ServiceUserSpotCreateRecord | ServiceUserSpotCloseRecord | ServiceActorCreateRecord
|
|
4109
4175
|
): Promise<ServiceUserSpotOperationResult> {
|
|
4110
|
-
const deadline =
|
|
4176
|
+
const deadline = operationDeadline(record.deadlineUnixMs);
|
|
4111
4177
|
try {
|
|
4112
4178
|
const result =
|
|
4113
4179
|
record.kind === 'userSpotCreate'
|
|
@@ -4211,7 +4277,10 @@ export class ServiceStatefulRuntime {
|
|
|
4211
4277
|
stop.signal.throwIfAborted();
|
|
4212
4278
|
if (!durableRequestCanReplay(error)) throw error;
|
|
4213
4279
|
if (durableRequestWasAdmitted(error)) wasAdmitted = true;
|
|
4214
|
-
const retryDelayMs = Math.min(
|
|
4280
|
+
const retryDelayMs = Math.min(
|
|
4281
|
+
STATEFUL_OPERATION_RETRY_TICK_MS,
|
|
4282
|
+
deadlineMs - performance.now()
|
|
4283
|
+
);
|
|
4215
4284
|
if (retryDelayMs <= 0) {
|
|
4216
4285
|
throw durableOperationExhausted(operationKind, wasAdmitted, error);
|
|
4217
4286
|
}
|
|
@@ -4262,8 +4331,8 @@ export class ServiceStatefulRuntime {
|
|
|
4262
4331
|
const applicationJobOwner = await this.raw.reserveLocalIngress();
|
|
4263
4332
|
try {
|
|
4264
4333
|
const result = await this.ingress({
|
|
4265
|
-
command: header[
|
|
4266
|
-
flags: header[
|
|
4334
|
+
command: header[SERVICE_WIRE_COMMAND_OFFSET]!,
|
|
4335
|
+
flags: header[SERVICE_WIRE_FLAGS_OFFSET]!,
|
|
4267
4336
|
sourceRoutingId: this.nodeRid,
|
|
4268
4337
|
requestSequence,
|
|
4269
4338
|
reply: finish,
|
|
@@ -4300,8 +4369,8 @@ export class ServiceStatefulRuntime {
|
|
|
4300
4369
|
void ServiceStatefulRuntime.detachedIngressScope(async () => {
|
|
4301
4370
|
try {
|
|
4302
4371
|
await this.ingress({
|
|
4303
|
-
command: parts[0]![
|
|
4304
|
-
flags: parts[0]![
|
|
4372
|
+
command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
|
|
4373
|
+
flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
|
|
4305
4374
|
sourceRoutingId: this.nodeRid,
|
|
4306
4375
|
sourceNodeGeneration: this.nodeGeneration,
|
|
4307
4376
|
parts,
|
|
@@ -4319,8 +4388,8 @@ export class ServiceStatefulRuntime {
|
|
|
4319
4388
|
}
|
|
4320
4389
|
try {
|
|
4321
4390
|
const result = await this.ingress({
|
|
4322
|
-
command: parts[0]![
|
|
4323
|
-
flags: parts[0]![
|
|
4391
|
+
command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
|
|
4392
|
+
flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
|
|
4324
4393
|
sourceRoutingId: this.nodeRid,
|
|
4325
4394
|
sourceNodeGeneration: this.nodeGeneration,
|
|
4326
4395
|
parts,
|
|
@@ -4361,17 +4430,23 @@ export class ServiceStatefulRuntime {
|
|
|
4361
4430
|
): void {
|
|
4362
4431
|
if (targetNodeRid === this.nodeRid) {
|
|
4363
4432
|
const deadlineUnixMs = BigInt(Date.now() + Math.max(0, timeoutMs));
|
|
4433
|
+
const capacityStop = new AbortController();
|
|
4434
|
+
void pending.promise.then(
|
|
4435
|
+
() => capacityStop.abort(),
|
|
4436
|
+
() => capacityStop.abort()
|
|
4437
|
+
);
|
|
4364
4438
|
void (async () => {
|
|
4365
|
-
const applicationJobOwner = await this.raw.reserveLocalIngress();
|
|
4366
|
-
const localIngress: RawServiceIngressRecord = {
|
|
4367
|
-
command: parts[0]![3]!,
|
|
4368
|
-
flags: parts[0]![4]!,
|
|
4369
|
-
sourceRoutingId: this.nodeRid,
|
|
4370
|
-
requestSequence: pending.id,
|
|
4371
|
-
parts,
|
|
4372
|
-
applicationJobOwner
|
|
4373
|
-
};
|
|
4439
|
+
const applicationJobOwner = await this.raw.reserveLocalIngress(capacityStop.signal);
|
|
4374
4440
|
try {
|
|
4441
|
+
if (!this.operations.isPending(pending.id)) return;
|
|
4442
|
+
const localIngress: RawServiceIngressRecord = {
|
|
4443
|
+
command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
|
|
4444
|
+
flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
|
|
4445
|
+
sourceRoutingId: this.nodeRid,
|
|
4446
|
+
requestSequence: pending.id,
|
|
4447
|
+
parts,
|
|
4448
|
+
applicationJobOwner
|
|
4449
|
+
};
|
|
4375
4450
|
await this.submitLocalRequest(
|
|
4376
4451
|
localIngress,
|
|
4377
4452
|
pending,
|
|
@@ -4407,10 +4482,10 @@ export class ServiceStatefulRuntime {
|
|
|
4407
4482
|
? this.tryActorFence(actor)
|
|
4408
4483
|
: this.acceptCanonicalActorFence(actor, canonical.actorFence);
|
|
4409
4484
|
if (target === undefined || actorRoute === undefined) {
|
|
4410
|
-
this.operations.reply(
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4485
|
+
this.operations.reply(
|
|
4486
|
+
pending.id,
|
|
4487
|
+
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
|
|
4488
|
+
);
|
|
4414
4489
|
return;
|
|
4415
4490
|
}
|
|
4416
4491
|
if (canonical !== undefined) {
|
|
@@ -4544,7 +4619,6 @@ export class ServiceStatefulRuntime {
|
|
|
4544
4619
|
this.resultFromReply(terminalResult, failureCode, replyPayload, tail, this.nodeRid, actor)
|
|
4545
4620
|
);
|
|
4546
4621
|
if (decoded.kind === 'spotRequest') {
|
|
4547
|
-
await this.spotAdmissionProvider?.awaitCloseDecision?.(decoded.target.spot.spotId);
|
|
4548
4622
|
this.validateDirectSpotFence(decoded.target);
|
|
4549
4623
|
this.enqueueApplicationFrame(ingress, `spot:${decoded.target.spot.spotId}`, payloadFrame!, {
|
|
4550
4624
|
receiveKind: ReceiveKind.SpotRequest,
|
|
@@ -4881,7 +4955,6 @@ export class ServiceStatefulRuntime {
|
|
|
4881
4955
|
`Spot '${fence.spot.spotId}' targets an unavailable owner route.`
|
|
4882
4956
|
);
|
|
4883
4957
|
}
|
|
4884
|
-
this.requireDirectSpotAdmission(fence.spot.spotId);
|
|
4885
4958
|
const spot = this.registry.spot(fence.spot.spotId);
|
|
4886
4959
|
if (spot === undefined) {
|
|
4887
4960
|
throw createInternalFrameworkException(
|
|
@@ -4926,21 +4999,6 @@ export class ServiceStatefulRuntime {
|
|
|
4926
4999
|
return spot;
|
|
4927
5000
|
}
|
|
4928
5001
|
|
|
4929
|
-
private requireDirectSpotAdmission(spotId: string): void {
|
|
4930
|
-
if (this.spotAdmissionProvider?.runtimeState() === ZLinkFrameworkRuntimeState.Draining) {
|
|
4931
|
-
throw createInternalFrameworkException(
|
|
4932
|
-
ZLinkFrameworkInternalErrorKind.RuntimeShutdown,
|
|
4933
|
-
`Spot '${spotId}' owner is Draining.`
|
|
4934
|
-
);
|
|
4935
|
-
}
|
|
4936
|
-
if (this.spotAdmissionProvider?.isClosing(spotId) === true) {
|
|
4937
|
-
throw createInternalFrameworkException(
|
|
4938
|
-
ZLinkFrameworkInternalErrorKind.RequestRejected,
|
|
4939
|
-
`Spot '${spotId}' authority is Closing.`
|
|
4940
|
-
);
|
|
4941
|
-
}
|
|
4942
|
-
}
|
|
4943
|
-
|
|
4944
5002
|
private holdOrRelaySpotMessage(
|
|
4945
5003
|
ingress: RawServiceIngressRecord,
|
|
4946
5004
|
wire: Extract<ServiceStatefulWireRecord, { readonly kind: 'spotSend' | 'spotRequest' }>
|
|
@@ -4998,7 +5056,10 @@ export class ServiceStatefulRuntime {
|
|
|
4998
5056
|
}
|
|
4999
5057
|
const current = this.peekSpotMessageFollow(state)!;
|
|
5000
5058
|
try {
|
|
5001
|
-
const metadata =
|
|
5059
|
+
const metadata =
|
|
5060
|
+
(current.ingress.parts[0]![SERVICE_WIRE_FLAGS_OFFSET]! &
|
|
5061
|
+
M6bServiceWireFlag.metadata) !==
|
|
5062
|
+
0;
|
|
5002
5063
|
const parts = [
|
|
5003
5064
|
encodeSpotHeader(
|
|
5004
5065
|
current.wire.kind,
|
|
@@ -5137,7 +5198,7 @@ export class ServiceStatefulRuntime {
|
|
|
5137
5198
|
if (state.queuedCount === 0) {
|
|
5138
5199
|
state.queued.length = 0;
|
|
5139
5200
|
state.queuedHead = 0;
|
|
5140
|
-
} else if (state.queuedHead
|
|
5201
|
+
} else if (shouldCompactBackingArray(state.queuedHead, state.queued.length)) {
|
|
5141
5202
|
state.queued.splice(0, state.queuedHead);
|
|
5142
5203
|
state.queuedHead = 0;
|
|
5143
5204
|
}
|
|
@@ -5358,28 +5419,6 @@ export class ServiceStatefulRuntime {
|
|
|
5358
5419
|
}
|
|
5359
5420
|
}
|
|
5360
5421
|
|
|
5361
|
-
function serviceSpotPublishFailureReason(
|
|
5362
|
-
result: number | undefined,
|
|
5363
|
-
routeReady: boolean,
|
|
5364
|
-
closed: boolean
|
|
5365
|
-
): 'stale_target' | 'backpressure' | 'shutdown' {
|
|
5366
|
-
if (closed || result === SubmitResult.Terminated) return 'shutdown';
|
|
5367
|
-
switch (result) {
|
|
5368
|
-
case SubmitResult.Backpressured:
|
|
5369
|
-
return 'backpressure';
|
|
5370
|
-
case SubmitResult.NotAdmitted:
|
|
5371
|
-
case SubmitResult.NotConnected:
|
|
5372
|
-
case SubmitResult.NotFound:
|
|
5373
|
-
case SubmitResult.InvalidHandle:
|
|
5374
|
-
return 'stale_target';
|
|
5375
|
-
default:
|
|
5376
|
-
// RawServiceMeshRuntime exposes failed Core submissions as false. A
|
|
5377
|
-
// ready route therefore identifies queue admission failure; a route
|
|
5378
|
-
// that became unready after selection is a stale target.
|
|
5379
|
-
return routeReady ? 'backpressure' : 'stale_target';
|
|
5380
|
-
}
|
|
5381
|
-
}
|
|
5382
|
-
|
|
5383
5422
|
function isEntrySpotFence(fence: ServiceSpotRouteFence): boolean {
|
|
5384
5423
|
return (
|
|
5385
5424
|
fence.spot.spotId === fence.targetNodeRid &&
|
|
@@ -5389,16 +5428,23 @@ function isEntrySpotFence(fence: ServiceSpotRouteFence): boolean {
|
|
|
5389
5428
|
);
|
|
5390
5429
|
}
|
|
5391
5430
|
|
|
5392
|
-
function
|
|
5431
|
+
function operationDeadline(deadlineUnixMs: bigint): {
|
|
5393
5432
|
readonly signal: AbortSignal;
|
|
5394
5433
|
close(): void;
|
|
5395
5434
|
} {
|
|
5396
5435
|
const controller = new AbortController();
|
|
5397
5436
|
const delay = Number(deadlineUnixMs - BigInt(Date.now()));
|
|
5398
|
-
const
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5437
|
+
const expire = () =>
|
|
5438
|
+
controller.abort(
|
|
5439
|
+
createInternalFrameworkException(
|
|
5440
|
+
ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
|
|
5441
|
+
'Operation deadline exceeded.'
|
|
5442
|
+
)
|
|
5443
|
+
);
|
|
5444
|
+
const timeout =
|
|
5445
|
+
delay <= 0
|
|
5446
|
+
? (expire(), undefined)
|
|
5447
|
+
: setTimeout(expire, Math.min(delay, MAX_NODE_TIMER_DELAY_MS));
|
|
5402
5448
|
return {
|
|
5403
5449
|
signal: controller.signal,
|
|
5404
5450
|
close: () => clearTimeout(timeout)
|
|
@@ -5479,12 +5525,12 @@ function actorLocation(actor: ServiceActorState): ActorLocation {
|
|
|
5479
5525
|
|
|
5480
5526
|
function failure(error: unknown): ServiceStatefulResult {
|
|
5481
5527
|
if (error instanceof ServiceStaleGenerationError) {
|
|
5482
|
-
return
|
|
5528
|
+
return internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale);
|
|
5483
5529
|
}
|
|
5484
5530
|
if (error instanceof ZLinkFrameworkException) {
|
|
5485
5531
|
return internalFrameworkWireReply(error);
|
|
5486
5532
|
}
|
|
5487
|
-
return
|
|
5533
|
+
return internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.RequestFailed);
|
|
5488
5534
|
}
|
|
5489
5535
|
|
|
5490
5536
|
function actorKey(actor: ServiceActorRef): string {
|
|
@@ -5877,7 +5923,7 @@ function topicMatches(filter: string, topic: string): boolean {
|
|
|
5877
5923
|
function emptyPayload(): ServiceApplicationPayload {
|
|
5878
5924
|
return {
|
|
5879
5925
|
packetName: 'ZLinkFrameworkEmpty',
|
|
5880
|
-
contentType:
|
|
5926
|
+
contentType: ZlinkStreamContentType.Raw,
|
|
5881
5927
|
payload: Buffer.alloc(0)
|
|
5882
5928
|
};
|
|
5883
5929
|
}
|