@zlink-systems/framework 0.30.1 → 0.30.3
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 +40 -19
- 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 +39 -11
- 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 +4 -0
- package/dist/runtime/locations/auto-connect-loop.js +35 -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 -179
- 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 +29 -6
- 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 +56 -28
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +60 -14
- 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 +38 -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 -287
- 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 +33 -8
- 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
|
@@ -30,7 +30,7 @@ export declare class ZLinkFanoutLocationRuntime {
|
|
|
30
30
|
lifecycleGeneration: bigint;
|
|
31
31
|
descriptorRevision: bigint;
|
|
32
32
|
advertisedEndpoint: string;
|
|
33
|
-
state: "error" | "preparing" | "serving" | "
|
|
33
|
+
state: "error" | "preparing" | "serving" | "stopped" | "retiring";
|
|
34
34
|
}[] | undefined;
|
|
35
35
|
private isAutomaticSubscriber;
|
|
36
36
|
reclaimOwnerRows(signal?: AbortSignal): Promise<void>;
|
|
@@ -112,7 +112,7 @@ class ZLinkFanoutLocationRuntime {
|
|
|
112
112
|
ownerId: owner.ownerId,
|
|
113
113
|
leaseGeneration: owner.leaseGeneration
|
|
114
114
|
};
|
|
115
|
-
const result = await this.store.updateFanoutPublisher(candidate, Locations_1.ZLinkLocationWriteIntent.Takeover, signal);
|
|
115
|
+
const result = await this.locationRuntime.writeDescriptor((writeSignal) => this.store.updateFanoutPublisher(candidate, Locations_1.ZLinkLocationWriteIntent.Takeover, writeSignal), signal);
|
|
116
116
|
if (result.status !== Locations_1.ZLinkLocationWriteStatus.Stored) {
|
|
117
117
|
throw new configuration_1.ZLinkConfigurationException(`Fanout publisher '${channelName}' descriptor recovery was fenced.`);
|
|
118
118
|
}
|
|
@@ -135,7 +135,7 @@ class ZLinkFanoutLocationRuntime {
|
|
|
135
135
|
}
|
|
136
136
|
const current = await this.lane.run(() => this.localDescriptors.get(channelName));
|
|
137
137
|
if (current !== undefined) {
|
|
138
|
-
const result = await this.store.updateFanoutPublisher(current, Locations_1.ZLinkLocationWriteIntent.Renew, signal);
|
|
138
|
+
const result = await this.locationRuntime.writeDescriptor((writeSignal) => this.store.updateFanoutPublisher(current, Locations_1.ZLinkLocationWriteIntent.Renew, writeSignal), signal);
|
|
139
139
|
if (result.status !== Locations_1.ZLinkLocationWriteStatus.Stored) {
|
|
140
140
|
throw new configuration_1.ZLinkConfigurationException(`Fanout publisher '${channelName}' descriptor renewal was fenced.`);
|
|
141
141
|
}
|
|
@@ -169,7 +169,7 @@ class ZLinkFanoutLocationRuntime {
|
|
|
169
169
|
leaseGeneration: owner.leaseGeneration,
|
|
170
170
|
updatedAt: new Date(0)
|
|
171
171
|
};
|
|
172
|
-
const result = await this.store.updateFanoutPublisher(descriptor, Locations_1.ZLinkLocationWriteIntent.NewClaim, signal);
|
|
172
|
+
const result = await this.locationRuntime.writeDescriptor((writeSignal) => this.store.updateFanoutPublisher(descriptor, Locations_1.ZLinkLocationWriteIntent.NewClaim, writeSignal), signal);
|
|
173
173
|
if (result.status !== Locations_1.ZLinkLocationWriteStatus.Stored) {
|
|
174
174
|
throw new configuration_1.ZLinkConfigurationException(`Fanout publisher '${channelName}' descriptor claim failed with '${result.status}'.`);
|
|
175
175
|
}
|
|
@@ -9,7 +9,6 @@ exports.createInboundFlow = createInboundFlow;
|
|
|
9
9
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
10
10
|
const node_crypto_1 = require("node:crypto");
|
|
11
11
|
const FLOW_UUID_BYTES = 16;
|
|
12
|
-
const FLOW_UUID_VARIANT_BYTE = 8;
|
|
13
12
|
/**
|
|
14
13
|
* Spec 27 §3 defines the flow_origin value set as lowercase
|
|
15
14
|
* (`inbound|timer|application|lifecycle`); every language emits these exact
|
|
@@ -70,13 +69,26 @@ function createInboundFlow(flowId, flowOrigin, createIfAbsent, streamSessionId)
|
|
|
70
69
|
}
|
|
71
70
|
return { flowId: flowId ?? createFlowId(), flowOrigin: flowOrigin ?? 'Inbound', streamSessionId };
|
|
72
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* UUIDv7 with a dedicated counter (RFC 9562 §6.2 method 1): the 48-bit
|
|
74
|
+
* millisecond timestamp, then a 42-bit counter that starts at a random value
|
|
75
|
+
* and spans `rand_a` and the top of `rand_b`, then 32 random bits drawn once
|
|
76
|
+
* per process. Flow ids stay unique within the process without drawing
|
|
77
|
+
* random bytes for every message.
|
|
78
|
+
*/
|
|
79
|
+
const flowRandom = (0, node_crypto_1.randomBytes)(FLOW_UUID_BYTES);
|
|
80
|
+
const FLOW_COUNTER_SPAN = 2 ** 42;
|
|
81
|
+
let flowCounter = flowRandom.readUIntBE(0, 6) % FLOW_COUNTER_SPAN;
|
|
82
|
+
const FLOW_ID_TAIL = flowRandom.toString('hex', FLOW_UUID_BYTES - 4);
|
|
73
83
|
function createFlowId() {
|
|
74
|
-
const
|
|
84
|
+
const counter = flowCounter;
|
|
85
|
+
flowCounter = (flowCounter + 1) % FLOW_COUNTER_SPAN;
|
|
75
86
|
// Date.now() is always within 48 bits, which is exactly the UUIDv7
|
|
76
87
|
// timestamp field.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
88
|
+
const timestamp = Date.now().toString(16).padStart(12, '0');
|
|
89
|
+
const randA = Math.floor(counter / 2 ** 30); // 12 bits
|
|
90
|
+
const randB = counter % 2 ** 30; // 30 bits after the 2 variant bits
|
|
91
|
+
const variantHigh = (0x8000 | Math.floor(randB / 2 ** 16)).toString(16);
|
|
92
|
+
const randBLow = (randB % 2 ** 16).toString(16).padStart(4, '0');
|
|
93
|
+
return `${timestamp.slice(0, 8)}-${timestamp.slice(8)}-7${randA.toString(16).padStart(3, '0')}-${variantHigh}-${randBLow}${FLOW_ID_TAIL}`;
|
|
82
94
|
}
|
|
@@ -18,7 +18,6 @@ exports.ZLinkLocationMonitoringEventEmitter = exports.ZLinkLocationRuntimeMonito
|
|
|
18
18
|
exports.isRelocationDebugEnabled = isRelocationDebugEnabled;
|
|
19
19
|
exports.relocationDebug = relocationDebug;
|
|
20
20
|
exports.emitActorOwnerLeaseObservation = emitActorOwnerLeaseObservation;
|
|
21
|
-
const node_async_hooks_1 = require("node:async_hooks");
|
|
22
21
|
const state_lane_1 = require("../execution/state-lane");
|
|
23
22
|
const routing_id_1 = require("../routing-id");
|
|
24
23
|
const internal_event_contracts_1 = require("./internal-event-contracts");
|
|
@@ -29,7 +28,6 @@ Object.defineProperty(exports, "ZLinkLocationRouteEventKind", { enumerable: true
|
|
|
29
28
|
Object.defineProperty(exports, "ZLinkLocationSpotEventKind", { enumerable: true, get: function () { return internal_event_contracts_2.ZLinkLocationSpotEventKind; } });
|
|
30
29
|
Object.defineProperty(exports, "ZLinkSocketNativeEventType", { enumerable: true, get: function () { return internal_event_contracts_2.ZLinkSocketNativeEventType; } });
|
|
31
30
|
const ZLINK_DISCONNECT_REASON_HANDSHAKE_FAILED = 3;
|
|
32
|
-
const detachedStateLaneResource = new node_async_hooks_1.AsyncResource('zlink:location-runtime-monitoring-source');
|
|
33
31
|
function isRelocationDebugEnabled() {
|
|
34
32
|
return process.env.ZLINK_DEBUG_FRAMEWORK_RELOCATION === '1';
|
|
35
33
|
}
|
|
@@ -113,7 +111,7 @@ class ZLinkLocationRuntimeMonitoringSource {
|
|
|
113
111
|
let topology;
|
|
114
112
|
let serviceSummary;
|
|
115
113
|
try {
|
|
116
|
-
[status, topology, serviceSummary] = await startOutsideStateLane(() => Promise.all([
|
|
114
|
+
[status, topology, serviceSummary] = await (0, state_lane_1.startOutsideStateLane)(() => Promise.all([
|
|
117
115
|
this.query.getStatus(signal),
|
|
118
116
|
this.query.listTopology({}, undefined, signal),
|
|
119
117
|
this.query.listServiceSummaries({}, undefined, signal)
|
|
@@ -121,7 +119,7 @@ class ZLinkLocationRuntimeMonitoringSource {
|
|
|
121
119
|
}
|
|
122
120
|
catch (error) {
|
|
123
121
|
if (await this.lane.run(() => this.markStoreFailureCore())) {
|
|
124
|
-
await startOutsideStateLane(() => this.publisher.publish({
|
|
122
|
+
await (0, state_lane_1.startOutsideStateLane)(() => this.publisher.publish({
|
|
125
123
|
sourceName: this.registration.sourceName,
|
|
126
124
|
timestamp: new Date(),
|
|
127
125
|
event: internal_event_contracts_1.ZLinkLocationRuntimeEventKind.StoreFailure
|
|
@@ -130,7 +128,7 @@ class ZLinkLocationRuntimeMonitoringSource {
|
|
|
130
128
|
return;
|
|
131
129
|
}
|
|
132
130
|
if (await this.lane.run(() => this.markStoreRecoveredCore())) {
|
|
133
|
-
await startOutsideStateLane(() => this.publisher.publish({
|
|
131
|
+
await (0, state_lane_1.startOutsideStateLane)(() => this.publisher.publish({
|
|
134
132
|
sourceName: this.registration.sourceName,
|
|
135
133
|
timestamp: new Date(),
|
|
136
134
|
event: internal_event_contracts_1.ZLinkLocationRuntimeEventKind.StoreRecovered
|
|
@@ -157,7 +155,7 @@ class ZLinkLocationRuntimeMonitoringSource {
|
|
|
157
155
|
const previous = await this.lane.run(() => this.previousSnapshotCore(event));
|
|
158
156
|
if (current === previous)
|
|
159
157
|
return;
|
|
160
|
-
await startOutsideStateLane(() => publishLocationRuntimeChange(this.publisher, this.registration.sourceName, event, snapshot));
|
|
158
|
+
await (0, state_lane_1.startOutsideStateLane)(() => publishLocationRuntimeChange(this.publisher, this.registration.sourceName, event, snapshot));
|
|
161
159
|
await this.lane.run(() => this.updateSnapshotCore(event, current));
|
|
162
160
|
}
|
|
163
161
|
previousSnapshotCore(event) {
|
|
@@ -352,9 +350,6 @@ async function publishLocationRuntimeChange(publisher, sourceName, event, snapsh
|
|
|
352
350
|
};
|
|
353
351
|
await publisher.publish(runtimeEvent);
|
|
354
352
|
}
|
|
355
|
-
function startOutsideStateLane(work) {
|
|
356
|
-
return detachedStateLaneResource.runInAsyncScope(work);
|
|
357
|
-
}
|
|
358
353
|
function stableSnapshot(value) {
|
|
359
354
|
return JSON.stringify(value, (_key, item) => (typeof item === 'bigint' ? item.toString() : item));
|
|
360
355
|
}
|
|
@@ -12,6 +12,12 @@ export interface ZLinkDiagnosticsContext {
|
|
|
12
12
|
export declare const DEFAULT_ZLINK_DIAGNOSTICS: ZLinkDiagnosticsOptions;
|
|
13
13
|
export declare const telemetryLogger: import("@opentelemetry/api-logs").Logger;
|
|
14
14
|
export declare function effectiveMessageFlow(ctx: ZLinkDiagnosticsContext): ZLinkMessageFlowLogMode;
|
|
15
|
+
/**
|
|
16
|
+
* Message-flow tracing is on at Normal and Detailed only (04-flow-correlation
|
|
17
|
+
* §4). Below it no flow ID is created, validated, captured or propagated. This
|
|
18
|
+
* is the one decision every flow processing point reads.
|
|
19
|
+
*/
|
|
20
|
+
export declare function messageFlowTracingEnabled(mode: ZLinkMessageFlowLogMode): boolean;
|
|
15
21
|
export declare function createMessageFlowModeCell(dispatch: {
|
|
16
22
|
diagnostics?: ZLinkDiagnosticsOptions;
|
|
17
23
|
} | undefined): ZLinkMessageFlowModeCell;
|
|
@@ -22,7 +28,9 @@ export declare function flowIfEnabled(flow: ZLinkMessageFlowTracer | undefined,
|
|
|
22
28
|
export interface ZLinkMessageFlowTracePoint {
|
|
23
29
|
trace(flowInput: MessageFlowInput): void;
|
|
24
30
|
}
|
|
31
|
+
export declare function traceSessionBindingControlDrop(flow: ZLinkMessageFlowTracer | undefined, sourceRid: string, actorId: string, packetName: string, errorReason: 'location_unavailable' | 'stale_target', error?: unknown): void;
|
|
25
32
|
type MessageFlowInput = Omit<ZLinkRuntimeMessageFlowEvent, 'effectiveMode' | 'flowId' | 'flowOrigin'> & {
|
|
33
|
+
readonly severity?: 'warning';
|
|
26
34
|
readonly effectiveMode?: ZLinkMessageFlowLogMode;
|
|
27
35
|
readonly flowId?: string;
|
|
28
36
|
readonly flowOrigin?: import('../../contracts').ZLinkFlowOrigin;
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkMessageFlowTracer = exports.telemetryLogger = exports.DEFAULT_ZLINK_DIAGNOSTICS = void 0;
|
|
4
4
|
exports.effectiveMessageFlow = effectiveMessageFlow;
|
|
5
|
+
exports.messageFlowTracingEnabled = messageFlowTracingEnabled;
|
|
5
6
|
exports.createMessageFlowModeCell = createMessageFlowModeCell;
|
|
6
7
|
exports.createDiagnosticsContext = createDiagnosticsContext;
|
|
7
8
|
exports.flowIfEnabled = flowIfEnabled;
|
|
9
|
+
exports.traceSessionBindingControlDrop = traceSessionBindingControlDrop;
|
|
8
10
|
const api_1 = require("@opentelemetry/api");
|
|
9
11
|
const api_logs_1 = require("@opentelemetry/api-logs");
|
|
10
12
|
const contracts_1 = require("../../contracts");
|
|
@@ -24,6 +26,14 @@ let diagnosticsGeneration = 0n;
|
|
|
24
26
|
function effectiveMessageFlow(ctx) {
|
|
25
27
|
return ctx.liveMode.mode;
|
|
26
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Message-flow tracing is on at Normal and Detailed only (04-flow-correlation
|
|
31
|
+
* §4). Below it no flow ID is created, validated, captured or propagated. This
|
|
32
|
+
* is the one decision every flow processing point reads.
|
|
33
|
+
*/
|
|
34
|
+
function messageFlowTracingEnabled(mode) {
|
|
35
|
+
return contracts_1.MESSAGE_FLOW_MODE_RANK[mode] >= contracts_1.MESSAGE_FLOW_MODE_RANK.normal;
|
|
36
|
+
}
|
|
27
37
|
function createMessageFlowModeCell(dispatch) {
|
|
28
38
|
return { mode: dispatch?.diagnostics?.messageFlow ?? 'errors' };
|
|
29
39
|
}
|
|
@@ -53,6 +63,21 @@ function flowIfEnabled(flow, outcome, result, flowId, sourceMeshGeneration) {
|
|
|
53
63
|
? flow
|
|
54
64
|
: undefined;
|
|
55
65
|
}
|
|
66
|
+
function traceSessionBindingControlDrop(flow, sourceRid, actorId, packetName, errorReason, error) {
|
|
67
|
+
const point = flowIfEnabled(flow, ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped);
|
|
68
|
+
if (point === undefined)
|
|
69
|
+
return;
|
|
70
|
+
point.trace({
|
|
71
|
+
outcome: ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped,
|
|
72
|
+
surface: ZLinkDispatchOptions_1.ZLinkDispatchErrorSurface.StreamSession,
|
|
73
|
+
messageKind: ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Control,
|
|
74
|
+
sourceRid,
|
|
75
|
+
actorId,
|
|
76
|
+
packetName,
|
|
77
|
+
errorReason,
|
|
78
|
+
...(0, dispatch_error_details_1.dispatchErrorDetails)(error)
|
|
79
|
+
});
|
|
80
|
+
}
|
|
56
81
|
class ZLinkMessageFlowTracer {
|
|
57
82
|
ctx;
|
|
58
83
|
errorSink;
|
|
@@ -100,7 +125,7 @@ class ZLinkMessageFlowTracer {
|
|
|
100
125
|
}
|
|
101
126
|
}
|
|
102
127
|
flowCreationEnabled() {
|
|
103
|
-
return effectiveMessageFlow(this.ctx)
|
|
128
|
+
return messageFlowTracingEnabled(effectiveMessageFlow(this.ctx));
|
|
104
129
|
}
|
|
105
130
|
trace(flowInput) {
|
|
106
131
|
const effectiveMode = effectiveMessageFlow(this.ctx);
|
|
@@ -164,12 +189,16 @@ class ZLinkMessageFlowTracer {
|
|
|
164
189
|
}
|
|
165
190
|
publishToLogger(record) {
|
|
166
191
|
try {
|
|
167
|
-
const
|
|
192
|
+
const severity = record.severity === 'warning'
|
|
193
|
+
? 'WARN'
|
|
194
|
+
: record.eventId === DISPATCH_ERROR_EVENT_ID
|
|
195
|
+
? 'ERROR'
|
|
196
|
+
: 'INFO';
|
|
168
197
|
exports.telemetryLogger.emit({
|
|
169
198
|
eventName: record.eventId,
|
|
170
199
|
timestamp: record.timestamp,
|
|
171
|
-
severityNumber,
|
|
172
|
-
severityText:
|
|
200
|
+
severityNumber: api_logs_1.SeverityNumber[severity],
|
|
201
|
+
severityText: severity,
|
|
173
202
|
body: structuredLogBody(record),
|
|
174
203
|
attributes: structuredLogAttributes(record)
|
|
175
204
|
});
|
|
@@ -205,6 +234,7 @@ class ZLinkMessageFlowTracer {
|
|
|
205
234
|
exports.ZLinkMessageFlowTracer = ZLinkMessageFlowTracer;
|
|
206
235
|
function toTelemetryRecord(flow, messageSizeBytes, durationSeconds) {
|
|
207
236
|
return {
|
|
237
|
+
severity: flow.severity,
|
|
208
238
|
eventId: flow.outcome === ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Error
|
|
209
239
|
? DISPATCH_ERROR_EVENT_ID
|
|
210
240
|
: MESSAGE_FLOW_EVENT_ID,
|
|
@@ -243,7 +273,7 @@ function toTelemetryRecord(flow, messageSizeBytes, durationSeconds) {
|
|
|
243
273
|
function traceAttributes(record) {
|
|
244
274
|
const attributes = {};
|
|
245
275
|
for (const [name, value] of Object.entries(record)) {
|
|
246
|
-
if (value === undefined || name === 'timestamp')
|
|
276
|
+
if (value === undefined || name === 'timestamp' || name === 'severity')
|
|
247
277
|
continue;
|
|
248
278
|
attributes[toSnakeCase(name)] = value instanceof Date ? value.toISOString() : value;
|
|
249
279
|
}
|
|
@@ -20,8 +20,8 @@ export interface ZLinkRuntimeMetricMeshSnapshot {
|
|
|
20
20
|
readonly channelName: string;
|
|
21
21
|
readonly readyMembers: number;
|
|
22
22
|
}>;
|
|
23
|
-
readonly actorCapacity
|
|
24
|
-
readonly spotCapacity
|
|
23
|
+
readonly actorCapacity?: ZLinkRuntimeMetricCapacity;
|
|
24
|
+
readonly spotCapacity?: ZLinkRuntimeMetricCapacity;
|
|
25
25
|
readonly spotTypeCapacities: ReadonlyArray<ZLinkRuntimeMetricSpotTypeCapacity>;
|
|
26
26
|
readonly activation: {
|
|
27
27
|
readonly active: number;
|
|
@@ -286,14 +286,16 @@ class MetricRegistry {
|
|
|
286
286
|
}
|
|
287
287
|
else if (name.startsWith('zlink.object.capacity.')) {
|
|
288
288
|
const field = metricSuffix(name);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
289
|
+
if (snapshot.actorCapacity !== undefined)
|
|
290
|
+
result.observe(capacityValue(snapshot.actorCapacity, field), {
|
|
291
|
+
...mesh,
|
|
292
|
+
capacity_scope: 'actor'
|
|
293
|
+
});
|
|
294
|
+
if (snapshot.spotCapacity !== undefined)
|
|
295
|
+
result.observe(capacityValue(snapshot.spotCapacity, field), {
|
|
296
|
+
...mesh,
|
|
297
|
+
capacity_scope: 'spot'
|
|
298
|
+
});
|
|
297
299
|
}
|
|
298
300
|
else if (name.startsWith('zlink.spot.type.capacity.')) {
|
|
299
301
|
const field = metricSuffix(name);
|
|
@@ -20,6 +20,7 @@ export declare class ZLinkSpotSerialTurn {
|
|
|
20
20
|
private suspendedResolve;
|
|
21
21
|
private suspendedPromise;
|
|
22
22
|
private suspendSignaled;
|
|
23
|
+
private yieldUsed;
|
|
23
24
|
private owner;
|
|
24
25
|
private frameworkOperationsBlocked;
|
|
25
26
|
constructor(postResume: (turn: ZLinkSpotSerialTurn, resume: () => void, reject: (reason: unknown) => void) => boolean, executionClaim: ZLinkExecutionBarrierClaim | undefined, yieldAllowed: boolean);
|
|
@@ -34,6 +35,7 @@ export declare class ZLinkSpotSerialTurn {
|
|
|
34
35
|
blockFrameworkOperations(): void;
|
|
35
36
|
ensureFrameworkOperationAllowed(): void;
|
|
36
37
|
resetSuspension(): void;
|
|
38
|
+
admitYield(): void;
|
|
37
39
|
yieldPromise<T>(pending: Promise<T>): Promise<T>;
|
|
38
40
|
/** Suspends a turn only for a Framework-owned lifecycle boundary. */
|
|
39
41
|
yieldFrameworkPromise<T>(pending: Promise<T>): Promise<T>;
|
|
@@ -47,14 +49,14 @@ export declare function captureZLinkSpotSerialTurn(executor?: ZLinkSpotSerialTur
|
|
|
47
49
|
export declare function currentZLinkSpotSerialSourceId(): unknown;
|
|
48
50
|
export declare function requireZLinkYieldTurn(capturedTurn?: ZLinkSpotSerialTurn): ZLinkSpotSerialTurn;
|
|
49
51
|
export interface ZLinkCapturedExecutionTurn {
|
|
50
|
-
yieldPromise<T>(
|
|
52
|
+
yieldPromise<T>(operation: () => Promise<T>): Promise<T>;
|
|
51
53
|
post(callback: () => void): void;
|
|
52
54
|
}
|
|
53
55
|
export declare function captureZLinkExecutionTurn(): ZLinkCapturedExecutionTurn | undefined;
|
|
54
56
|
export declare function isCurrentZLinkSpotSerialTurn(executor: ZLinkSpotSerialTurnExecutorLike): boolean;
|
|
55
57
|
export interface ZLinkExecutionBarrierSeal {
|
|
56
58
|
readonly generation: bigint;
|
|
57
|
-
readonly kind: 'close' | 'relocation';
|
|
59
|
+
readonly kind: 'close' | 'relocation' | 'activation';
|
|
58
60
|
}
|
|
59
61
|
export interface ZLinkExecutionBarrierClaim {
|
|
60
62
|
release(): void;
|
|
@@ -11,7 +11,6 @@ exports.requireZLinkYieldTurn = requireZLinkYieldTurn;
|
|
|
11
11
|
exports.captureZLinkExecutionTurn = captureZLinkExecutionTurn;
|
|
12
12
|
exports.isCurrentZLinkSpotSerialTurn = isCurrentZLinkSpotSerialTurn;
|
|
13
13
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
14
|
-
const configuration_1 = require("../configuration");
|
|
15
14
|
const abort_1 = require("../abort");
|
|
16
15
|
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
17
16
|
var state_lane_1 = require("./state-lane");
|
|
@@ -36,6 +35,7 @@ class ZLinkSpotSerialTurn {
|
|
|
36
35
|
suspendedResolve;
|
|
37
36
|
suspendedPromise;
|
|
38
37
|
suspendSignaled = false;
|
|
38
|
+
yieldUsed = false;
|
|
39
39
|
owner;
|
|
40
40
|
frameworkOperationsBlocked = false;
|
|
41
41
|
constructor(postResume, executionClaim, yieldAllowed) {
|
|
@@ -79,22 +79,34 @@ class ZLinkSpotSerialTurn {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
resetSuspension() {
|
|
82
|
+
this.yieldUsed = false;
|
|
82
83
|
this.suspendSignaled = false;
|
|
83
84
|
this.suspendedResolve = undefined;
|
|
84
85
|
this.suspendedPromise = undefined;
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
admitYield() {
|
|
88
|
+
const current = spotSerialTurnStorage.getStore();
|
|
89
|
+
if (current?.turn !== this ||
|
|
90
|
+
!this.yieldAllowed ||
|
|
91
|
+
!current.executor.isActiveTurn(this, current.turnId) ||
|
|
92
|
+
this.yieldUsed) {
|
|
93
|
+
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.InvalidOperation, 'Yield requires the current SpotWide application turn and may be used only once per turn.');
|
|
89
94
|
}
|
|
95
|
+
this.yieldUsed = true;
|
|
96
|
+
}
|
|
97
|
+
async yieldPromise(pending) {
|
|
98
|
+
this.admitYield();
|
|
90
99
|
return await this.yieldFrameworkPromise(pending);
|
|
91
100
|
}
|
|
92
101
|
/** Suspends a turn only for a Framework-owned lifecycle boundary. */
|
|
93
102
|
async yieldFrameworkPromise(pending) {
|
|
94
103
|
this.signalSuspended();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
try {
|
|
105
|
+
return await pending;
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
await this.awaitResumePermit();
|
|
109
|
+
}
|
|
98
110
|
}
|
|
99
111
|
async resumeOwnerUntilNextYield() {
|
|
100
112
|
const owner = this.owner;
|
|
@@ -146,9 +158,10 @@ function currentZLinkSpotSerialSourceId() {
|
|
|
146
158
|
}
|
|
147
159
|
function requireZLinkYieldTurn(capturedTurn) {
|
|
148
160
|
const turn = capturedTurn ?? captureZLinkSpotSerialTurn();
|
|
149
|
-
if (turn === undefined
|
|
150
|
-
throw
|
|
161
|
+
if (turn === undefined) {
|
|
162
|
+
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.InvalidOperation, 'Yield requires a current SpotWide application turn.');
|
|
151
163
|
}
|
|
164
|
+
turn.admitYield();
|
|
152
165
|
return turn;
|
|
153
166
|
}
|
|
154
167
|
function captureZLinkExecutionTurn() {
|
|
@@ -157,7 +170,17 @@ function captureZLinkExecutionTurn() {
|
|
|
157
170
|
return undefined;
|
|
158
171
|
}
|
|
159
172
|
return {
|
|
160
|
-
yieldPromise: (
|
|
173
|
+
yieldPromise: (operation) => {
|
|
174
|
+
const turn = requireZLinkYieldTurn(current.turn);
|
|
175
|
+
let pending;
|
|
176
|
+
try {
|
|
177
|
+
pending = operation();
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
pending = Promise.reject(error);
|
|
181
|
+
}
|
|
182
|
+
return turn.yieldFrameworkPromise(pending);
|
|
183
|
+
},
|
|
161
184
|
post: (callback) => {
|
|
162
185
|
void current.executor.post(callback);
|
|
163
186
|
}
|
|
@@ -169,6 +192,11 @@ function isCurrentZLinkSpotSerialTurn(executor) {
|
|
|
169
192
|
current.executor === executor &&
|
|
170
193
|
executor.isActiveTurn(current.turn, current.turnId));
|
|
171
194
|
}
|
|
195
|
+
function createExecutionBarrierAdmissionException(seal, message) {
|
|
196
|
+
return (0, framework_errors_internal_1.createInternalFrameworkException)(seal.kind === 'close'
|
|
197
|
+
? framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestTargetNotFound
|
|
198
|
+
: framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotMoving, message);
|
|
199
|
+
}
|
|
172
200
|
/**
|
|
173
201
|
* Seals application-lane admission and waits for every active Promise turn to
|
|
174
202
|
* finish. A seal generation prevents a stale abort from reopening a newer
|
|
@@ -192,14 +220,9 @@ class ZLinkExecutionBarrier {
|
|
|
192
220
|
}
|
|
193
221
|
enter() {
|
|
194
222
|
if (this.committedSeal !== undefined) {
|
|
195
|
-
throw (
|
|
196
|
-
? framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestRejected
|
|
197
|
-
: framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotMoving, 'ZLink execution barrier is committed.');
|
|
223
|
+
throw createExecutionBarrierAdmissionException(this.committedSeal, 'ZLink execution barrier is committed.');
|
|
198
224
|
}
|
|
199
225
|
if (this.currentSeal !== undefined) {
|
|
200
|
-
if (this.currentSeal.kind === 'close') {
|
|
201
|
-
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestRejected, 'ZLink execution barrier is sealed for Close.');
|
|
202
|
-
}
|
|
203
226
|
return new Promise((resolve, reject) => {
|
|
204
227
|
this.admissionWaiters.push({ resolve, reject });
|
|
205
228
|
});
|
|
@@ -279,9 +302,7 @@ class ZLinkExecutionBarrier {
|
|
|
279
302
|
return false;
|
|
280
303
|
this.currentSeal = undefined;
|
|
281
304
|
this.committedSeal = seal;
|
|
282
|
-
const error = (
|
|
283
|
-
? framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestRejected
|
|
284
|
-
: framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotMoving, 'ZLink execution barrier is committed.');
|
|
305
|
+
const error = createExecutionBarrierAdmissionException(seal, 'ZLink execution barrier is committed.');
|
|
285
306
|
for (const waiter of this.admissionWaiters)
|
|
286
307
|
waiter.reject(error);
|
|
287
308
|
this.admissionWaiters.length = 0;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type ZLinkSerialWorkLane = 'application' | 'lifecycle';
|
|
2
2
|
export interface ZLinkSerialWorkOptions {
|
|
3
3
|
readonly onAdmitted?: () => void;
|
|
4
|
+
/** Transfers an unstarted durable record out of this FIFO in the owner turn. */
|
|
5
|
+
readonly onWithdrawable?: (withdraw: () => boolean) => void;
|
|
4
6
|
readonly lane?: ZLinkSerialWorkLane;
|
|
5
7
|
readonly payloadBytes?: number;
|
|
6
8
|
readonly metadataBytes?: number;
|
|
@@ -67,7 +69,9 @@ export declare class ZLinkSerialExecutionQueue {
|
|
|
67
69
|
submitPreAdmitted<T>(operation: () => Promise<T> | T, options?: ZLinkSerialWorkOptions, context?: unknown): Promise<T>;
|
|
68
70
|
/** Holds lifecycle FIFO through an operation result while its application turns can run. */
|
|
69
71
|
submitLifecycleOperation<T>(operation: () => Promise<T> | T, context?: ZLinkSerialLifecycleContext): Promise<T>;
|
|
72
|
+
get retainsApplicationForLifecycle(): boolean;
|
|
70
73
|
visitPendingApplication(visitor: (record: ZLinkSerialWorkRecord<unknown>) => void): void;
|
|
74
|
+
get hasPendingDurableApplication(): boolean;
|
|
71
75
|
get hasPendingWork(): boolean;
|
|
72
76
|
whenIdle(): Promise<void>;
|
|
73
77
|
/** Stops new submissions while allowing the accepted FIFO to finish. */
|
|
@@ -84,12 +84,20 @@ class ZLinkSerialExecutionQueue {
|
|
|
84
84
|
submitLifecycleOperation(operation, context) {
|
|
85
85
|
return this.admit(operation, { lane: 'lifecycle' }, context, undefined, true);
|
|
86
86
|
}
|
|
87
|
+
get retainsApplicationForLifecycle() {
|
|
88
|
+
return this.activeLifecycle?.context !== undefined;
|
|
89
|
+
}
|
|
87
90
|
visitPendingApplication(visitor) {
|
|
88
91
|
for (const record of this.application.records) {
|
|
89
92
|
if (record.mailbox === undefined)
|
|
90
93
|
visitor(record);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
96
|
+
get hasPendingDurableApplication() {
|
|
97
|
+
// Every application record accepted behind durable work inherits durable
|
|
98
|
+
// ownership, so the tail answers this without scanning the FIFO.
|
|
99
|
+
return this.application.records.at(-1)?.preparation !== undefined;
|
|
100
|
+
}
|
|
93
101
|
get hasPendingWork() {
|
|
94
102
|
return (this.consumer?.running === true ||
|
|
95
103
|
this.activeRecord !== undefined ||
|
|
@@ -182,6 +190,17 @@ class ZLinkSerialExecutionQueue {
|
|
|
182
190
|
throw error;
|
|
183
191
|
}
|
|
184
192
|
options.onAdmitted?.();
|
|
193
|
+
options.onWithdrawable?.(() => {
|
|
194
|
+
const index = target.records.indexOf(record);
|
|
195
|
+
if (index < 0)
|
|
196
|
+
return false;
|
|
197
|
+
target.records.splice(index, 1);
|
|
198
|
+
record.preparationController?.abort(new Error('Durable record transferred to another handoff.'));
|
|
199
|
+
record.preparation?.cancel();
|
|
200
|
+
resolve(undefined);
|
|
201
|
+
release();
|
|
202
|
+
return true;
|
|
203
|
+
});
|
|
185
204
|
this.scheduleDrain();
|
|
186
205
|
return result;
|
|
187
206
|
}
|
|
@@ -199,10 +218,10 @@ class ZLinkSerialExecutionQueue {
|
|
|
199
218
|
if (consumer.scheduled || consumer.running)
|
|
200
219
|
return;
|
|
201
220
|
consumer.scheduled = true;
|
|
202
|
-
queueMicrotask(() => {
|
|
221
|
+
(0, state_lane_1.startOutsideStateLane)(() => queueMicrotask(() => {
|
|
203
222
|
consumer.scheduled = false;
|
|
204
223
|
void this.drain();
|
|
205
|
-
});
|
|
224
|
+
}));
|
|
206
225
|
}
|
|
207
226
|
/** Notifications carry no payload, admission sequence, result Promise, or host permit. */
|
|
208
227
|
enqueueMailboxTurn(operation) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
type ZLinkStateLaneWork<T> = () => Promise<T> | T;
|
|
2
2
|
export declare function isStructuralGuardEnabled(): boolean;
|
|
3
|
+
/** Detaches lane ownership while preserving the caller's other execution contexts. */
|
|
4
|
+
export declare function startOutsideStateLane<T>(work: () => T): T;
|
|
3
5
|
/**
|
|
4
6
|
* Single-owner execution lane for a component's mutable state.
|
|
5
7
|
*
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkStateLane = void 0;
|
|
4
4
|
exports.isStructuralGuardEnabled = isStructuralGuardEnabled;
|
|
5
|
+
exports.startOutsideStateLane = startOutsideStateLane;
|
|
5
6
|
exports.guardStateLaneCompletion = guardStateLaneCompletion;
|
|
6
7
|
exports.trackDiagnosticCompletion = trackDiagnosticCompletion;
|
|
7
8
|
exports.debugPendingWorkNames = debugPendingWorkNames;
|
|
@@ -11,8 +12,16 @@ const UNKNOWN_DIAGNOSTIC_CALLER = '<unknown caller>';
|
|
|
11
12
|
function isStructuralGuardEnabled() {
|
|
12
13
|
return process.env.ZLINK_NODE_STRUCTURAL_GUARD === '1' || process.env.NODE_ENV === 'test';
|
|
13
14
|
}
|
|
15
|
+
/** Detaches lane ownership while preserving the caller's other execution contexts. */
|
|
16
|
+
function startOutsideStateLane(work) {
|
|
17
|
+
return currentLaneStorage.exit(() => diagnosticTurnStorage === undefined ? work() : diagnosticTurnStorage.exit(work));
|
|
18
|
+
}
|
|
14
19
|
const currentLaneStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
15
20
|
const diagnosticPending = isStructuralGuardEnabled() ? new Map() : undefined;
|
|
21
|
+
const diagnosticLaneIds = isStructuralGuardEnabled()
|
|
22
|
+
? new WeakMap()
|
|
23
|
+
: undefined;
|
|
24
|
+
let nextDiagnosticLane = 0;
|
|
16
25
|
let nextDiagnosticWork = 0;
|
|
17
26
|
const diagnosticTurnStorage = diagnosticPending === undefined ? undefined : new node_async_hooks_1.AsyncLocalStorage();
|
|
18
27
|
/**
|
|
@@ -127,15 +136,24 @@ if (isStructuralGuardEnabled()) {
|
|
|
127
136
|
});
|
|
128
137
|
const run = ZLinkStateLane.prototype.run;
|
|
129
138
|
ZLinkStateLane.prototype.run = function (work) {
|
|
130
|
-
const
|
|
131
|
-
|
|
139
|
+
const release = registerDiagnosticWork(`${diagnosticLaneName(this)} ${diagnosticWorkName(work)}`);
|
|
140
|
+
let completion;
|
|
141
|
+
try {
|
|
142
|
+
completion = run.call(this, () => runDiagnosticTurn(this, work, release.description));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
release();
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
void completion.then(release, release);
|
|
149
|
+
return guardStateLaneCompletion(completion, `another state lane completion [${release.description}]`, this);
|
|
132
150
|
};
|
|
133
151
|
const tryPost = ZLinkStateLane.prototype.tryPost;
|
|
134
152
|
ZLinkStateLane.prototype.tryPost = function (work) {
|
|
135
|
-
const release = registerDiagnosticWork(
|
|
153
|
+
const release = registerDiagnosticWork(`${diagnosticLaneName(this)} post ${diagnosticWorkName(work)}`);
|
|
136
154
|
const accepted = tryPost.call(this, () => {
|
|
137
155
|
try {
|
|
138
|
-
const result = runDiagnosticTurn(this, work);
|
|
156
|
+
const result = runDiagnosticTurn(this, work, release.description);
|
|
139
157
|
if (result instanceof Promise)
|
|
140
158
|
return result.finally(release);
|
|
141
159
|
release();
|
|
@@ -151,8 +169,8 @@ if (isStructuralGuardEnabled()) {
|
|
|
151
169
|
return accepted;
|
|
152
170
|
};
|
|
153
171
|
}
|
|
154
|
-
function runDiagnosticTurn(lane, work) {
|
|
155
|
-
const turn = { lane, active: true };
|
|
172
|
+
function runDiagnosticTurn(lane, work, description) {
|
|
173
|
+
const turn = { lane, description, active: true };
|
|
156
174
|
return diagnosticTurnStorage.run(turn, () => {
|
|
157
175
|
try {
|
|
158
176
|
const result = work();
|
|
@@ -178,7 +196,8 @@ function guardStateLaneCompletion(completion, label, owner) {
|
|
|
178
196
|
return (onFulfilled, onRejected) => {
|
|
179
197
|
const current = ZLinkStateLane.current;
|
|
180
198
|
if (current !== undefined && current !== owner) {
|
|
181
|
-
throw new Error(`A state lane turn cannot wait for ${label}
|
|
199
|
+
throw new Error(`A state lane turn cannot wait for ${label}. ` +
|
|
200
|
+
`current turn: ${diagnosticTurnStorage?.getStore()?.description ?? UNKNOWN_DIAGNOSTIC_CALLER}`);
|
|
182
201
|
}
|
|
183
202
|
return target.then(onFulfilled, onRejected);
|
|
184
203
|
};
|
|
@@ -205,16 +224,25 @@ function debugPendingWorkNames() {
|
|
|
205
224
|
function diagnosticWorkName(work) {
|
|
206
225
|
return work.name.length > 0 ? work.name : '<anonymous>';
|
|
207
226
|
}
|
|
227
|
+
function diagnosticLaneName(lane) {
|
|
228
|
+
let id = diagnosticLaneIds.get(lane);
|
|
229
|
+
if (id === undefined) {
|
|
230
|
+
id = ++nextDiagnosticLane;
|
|
231
|
+
diagnosticLaneIds.set(lane, id);
|
|
232
|
+
}
|
|
233
|
+
return `state lane #${id}`;
|
|
234
|
+
}
|
|
208
235
|
function registerDiagnosticWork(name) {
|
|
209
236
|
if (diagnosticPending === undefined)
|
|
210
|
-
return () => undefined;
|
|
237
|
+
return Object.assign(() => undefined, { description: name });
|
|
211
238
|
const id = ++nextDiagnosticWork;
|
|
212
239
|
const frames = new Error().stack?.split('\n').slice(2) ?? [];
|
|
213
240
|
const caller = frames
|
|
214
241
|
.find((frame) => !frame.includes('state-lane.') && !frame.includes('serial-execution-queue.'))
|
|
215
242
|
?.trim() ?? UNKNOWN_DIAGNOSTIC_CALLER;
|
|
216
|
-
|
|
217
|
-
|
|
243
|
+
const description = `${name} ${caller}`;
|
|
244
|
+
diagnosticPending.set(id, description);
|
|
245
|
+
return Object.assign(() => {
|
|
218
246
|
diagnosticPending.delete(id);
|
|
219
|
-
};
|
|
247
|
+
}, { description });
|
|
220
248
|
}
|