@zlink-systems/framework 0.30.1 → 0.30.2
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/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +4 -0
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +0 -1
- package/dist/runtime/actors/actor-client.js +38 -45
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +7 -3
- package/dist/runtime/actors/actor-handoff.js +212 -88
- package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
- package/dist/runtime/actors/actor-local-native-join.js +4 -0
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +6 -2
- package/dist/runtime/actors/index.js +37 -21
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +55 -32
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
- package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
- package/dist/runtime/application-jobs/contracts.d.ts +2 -0
- package/dist/runtime/backend/contracts/index.d.ts +19 -3
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.js +5 -0
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
- package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +20 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
- package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatchers.js +44 -37
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +74 -31
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
- package/dist/runtime/channels/channel-runtime-manager.js +4 -4
- package/dist/runtime/channels/channel-transports.d.ts +0 -1
- package/dist/runtime/channels/channel-transports.js +35 -33
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
- package/dist/runtime/execution/serial-execution-queue.js +21 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
- package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +24 -3
- package/dist/runtime/host/application-job-queue.js +28 -41
- package/dist/runtime/host/index.d.ts +5 -1
- package/dist/runtime/host/index.js +171 -97
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +71 -190
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +5 -3
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
- package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
- package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +6 -2
- package/dist/runtime/locations/runtime.js +37 -30
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.js +29 -26
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
- package/dist/runtime/spots/index.d.ts +18 -11
- package/dist/runtime/spots/index.js +234 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +6 -3
- package/dist/runtime/spots/spot-activation.js +123 -44
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +14 -9
- package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
- package/dist/runtime/spots/spot-handler-registry.js +6 -2
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.js +3 -3
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +287 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.js +1 -4
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +8 -0
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +61 -70
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +282 -106
- package/src/runtime/actors/actor-join-relocation.ts +2 -0
- package/src/runtime/actors/actor-local-native-join.ts +4 -0
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +41 -27
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/admission.ts +69 -34
- package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
- package/src/runtime/application-jobs/contracts.ts +2 -0
- package/src/runtime/backend/contracts/index.ts +39 -4
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +4 -0
- package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
- package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
- package/src/runtime/channels/channel-clients.ts +49 -24
- package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
- package/src/runtime/channels/channel-dispatchers.ts +116 -72
- package/src/runtime/channels/channel-envelope.ts +105 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +12 -5
- package/src/runtime/channels/channel-transports.ts +49 -58
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
- package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +29 -44
- package/src/runtime/host/index.ts +286 -129
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +86 -248
- package/src/runtime/host/route-mesh-runtime.ts +11 -5
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
- package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +70 -40
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +33 -29
- package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
- package/src/runtime/spots/index.ts +375 -281
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +170 -86
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +24 -19
- package/src/runtime/spots/spot-handler-registry.ts +15 -4
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +3 -3
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-runtime-ports.ts +0 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
- package/src/runtime/spots/spot-timer.ts +413 -157
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +1 -5
- package/src/runtime/workers/index.ts +1 -1
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import type { RoutingId } from '../../contracts';
|
|
2
|
+
import { type ServiceSessionRelocationRoute, type ServiceSessionRelocationSeal, type ServiceSessionRelocationSealed } from '../foundation/service-stateful-wire-codec';
|
|
3
|
+
export interface ZLinkPreparedSessionRelocationSeal {
|
|
4
|
+
readonly response: ServiceSessionRelocationSealed;
|
|
5
|
+
readonly ready: Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
interface SessionRelocationResult extends ZLinkPreparedSessionRelocationSeal {
|
|
8
|
+
readonly key: string;
|
|
9
|
+
readonly fingerprint: string;
|
|
10
|
+
readonly seal?: ZLinkActorSessionRelocationState;
|
|
11
|
+
}
|
|
1
12
|
export declare const DEFAULT_TERMINAL_RELOCATION_CAPACITY = 4096;
|
|
2
13
|
export interface ZLinkActorSessionBindingActor {
|
|
3
14
|
readonly actorId: string;
|
|
@@ -7,7 +18,7 @@ export interface ZLinkActorSessionBindingActor {
|
|
|
7
18
|
};
|
|
8
19
|
}
|
|
9
20
|
export interface ZLinkActorSessionBindingContext<TActor extends ZLinkActorSessionBindingActor> {
|
|
10
|
-
readonly routingId?:
|
|
21
|
+
readonly routingId?: RoutingId;
|
|
11
22
|
readonly actorSlotControls?: {
|
|
12
23
|
enqueueBound(actorSlot: number, actorId: string): Promise<void>;
|
|
13
24
|
enqueueUnbound(actorSlot: number): Promise<void>;
|
|
@@ -20,17 +31,18 @@ export interface ZLinkActorSessionRoute<TContext extends ZLinkActorSessionBindin
|
|
|
20
31
|
readonly actor: TActor;
|
|
21
32
|
readonly bindingToken: string;
|
|
22
33
|
readonly actorSlot?: number;
|
|
23
|
-
readonly sessionIdentity?:
|
|
34
|
+
readonly sessionIdentity?: RoutingId;
|
|
24
35
|
readonly activeFrames: ZLinkActorSessionActiveFrames;
|
|
25
36
|
sealId?: string;
|
|
37
|
+
sessionRelocationResult?: SessionRelocationResult;
|
|
26
38
|
authorityFence?: ZLinkActorSessionAuthorityFence;
|
|
27
39
|
}
|
|
28
40
|
export interface ZLinkActorSessionRelocationClaim {
|
|
29
41
|
readonly actorId: string;
|
|
30
42
|
readonly actorGeneration: bigint;
|
|
31
43
|
readonly bindingGeneration: bigint;
|
|
32
|
-
readonly sessionIdentity?:
|
|
33
|
-
readonly actorNodeRid?:
|
|
44
|
+
readonly sessionIdentity?: RoutingId;
|
|
45
|
+
readonly actorNodeRid?: RoutingId;
|
|
34
46
|
readonly actorNodeGeneration?: bigint;
|
|
35
47
|
readonly sealId: string;
|
|
36
48
|
}
|
|
@@ -57,6 +69,21 @@ interface ZLinkActorSessionActiveFrames {
|
|
|
57
69
|
captureBySeal(): void;
|
|
58
70
|
}>;
|
|
59
71
|
}
|
|
72
|
+
interface ZLinkActorSessionRelocationState {
|
|
73
|
+
readonly actorId: string;
|
|
74
|
+
readonly actorGeneration: bigint;
|
|
75
|
+
readonly bindingGeneration: bigint;
|
|
76
|
+
readonly sessionIdentity?: RoutingId;
|
|
77
|
+
readonly actorNodeRid?: RoutingId;
|
|
78
|
+
readonly actorNodeGeneration?: bigint;
|
|
79
|
+
readonly sealId: string;
|
|
80
|
+
phase: 'sealed' | 'applying' | 'applied' | 'terminal';
|
|
81
|
+
applyFingerprint?: string;
|
|
82
|
+
applyPromise?: Promise<void>;
|
|
83
|
+
readonly ready: Promise<void>;
|
|
84
|
+
readonly terminal: Promise<void>;
|
|
85
|
+
readonly resolveTerminal: () => void;
|
|
86
|
+
}
|
|
60
87
|
export interface ZLinkActorSessionAuthorityFence {
|
|
61
88
|
readonly authorityOwnerGeneration: bigint;
|
|
62
89
|
readonly ownerLeaseGeneration: bigint;
|
|
@@ -79,21 +106,22 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
|
|
|
79
106
|
private readonly sealWaiters;
|
|
80
107
|
private readonly activeFrameWaiters;
|
|
81
108
|
private readonly relocations;
|
|
109
|
+
private readonly absentSessionRelocationResults;
|
|
82
110
|
private readonly terminalRelocations;
|
|
83
111
|
constructor(terminalRelocationCapacity?: number, sealWaitTimeoutMs?: number, errorSink?: (() => {
|
|
84
112
|
reportRuntimeTaskException(taskName: string, error: unknown): void;
|
|
85
113
|
} | undefined) | undefined);
|
|
86
|
-
bind(context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?:
|
|
114
|
+
bind(context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: RoutingId, commitActor?: () => void): Promise<void>;
|
|
87
115
|
private commitCore;
|
|
88
116
|
private issueActorSlot;
|
|
89
|
-
replace(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?:
|
|
90
|
-
replaceAndReleaseSeal(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, sealId: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?:
|
|
117
|
+
replace(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: RoutingId, commitActor?: () => void): Promise<void>;
|
|
118
|
+
replaceAndReleaseSeal(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, sealId: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: RoutingId, commitActor?: () => void): Promise<void>;
|
|
91
119
|
private replaceAndReleaseSealCore;
|
|
92
120
|
find(actorId: string): Promise<TActor | undefined>;
|
|
93
121
|
private findCore;
|
|
94
122
|
route(actorId: string): Promise<ZLinkActorSessionRoute<TContext, TActor> | undefined>;
|
|
95
123
|
/** Selects the route only when it is the exact Session binding (§8.1 validation values). */
|
|
96
|
-
routeForSessionBinding(actorId: string, sessionRid:
|
|
124
|
+
routeForSessionBinding(actorId: string, sessionRid: RoutingId, bindingGeneration?: bigint): Promise<ZLinkActorSessionRoute<TContext, TActor> | undefined>;
|
|
97
125
|
private routeCore;
|
|
98
126
|
capturePendingReplyClaim(actorId: string, actor: ZLinkActorSessionBindingActor, bindingToken: string): Promise<{
|
|
99
127
|
readonly context: TContext;
|
|
@@ -131,11 +159,16 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
|
|
|
131
159
|
seal(actorId: string, sealId: string, expected: ZLinkActorSessionRouteFence): Promise<void>;
|
|
132
160
|
private sealCore;
|
|
133
161
|
sealAndWait(actorId: string, sealId: string, expected: ZLinkActorSessionRouteFence, signal?: AbortSignal): Promise<void>;
|
|
162
|
+
prepareSessionRelocationSeal(value: ServiceSessionRelocationSeal, signal?: AbortSignal): Promise<ZLinkPreparedSessionRelocationSeal | undefined>;
|
|
163
|
+
private prepareSessionRelocationSealCore;
|
|
164
|
+
acceptSessionRelocationRoute(value: ServiceSessionRelocationRoute, apply: () => Promise<void>): Promise<boolean>;
|
|
165
|
+
clearSessionRelocationResults(): Promise<void>;
|
|
134
166
|
sealRelocation(claim: ZLinkActorSessionRelocationClaim, expected: ZLinkActorSessionRouteFence, signal?: AbortSignal): Promise<void>;
|
|
135
167
|
private prepareRelocationSeal;
|
|
136
168
|
relocationSnapshot(actorId: string, sealId: string): Promise<ZLinkActorSessionRelocationSnapshot | undefined>;
|
|
137
169
|
private relocationSnapshotCore;
|
|
138
170
|
applyRelocation(actorId: string, sealId: string, applyFingerprint: string, commitOwnerTransition: () => Promise<void>): Promise<void>;
|
|
171
|
+
private runRelocationApply;
|
|
139
172
|
private prepareRelocationApply;
|
|
140
173
|
private completeRelocationApply;
|
|
141
174
|
private failRelocationApply;
|
|
@@ -149,7 +182,7 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
|
|
|
149
182
|
* single physical route's disconnect, which must not disturb a relocation
|
|
150
183
|
* seal it does not own (see `clearRouteRelocation`).
|
|
151
184
|
*/
|
|
152
|
-
clearRelocation(actorId: string, error: unknown): Promise<void>;
|
|
185
|
+
clearRelocation(actorId: string, error: unknown, sealId?: string): Promise<void>;
|
|
153
186
|
private clearRelocationCore;
|
|
154
187
|
/**
|
|
155
188
|
* Spec 48 §137: a relocation seal's lifecycle is independent of any single
|
|
@@ -165,8 +198,6 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
|
|
|
165
198
|
private clearRouteRelocation;
|
|
166
199
|
abortSeal(actorId: string, sealId: string): Promise<boolean>;
|
|
167
200
|
private abortSealCore;
|
|
168
|
-
updateAuthorityFence(actorId: string, authorityFence: ZLinkActorSessionAuthorityFence): Promise<void>;
|
|
169
|
-
private updateAuthorityFenceCore;
|
|
170
201
|
validateSeal(actorId: string, sealId: string): Promise<boolean>;
|
|
171
202
|
private validateSealCore;
|
|
172
203
|
/** True while a relocation seal currently holds this actor's ingress. */
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkActorSessionBindingRegistry = exports.ZLinkActorSessionBindingTermination = exports.DEFAULT_TERMINAL_RELOCATION_CAPACITY = void 0;
|
|
4
|
-
const node_async_hooks_1 = require("node:async_hooks");
|
|
5
4
|
const ZLinkFrameworkException_1 = require("../../contracts/Errors/ZLinkFrameworkException");
|
|
6
5
|
const Options_1 = require("../../contracts/Locations/Options");
|
|
7
6
|
const abort_1 = require("../abort");
|
|
8
7
|
const state_lane_1 = require("../execution/state-lane");
|
|
8
|
+
const routing_id_1 = require("../routing-id");
|
|
9
9
|
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
10
|
+
const service_stateful_wire_codec_1 = require("../foundation/service-stateful-wire-codec");
|
|
11
|
+
const service_wire_m6a_codec_1 = require("../foundation/service-wire-m6a-codec");
|
|
12
|
+
const bound_session_wire_1 = require("../actors/bound-session-wire");
|
|
10
13
|
exports.DEFAULT_TERMINAL_RELOCATION_CAPACITY = 4096;
|
|
11
|
-
const detachedStateLaneResource = new node_async_hooks_1.AsyncResource('zlink:actor-session-binding-registry');
|
|
12
14
|
var ZLinkActorSessionBindingTermination;
|
|
13
15
|
(function (ZLinkActorSessionBindingTermination) {
|
|
14
16
|
ZLinkActorSessionBindingTermination[ZLinkActorSessionBindingTermination["BindingEnd"] = 0] = "BindingEnd";
|
|
@@ -24,6 +26,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
24
26
|
sealWaiters = new Map();
|
|
25
27
|
activeFrameWaiters = new Map();
|
|
26
28
|
relocations = new Map();
|
|
29
|
+
absentSessionRelocationResults = new Map();
|
|
27
30
|
terminalRelocations = new Map();
|
|
28
31
|
constructor(terminalRelocationCapacity = exports.DEFAULT_TERMINAL_RELOCATION_CAPACITY,
|
|
29
32
|
// Spec 06 — SessionRelocationSealTimeout bounds how long a session
|
|
@@ -51,26 +54,20 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
51
54
|
if (current !== previous) {
|
|
52
55
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorSessionNotBound, `Actor '${actor.actorId}' session binding changed before route commit.`, true);
|
|
53
56
|
}
|
|
57
|
+
const currentSessionIdentity = sessionIdentity ?? sessionIdentityFromContext(context);
|
|
54
58
|
const sameBinding = previous !== undefined &&
|
|
55
|
-
previous.
|
|
56
|
-
previous.
|
|
59
|
+
previous.bindingToken === bindingToken &&
|
|
60
|
+
(previous.context === context ||
|
|
61
|
+
(previous.sessionIdentity !== undefined &&
|
|
62
|
+
currentSessionIdentity !== undefined &&
|
|
63
|
+
(0, routing_id_1.routingIdsEqual)(previous.sessionIdentity, currentSessionIdentity)));
|
|
57
64
|
const actorSlot = sameBinding ? previous.actorSlot : this.issueActorSlot(context);
|
|
58
65
|
commitActor?.();
|
|
59
66
|
context.bindLocal(actor, bindingToken, actorSlot);
|
|
60
67
|
try {
|
|
61
68
|
if (previous !== undefined && !sameBinding) {
|
|
62
|
-
this.
|
|
63
|
-
|
|
64
|
-
if (previous.actorSlot !== undefined) {
|
|
65
|
-
let unbound;
|
|
66
|
-
try {
|
|
67
|
-
unbound = previous.context.actorSlotControls?.enqueueUnbound(previous.actorSlot);
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
unbound = Promise.reject(error);
|
|
71
|
-
}
|
|
72
|
-
void unbound?.catch((error) => this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error));
|
|
73
|
-
}
|
|
69
|
+
const unbound = this.unbindCore(actor.actorId, previous.context, previous.bindingToken, ZLinkActorSessionBindingTermination.BindingEnd);
|
|
70
|
+
void unbound?.catch((error) => this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error));
|
|
74
71
|
}
|
|
75
72
|
if (!sameBinding && actorSlot !== undefined) {
|
|
76
73
|
// Session–Actor binding §5-2: `$zlink.actor.bound` enters the ordered
|
|
@@ -90,15 +87,19 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
90
87
|
context.unbindLocal(actor.actorId, bindingToken);
|
|
91
88
|
throw error;
|
|
92
89
|
}
|
|
90
|
+
const bindingState = sameBinding ? previous : undefined;
|
|
93
91
|
this.routes.set(actor.actorId, {
|
|
94
92
|
context,
|
|
95
93
|
actor,
|
|
96
94
|
bindingToken,
|
|
97
95
|
actorSlot,
|
|
98
|
-
sessionIdentity:
|
|
96
|
+
sessionIdentity: currentSessionIdentity,
|
|
97
|
+
// Accepted frames retain their completion fence across route replacement;
|
|
98
|
+
// the successor's seal must still drain them (Session binding §8.1).
|
|
99
99
|
activeFrames: previous?.activeFrames ?? { count: 0, requests: new Set() },
|
|
100
|
-
sealId:
|
|
101
|
-
|
|
100
|
+
sealId: bindingState?.sealId,
|
|
101
|
+
sessionRelocationResult: bindingState?.sessionRelocationResult,
|
|
102
|
+
authorityFence: authorityFence ?? bindingState?.authorityFence
|
|
102
103
|
});
|
|
103
104
|
}
|
|
104
105
|
issueActorSlot(context) {
|
|
@@ -143,7 +144,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
143
144
|
return await this.lane.run(() => {
|
|
144
145
|
const route = this.routeCore(actorId);
|
|
145
146
|
const generation = route?.actor.ref.bindingGeneration;
|
|
146
|
-
return route?.sessionIdentity
|
|
147
|
+
return (0, routing_id_1.routingIdsEqual)(route?.sessionIdentity, sessionRid) &&
|
|
147
148
|
(bindingGeneration === undefined || generation === bindingGeneration)
|
|
148
149
|
? route
|
|
149
150
|
: undefined;
|
|
@@ -181,7 +182,12 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
181
182
|
this.clearRouteRelocation(actorId, route);
|
|
182
183
|
if (termination === ZLinkActorSessionBindingTermination.BindingEnd &&
|
|
183
184
|
route.actorSlot !== undefined) {
|
|
184
|
-
|
|
185
|
+
try {
|
|
186
|
+
return context.actorSlotControls?.enqueueUnbound(route.actorSlot);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
return Promise.reject(error);
|
|
190
|
+
}
|
|
185
191
|
}
|
|
186
192
|
return undefined;
|
|
187
193
|
}
|
|
@@ -409,6 +415,120 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
409
415
|
await this.lane.run(() => this.sealCore(actorId, sealId, expected));
|
|
410
416
|
await this.waitForActiveFrames(actorId, signal);
|
|
411
417
|
}
|
|
418
|
+
async prepareSessionRelocationSeal(value, signal) {
|
|
419
|
+
for (;;) {
|
|
420
|
+
const step = await this.lane.run(() => this.prepareSessionRelocationSealCore(value, signal));
|
|
421
|
+
if (step === undefined || !('predecessor' in step))
|
|
422
|
+
return step;
|
|
423
|
+
await waitForSessionRelocation(step.predecessor, signal);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
prepareSessionRelocationSealCore(value, signal) {
|
|
427
|
+
const actorId = value.actor.actor.actorId;
|
|
428
|
+
const key = (0, service_stateful_wire_codec_1.serviceSessionRelocationIdentityKey)(value);
|
|
429
|
+
const fingerprint = (0, service_stateful_wire_codec_1.encodeSessionRelocationSeal)(value).toString('base64');
|
|
430
|
+
const route = this.routes.get(actorId);
|
|
431
|
+
const bindingResult = route?.sessionRelocationResult;
|
|
432
|
+
const recorded = this.absentSessionRelocationResults.get(key)?.result ??
|
|
433
|
+
(bindingResult?.key === key ? bindingResult : undefined);
|
|
434
|
+
if (recorded !== undefined) {
|
|
435
|
+
if (recorded.fingerprint !== fingerprint) {
|
|
436
|
+
throw new service_wire_m6a_codec_1.ServiceWireProtocolError(`Session relocation '${key}' repeated command 42 with different bytes.`);
|
|
437
|
+
}
|
|
438
|
+
if (recorded.seal?.phase === 'terminal') {
|
|
439
|
+
console.warn(`late_session_relocation_seal session=${value.session.sessionRid}`);
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
return recorded;
|
|
443
|
+
}
|
|
444
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
445
|
+
const response = {
|
|
446
|
+
relocation: value.relocation,
|
|
447
|
+
coordinator: value.coordinator,
|
|
448
|
+
actor: value.actor,
|
|
449
|
+
session: value.session,
|
|
450
|
+
sealResult: route === undefined ? 'bindingAbsent' : 'sealed'
|
|
451
|
+
};
|
|
452
|
+
if (route === undefined) {
|
|
453
|
+
const result = {
|
|
454
|
+
key,
|
|
455
|
+
fingerprint,
|
|
456
|
+
response,
|
|
457
|
+
ready: Promise.resolve()
|
|
458
|
+
};
|
|
459
|
+
const expiry = (0, state_lane_1.startOutsideStateLane)(() => setTimeout(() => {
|
|
460
|
+
void (async () => {
|
|
461
|
+
await this.lane.run(() => this.absentSessionRelocationResults.delete(key));
|
|
462
|
+
})().catch((error) => this.errorSink?.()?.reportRuntimeTaskException('session relocation result expiry', error));
|
|
463
|
+
}, this.sealWaitTimeoutMs));
|
|
464
|
+
expiry.unref();
|
|
465
|
+
this.absentSessionRelocationResults.set(key, { result, expiry });
|
|
466
|
+
return result;
|
|
467
|
+
}
|
|
468
|
+
const expected = {
|
|
469
|
+
objectGeneration: value.actor.actor.generation,
|
|
470
|
+
bindingGeneration: value.session.bindingGeneration
|
|
471
|
+
};
|
|
472
|
+
if (!(0, routing_id_1.routingIdsEqual)(route.sessionIdentity, value.session.sessionRid) ||
|
|
473
|
+
!routeMatchesFence(route, expected) ||
|
|
474
|
+
(route.authorityFence !== undefined &&
|
|
475
|
+
value.actor.ownerLeaseGeneration < route.authorityFence.ownerLeaseGeneration) ||
|
|
476
|
+
(route.sealId !== undefined && route.sealId !== key)) {
|
|
477
|
+
throw new bound_session_wire_1.ZLinkRemoteBoundSessionFenceError(`Actor '${actorId}' command 42 was fenced by its exact Session route.`);
|
|
478
|
+
}
|
|
479
|
+
const step = this.prepareRelocationSeal({
|
|
480
|
+
actorId,
|
|
481
|
+
actorGeneration: value.actor.actor.generation,
|
|
482
|
+
bindingGeneration: value.session.bindingGeneration,
|
|
483
|
+
sessionIdentity: value.session.sessionRid,
|
|
484
|
+
actorNodeRid: value.actor.actor.nodeRid,
|
|
485
|
+
actorNodeGeneration: value.actor.targetNodeGeneration,
|
|
486
|
+
sealId: key
|
|
487
|
+
}, expected, signal);
|
|
488
|
+
if (step.kind === 'predecessor')
|
|
489
|
+
return { predecessor: step.wait };
|
|
490
|
+
const result = {
|
|
491
|
+
key,
|
|
492
|
+
fingerprint,
|
|
493
|
+
response,
|
|
494
|
+
ready: step.wait,
|
|
495
|
+
seal: this.relocations.get(actorId).seals.get(key)
|
|
496
|
+
};
|
|
497
|
+
route.sessionRelocationResult = result;
|
|
498
|
+
return result;
|
|
499
|
+
}
|
|
500
|
+
async acceptSessionRelocationRoute(value, apply) {
|
|
501
|
+
const key = (0, service_stateful_wire_codec_1.serviceSessionRelocationIdentityKey)(value);
|
|
502
|
+
const fingerprint = (0, service_stateful_wire_codec_1.encodeSessionRelocationRoute)(value).toString('base64');
|
|
503
|
+
const prepared = await this.lane.run(() => {
|
|
504
|
+
if (this.absentSessionRelocationResults.has(key))
|
|
505
|
+
return undefined;
|
|
506
|
+
const result = this.routes.get(value.actor.actorId)?.sessionRelocationResult;
|
|
507
|
+
if (result?.key !== key || result.seal === undefined)
|
|
508
|
+
return undefined;
|
|
509
|
+
const seal = result.seal;
|
|
510
|
+
if (seal.applyFingerprint !== undefined && seal.applyFingerprint !== fingerprint) {
|
|
511
|
+
throw new service_wire_m6a_codec_1.ServiceWireProtocolError(`Session relocation '${key}' repeated command 44 with different bytes.`);
|
|
512
|
+
}
|
|
513
|
+
if (seal.phase === 'terminal')
|
|
514
|
+
return undefined;
|
|
515
|
+
return this.prepareRelocationApply(value.actor.actorId, key, fingerprint);
|
|
516
|
+
});
|
|
517
|
+
if (prepared === undefined)
|
|
518
|
+
return false;
|
|
519
|
+
await this.runRelocationApply(prepared, apply);
|
|
520
|
+
await this.observeRelocationTerminal(value.actor.actorId, key, fingerprint);
|
|
521
|
+
return true;
|
|
522
|
+
}
|
|
523
|
+
async clearSessionRelocationResults() {
|
|
524
|
+
await this.lane.run(() => {
|
|
525
|
+
for (const { expiry } of this.absentSessionRelocationResults.values())
|
|
526
|
+
clearTimeout(expiry);
|
|
527
|
+
this.absentSessionRelocationResults.clear();
|
|
528
|
+
for (const route of this.routes.values())
|
|
529
|
+
route.sessionRelocationResult = undefined;
|
|
530
|
+
});
|
|
531
|
+
}
|
|
412
532
|
async sealRelocation(claim, expected, signal) {
|
|
413
533
|
for (;;) {
|
|
414
534
|
(0, abort_1.throwIfAborted)(signal);
|
|
@@ -467,11 +587,14 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
467
587
|
}
|
|
468
588
|
async applyRelocation(actorId, sealId, applyFingerprint, commitOwnerTransition) {
|
|
469
589
|
const prepared = await this.lane.run(() => this.prepareRelocationApply(actorId, sealId, applyFingerprint));
|
|
590
|
+
await this.runRelocationApply(prepared, commitOwnerTransition);
|
|
591
|
+
}
|
|
592
|
+
async runRelocationApply(prepared, commitOwnerTransition) {
|
|
470
593
|
if (prepared.applyPromise !== undefined) {
|
|
471
594
|
await prepared.applyPromise;
|
|
472
595
|
return;
|
|
473
596
|
}
|
|
474
|
-
startOutsideStateLane(() => {
|
|
597
|
+
(0, state_lane_1.startOutsideStateLane)(() => {
|
|
475
598
|
void (async () => {
|
|
476
599
|
try {
|
|
477
600
|
await commitOwnerTransition();
|
|
@@ -552,10 +675,13 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
552
675
|
* single physical route's disconnect, which must not disturb a relocation
|
|
553
676
|
* seal it does not own (see `clearRouteRelocation`).
|
|
554
677
|
*/
|
|
555
|
-
async clearRelocation(actorId, error) {
|
|
556
|
-
await this.lane.run(() => this.clearRelocationCore(actorId, error));
|
|
678
|
+
async clearRelocation(actorId, error, sealId) {
|
|
679
|
+
await this.lane.run(() => this.clearRelocationCore(actorId, error, sealId));
|
|
557
680
|
}
|
|
558
|
-
clearRelocationCore(actorId, error) {
|
|
681
|
+
clearRelocationCore(actorId, error, sealId) {
|
|
682
|
+
const result = this.routes.get(actorId)?.sessionRelocationResult;
|
|
683
|
+
if (sealId !== undefined && (result?.key !== sealId || result.seal?.phase === 'terminal'))
|
|
684
|
+
return;
|
|
559
685
|
const queue = this.relocations.get(actorId);
|
|
560
686
|
if (queue === undefined)
|
|
561
687
|
return;
|
|
@@ -569,8 +695,8 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
569
695
|
this.relocations.delete(actorId);
|
|
570
696
|
for (const state of queue.seals.values()) {
|
|
571
697
|
this.terminalRelocations.delete(state);
|
|
572
|
-
|
|
573
|
-
|
|
698
|
+
state.phase = 'terminal';
|
|
699
|
+
state.resolveTerminal();
|
|
574
700
|
}
|
|
575
701
|
}
|
|
576
702
|
/**
|
|
@@ -592,7 +718,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
592
718
|
const activeState = activeSealId === undefined ? undefined : queue.seals.get(activeSealId);
|
|
593
719
|
const ownsActiveSeal = activeState !== undefined &&
|
|
594
720
|
activeState.phase !== 'terminal' &&
|
|
595
|
-
activeState.sessionIdentity
|
|
721
|
+
(0, routing_id_1.routingIdsEqual)(activeState.sessionIdentity, route.sessionIdentity);
|
|
596
722
|
if (!ownsActiveSeal) {
|
|
597
723
|
// Nothing this exact route still holds open — leave terminal
|
|
598
724
|
// retention and any other Session's active seal untouched.
|
|
@@ -602,6 +728,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
602
728
|
queue.activeSealId = undefined;
|
|
603
729
|
queue.seals.delete(activeSealId);
|
|
604
730
|
this.terminalRelocations.delete(activeState);
|
|
731
|
+
activeState.phase = 'terminal';
|
|
605
732
|
activeState.resolveTerminal();
|
|
606
733
|
this.deleteEmptyRelocationQueue(queue);
|
|
607
734
|
}
|
|
@@ -616,13 +743,6 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
616
743
|
this.resolveSealWaiters(actorId, sealId);
|
|
617
744
|
return true;
|
|
618
745
|
}
|
|
619
|
-
async updateAuthorityFence(actorId, authorityFence) {
|
|
620
|
-
await this.lane.run(() => this.updateAuthorityFenceCore(actorId, authorityFence));
|
|
621
|
-
}
|
|
622
|
-
updateAuthorityFenceCore(actorId, authorityFence) {
|
|
623
|
-
const route = this.requireRouteCore(actorId);
|
|
624
|
-
route.authorityFence = authorityFence;
|
|
625
|
-
}
|
|
626
746
|
async validateSeal(actorId, sealId) {
|
|
627
747
|
return await this.lane.run(() => this.validateSealCore(actorId, sealId));
|
|
628
748
|
}
|
|
@@ -679,7 +799,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
679
799
|
if (waiters.size === 0)
|
|
680
800
|
this.sealWaiters.delete(actorId);
|
|
681
801
|
};
|
|
682
|
-
timer = startOutsideStateLane(() => setTimeout(() => {
|
|
802
|
+
timer = (0, state_lane_1.startOutsideStateLane)(() => setTimeout(() => {
|
|
683
803
|
this.lane.tryPost(() => {
|
|
684
804
|
removeWaiter();
|
|
685
805
|
rejectWaiter((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `Actor '${actorId}' session seal was not released within the relocation seal timeout.`, true));
|
|
@@ -698,7 +818,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
698
818
|
onAbort();
|
|
699
819
|
return;
|
|
700
820
|
}
|
|
701
|
-
startOutsideStateLane(() => signal.addEventListener('abort', onAbort, { once: true }));
|
|
821
|
+
(0, state_lane_1.startOutsideStateLane)(() => signal.addEventListener('abort', onAbort, { once: true }));
|
|
702
822
|
});
|
|
703
823
|
}
|
|
704
824
|
async waitForActiveFrames(actorId, signal) {
|
|
@@ -749,7 +869,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
749
869
|
// Spec 48:205 — transport/deadline limits keep applying during
|
|
750
870
|
// relocation: the sealing side must not wait forever for active
|
|
751
871
|
// frames that themselves may be waiting on this relocation.
|
|
752
|
-
timer = startOutsideStateLane(() => setTimeout(() => {
|
|
872
|
+
timer = (0, state_lane_1.startOutsideStateLane)(() => setTimeout(() => {
|
|
753
873
|
this.lane.tryPost(() => {
|
|
754
874
|
waiters.delete(waiter);
|
|
755
875
|
if (waiters.size === 0)
|
|
@@ -763,7 +883,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
763
883
|
if (signal.aborted)
|
|
764
884
|
onAbort();
|
|
765
885
|
else
|
|
766
|
-
startOutsideStateLane(() => signal.addEventListener('abort', onAbort, { once: true }));
|
|
886
|
+
(0, state_lane_1.startOutsideStateLane)(() => signal.addEventListener('abort', onAbort, { once: true }));
|
|
767
887
|
});
|
|
768
888
|
}
|
|
769
889
|
resolveActiveFrameWaiters(actorId) {
|
|
@@ -838,7 +958,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
838
958
|
startHeldOneWayDrain(actorId, queue) {
|
|
839
959
|
if (queue.ingressDrain !== undefined)
|
|
840
960
|
return;
|
|
841
|
-
const drain = startOutsideStateLane(async () => {
|
|
961
|
+
const drain = (0, state_lane_1.startOutsideStateLane)(async () => {
|
|
842
962
|
for (;;) {
|
|
843
963
|
const next = await this.lane.run(() => {
|
|
844
964
|
if (this.relocations.get(actorId) !== queue)
|
|
@@ -859,7 +979,7 @@ class ZLinkActorSessionBindingRegistry {
|
|
|
859
979
|
}
|
|
860
980
|
});
|
|
861
981
|
queue.ingressDrain = drain;
|
|
862
|
-
startOutsideStateLane(() => {
|
|
982
|
+
(0, state_lane_1.startOutsideStateLane)(() => {
|
|
863
983
|
void drain.finally(async () => {
|
|
864
984
|
await this.lane.run(() => {
|
|
865
985
|
if (queue.ingressDrain !== drain)
|
|
@@ -878,19 +998,16 @@ exports.ZLinkActorSessionBindingRegistry = ZLinkActorSessionBindingRegistry;
|
|
|
878
998
|
function assertRelocationClaim(state, claim) {
|
|
879
999
|
if (state.actorGeneration !== claim.actorGeneration ||
|
|
880
1000
|
state.bindingGeneration !== claim.bindingGeneration ||
|
|
881
|
-
state.sessionIdentity
|
|
882
|
-
state.actorNodeRid
|
|
1001
|
+
!(0, routing_id_1.routingIdsEqual)(state.sessionIdentity, claim.sessionIdentity) ||
|
|
1002
|
+
!(0, routing_id_1.routingIdsEqual)(state.actorNodeRid, claim.actorNodeRid) ||
|
|
883
1003
|
state.actorNodeGeneration !== claim.actorNodeGeneration) {
|
|
884
1004
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorLocationStale, `Actor '${claim.actorId}' repeated Session seal changed its exact identity.`, true);
|
|
885
1005
|
}
|
|
886
1006
|
}
|
|
887
|
-
function startOutsideStateLane(work) {
|
|
888
|
-
return detachedStateLaneResource.runInAsyncScope(work);
|
|
889
|
-
}
|
|
890
1007
|
function assertSuccessorSessionIdentity(predecessor, successor) {
|
|
891
1008
|
if (predecessor.actorGeneration !== successor.actorGeneration ||
|
|
892
1009
|
predecessor.bindingGeneration !== successor.bindingGeneration ||
|
|
893
|
-
predecessor.sessionIdentity
|
|
1010
|
+
!(0, routing_id_1.routingIdsEqual)(predecessor.sessionIdentity, successor.sessionIdentity)) {
|
|
894
1011
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorLocationStale, `Actor '${successor.actorId}' successor Session seal changed its exact Session identity.`, true);
|
|
895
1012
|
}
|
|
896
1013
|
}
|
|
@@ -901,7 +1018,7 @@ function routeMatchesFence(route, expected) {
|
|
|
901
1018
|
ref.bindingGeneration === expected.bindingGeneration);
|
|
902
1019
|
}
|
|
903
1020
|
function sessionIdentityFromContext(context) {
|
|
904
|
-
return context.routingId
|
|
1021
|
+
return context.routingId;
|
|
905
1022
|
}
|
|
906
1023
|
function waitForSessionRelocation(operation, signal) {
|
|
907
1024
|
if (signal === undefined)
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import type { RoutingId } from '../../contracts';
|
|
2
|
+
import type { ServiceSessionRelocationSeal, ServiceSessionRelocationRoute } from '../foundation/service-stateful-wire-codec';
|
|
1
3
|
import type { ActorRef } from '../../contracts';
|
|
2
|
-
import type { ZLinkActorSessionAuthorityFence,
|
|
4
|
+
import type { ZLinkActorSessionAuthorityFence, ZLinkActorSessionRelocationSnapshot, ZLinkPreparedSessionRelocationSeal } from './actor-session-binding-registry';
|
|
3
5
|
export interface ZLinkActorSessionBindingRuntimeOwner {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
prepareSessionRelocationSeal(value: ServiceSessionRelocationSeal, signal?: AbortSignal): Promise<ZLinkPreparedSessionRelocationSeal | undefined>;
|
|
7
|
+
acceptSessionRelocationRoute(value: ServiceSessionRelocationRoute, apply: () => Promise<void>): Promise<boolean>;
|
|
8
|
+
clearSessionRelocationResults(): Promise<void>;
|
|
9
|
+
actorSlot(actorId: string, sessionRid: RoutingId): Promise<number | undefined>;
|
|
6
10
|
relocationSnapshot(actorId: string, sealId: string): Promise<ZLinkActorSessionRelocationSnapshot | undefined>;
|
|
7
11
|
applyRelocation(actorId: string, sealId: string, applyFingerprint: string, commitOwnerTransition: () => Promise<void>): Promise<void>;
|
|
8
12
|
observeRelocationTerminal(actorId: string, sealId: string, applyFingerprint: string): Promise<void>;
|
|
9
|
-
clearRelocation(actorId: string, error: unknown): Promise<void>;
|
|
13
|
+
clearRelocation(actorId: string, error: unknown, sealId?: string): Promise<void>;
|
|
10
14
|
committedRoute(actorId: string): Promise<{
|
|
11
15
|
readonly actor: ActorRef;
|
|
12
16
|
readonly authorityFence?: ZLinkActorSessionAuthorityFence;
|
|
@@ -7,13 +7,14 @@ import { ZLinkActorSessionLifecycleCoordinator } from './actor-session-lifecycle
|
|
|
7
7
|
import { type ZLinkStreamFrameHeader } from './protocol';
|
|
8
8
|
import { DefaultZLinkSessionActor, DefaultZLinkSessionContext } from './session-context';
|
|
9
9
|
import { ZLinkStreamFrameMessageFactory } from './stream-frame-factory';
|
|
10
|
+
import type { ServiceStreamSessionBinding } from '../foundation/service-runtime-contracts';
|
|
10
11
|
export declare const DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS = 2000;
|
|
11
12
|
export interface ZLinkBoundActorRelaySenderOptions {
|
|
12
13
|
readonly dispatchErrors?: ZLinkDispatchErrorReporter;
|
|
13
14
|
readonly actorBindTimeoutMs?: number;
|
|
14
15
|
readonly messageSerializers?: ReadonlyMap<string, ZLinkMessageSerializer>;
|
|
15
16
|
readonly relay?: (actor: ZLinkSessionActor, header: ZLinkStreamFrameHeader, payload: Message) => Promise<boolean>;
|
|
16
|
-
readonly notifyDisconnected?: (actor: ZLinkSessionActor, signal?: AbortSignal) => Promise<void>;
|
|
17
|
+
readonly notifyDisconnected?: (actor: ZLinkSessionActor, signal?: AbortSignal, binding?: ServiceStreamSessionBinding) => Promise<void>;
|
|
17
18
|
}
|
|
18
19
|
export declare class ZLinkBoundActorRelaySender {
|
|
19
20
|
private readonly routes;
|
|
@@ -159,15 +159,18 @@ class ZLinkBoundActorRelaySender {
|
|
|
159
159
|
const detached = await this.lifecycle.run(actor.actorId, async () => {
|
|
160
160
|
await this.routes.requireCurrentToken(actor.actorId, actor.bindingToken);
|
|
161
161
|
const route = await this.routes.requireRoute(actor.actorId);
|
|
162
|
+
const binding = route.context.stream instanceof managed_stream_1.ZLinkManagedStream
|
|
163
|
+
? route.context.stream.actorBinding(actor.actorId)
|
|
164
|
+
: undefined;
|
|
162
165
|
await this.routes.unbind(actor.actorId, route.context, actor.bindingToken);
|
|
163
|
-
return route;
|
|
166
|
+
return { route, binding };
|
|
164
167
|
});
|
|
165
168
|
if (unbindNative &&
|
|
166
|
-
detached.bindingToken === actor.bindingToken &&
|
|
167
|
-
detached.context.stream instanceof managed_stream_1.ZLinkManagedStream) {
|
|
168
|
-
await detached.context.stream.unbindActor(actor.actorId, this.options.actorBindTimeoutMs ?? exports.DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS, signal);
|
|
169
|
+
detached.route.bindingToken === actor.bindingToken &&
|
|
170
|
+
detached.route.context.stream instanceof managed_stream_1.ZLinkManagedStream) {
|
|
171
|
+
await detached.route.context.stream.unbindActor(actor.actorId, this.options.actorBindTimeoutMs ?? exports.DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS, signal);
|
|
169
172
|
}
|
|
170
|
-
await this.options.notifyDisconnected?.(actor, signal);
|
|
173
|
+
await this.options.notifyDisconnected?.(actor, signal, detached.binding);
|
|
171
174
|
}
|
|
172
175
|
async notifyPhysicalDisconnect(context) {
|
|
173
176
|
const snapshot = [...context.boundActors];
|
|
@@ -184,16 +187,20 @@ class ZLinkBoundActorRelaySender {
|
|
|
184
187
|
// The transport is already closed, so remove its exact route before
|
|
185
188
|
// invoking application lifecycle code. A reconnect can then install
|
|
186
189
|
// a successor while this best-effort notification is in flight.
|
|
190
|
+
const binding = context.stream instanceof managed_stream_1.ZLinkManagedStream
|
|
191
|
+
? context.stream.actorBinding(actor.actorId)
|
|
192
|
+
: undefined;
|
|
187
193
|
await this.routes.unbind(actor.actorId, context, actor.bindingToken, actor_session_binding_registry_1.ZLinkActorSessionBindingTermination.PhysicalDisconnect);
|
|
188
|
-
return
|
|
194
|
+
return { binding };
|
|
189
195
|
});
|
|
190
|
-
if (
|
|
196
|
+
if (detached === false)
|
|
191
197
|
return;
|
|
192
198
|
const controller = new AbortController();
|
|
193
199
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
194
200
|
try {
|
|
195
201
|
await Promise.race([
|
|
196
|
-
this.options.notifyDisconnected?.(actor, controller.signal) ??
|
|
202
|
+
this.options.notifyDisconnected?.(actor, controller.signal, detached.binding) ??
|
|
203
|
+
Promise.resolve(),
|
|
197
204
|
new Promise((_, reject) => {
|
|
198
205
|
controller.signal.addEventListener('abort', () => reject(new Error(`Actor '${actor.actorId}' disconnect notification exceeded ${timeoutMs} ms.`)), { once: true });
|
|
199
206
|
})
|
|
@@ -38,7 +38,7 @@ export declare class ZLinkBoundSessionService {
|
|
|
38
38
|
sendNativeBoundSession(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, message: unknown, packetName: string | undefined, metadata: ReadonlyMap<string, string>, signal?: AbortSignal): Promise<ZLinkSubmitResult>;
|
|
39
39
|
sendNativeBoundSessionResponse(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, packetName: string, requestSeq: bigint, message: unknown, metadata: ReadonlyMap<string, string>, compressPayload: boolean, signal?: AbortSignal): Promise<void>;
|
|
40
40
|
sendNativeBoundSessionError(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, packetName: string, requestSeq: bigint, error: unknown, metadata: ReadonlyMap<string, string>, signal?: AbortSignal): Promise<void>;
|
|
41
|
-
disconnectNativeBoundSession(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, signal?: AbortSignal): Promise<void>;
|
|
41
|
+
disconnectNativeBoundSession(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, timeoutMs: number, signal?: AbortSignal): Promise<void>;
|
|
42
42
|
disconnectBoundSession(actorId: string, signal?: AbortSignal): Promise<void>;
|
|
43
43
|
/**
|
|
44
44
|
* Closes the physical Session of one exact binding after its relocation
|
|
@@ -86,22 +86,17 @@ class ZLinkBoundSessionService {
|
|
|
86
86
|
(0, abort_1.throwIfAborted)(signal);
|
|
87
87
|
await this.sendNativeBoundSessionPayload(node, actorRef, protocol_1.ZLinkStreamMessageKind.Error, packetName, metadata, false, requestSeq, (0, bound_session_response_target_1.boundSessionErrorPayload)(error), signal);
|
|
88
88
|
}
|
|
89
|
-
async disconnectNativeBoundSession(node, actorRef, signal) {
|
|
89
|
+
async disconnectNativeBoundSession(node, actorRef, timeoutMs, signal) {
|
|
90
90
|
(0, abort_1.throwIfAborted)(signal);
|
|
91
|
-
await node.closeActorBoundSession(actorRef, requireBoundSessionGeneration(actorRef),
|
|
91
|
+
await node.closeActorBoundSession(toBoundSessionSendActorRef(actorRef), requireBoundSessionGeneration(actorRef), timeoutMs, signal);
|
|
92
92
|
}
|
|
93
93
|
async disconnectBoundSession(actorId, signal) {
|
|
94
94
|
(0, abort_1.throwIfAborted)(signal);
|
|
95
95
|
const route = await this.routes.requireRoute(actorId);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
finally {
|
|
103
|
-
await this.routes.unbind(actorId, route.context, route.bindingToken);
|
|
104
|
-
}
|
|
96
|
+
await this.requireTransport().disconnect(actorId, {
|
|
97
|
+
bindingToken: route.bindingToken,
|
|
98
|
+
signal
|
|
99
|
+
});
|
|
105
100
|
}
|
|
106
101
|
/**
|
|
107
102
|
* Closes the physical Session of one exact binding after its relocation
|