@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,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ZLinkFrameworkException,
|
|
3
|
+
ZLinkFrameworkErrorKind
|
|
4
|
+
} from '../../contracts/Errors/ZLinkFrameworkException';
|
|
5
|
+
import { isIndeterminateLocationStoreFailure } from './location-store-failure';
|
|
6
|
+
import type { ZLinkRuntimeMetrics } from '../diagnostics/runtime-metrics';
|
|
1
7
|
import { randomUUID } from 'node:crypto';
|
|
2
8
|
import { awaitWithAbort, macrotaskBoundary } from '../abort';
|
|
3
9
|
import type {
|
|
@@ -19,6 +25,22 @@ export async function putNewRelocationBlob(
|
|
|
19
25
|
readonly reference: ZLinkBlobReference;
|
|
20
26
|
readonly expiresAt: Date;
|
|
21
27
|
readonly storeNow: Date;
|
|
28
|
+
}> {
|
|
29
|
+
if (store instanceof ZLinkProviderRelocationRepository) {
|
|
30
|
+
return store.putNew(payload, retentionMs, signal);
|
|
31
|
+
}
|
|
32
|
+
return putNewRelocationBlobCore(store, payload, retentionMs, signal);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function putNewRelocationBlobCore(
|
|
36
|
+
store: ZLinkRelocationStore,
|
|
37
|
+
payload: Uint8Array,
|
|
38
|
+
retentionMs: number,
|
|
39
|
+
signal?: AbortSignal
|
|
40
|
+
): Promise<{
|
|
41
|
+
readonly reference: ZLinkBlobReference;
|
|
42
|
+
readonly expiresAt: Date;
|
|
43
|
+
readonly storeNow: Date;
|
|
22
44
|
}> {
|
|
23
45
|
let reference = relocationBlobReference(randomUUID());
|
|
24
46
|
for (; ; await macrotaskBoundary()) {
|
|
@@ -26,7 +48,8 @@ export async function putNewRelocationBlob(
|
|
|
26
48
|
let result: ZLinkBlobPutResult;
|
|
27
49
|
try {
|
|
28
50
|
result = await awaitWithAbort(store.put(reference, payload, retentionMs, signal), signal);
|
|
29
|
-
} catch {
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (!isRelocationProviderFailure(error)) throw error;
|
|
30
53
|
signal?.throwIfAborted();
|
|
31
54
|
const read = await awaitWithAbort(store.read(reference, signal), signal);
|
|
32
55
|
if (read.kind === 'found' && Buffer.compare(read.bytes, payload) === 0) {
|
|
@@ -45,3 +68,54 @@ export async function putNewRelocationBlob(
|
|
|
45
68
|
reference = relocationBlobReference(randomUUID());
|
|
46
69
|
}
|
|
47
70
|
}
|
|
71
|
+
|
|
72
|
+
/** Observes provider requests before callers interpret or decode blob contents. */
|
|
73
|
+
export class ZLinkProviderRelocationRepository implements ZLinkRelocationStore {
|
|
74
|
+
constructor(
|
|
75
|
+
private readonly provider: ZLinkRelocationStore,
|
|
76
|
+
private readonly metrics: ZLinkRuntimeMetrics
|
|
77
|
+
) {}
|
|
78
|
+
|
|
79
|
+
putNew(payload: Uint8Array, retentionMs: number, signal?: AbortSignal) {
|
|
80
|
+
return this.observe(
|
|
81
|
+
'relocation_put',
|
|
82
|
+
() => putNewRelocationBlobCore(this.provider, payload, retentionMs, signal),
|
|
83
|
+
signal
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
put(...args: Parameters<ZLinkRelocationStore['put']>) {
|
|
87
|
+
return this.observe('relocation_put', () => this.provider.put(...args), args[3]);
|
|
88
|
+
}
|
|
89
|
+
read(...args: Parameters<ZLinkRelocationStore['read']>) {
|
|
90
|
+
return this.observe('relocation_get', () => this.provider.read(...args), args[1]);
|
|
91
|
+
}
|
|
92
|
+
renew(...args: Parameters<ZLinkRelocationStore['renew']>) {
|
|
93
|
+
return this.observe('relocation_put', () => this.provider.renew(...args), args[2]);
|
|
94
|
+
}
|
|
95
|
+
delete(...args: Parameters<ZLinkRelocationStore['delete']>) {
|
|
96
|
+
return this.observe('relocation_delete', () => this.provider.delete(...args), args[1]);
|
|
97
|
+
}
|
|
98
|
+
private async observe<T>(
|
|
99
|
+
operation: 'relocation_put' | 'relocation_get' | 'relocation_delete',
|
|
100
|
+
request: () => Promise<T>,
|
|
101
|
+
signal?: AbortSignal
|
|
102
|
+
): Promise<T> {
|
|
103
|
+
try {
|
|
104
|
+
return await request();
|
|
105
|
+
} catch (error) {
|
|
106
|
+
if (isRelocationProviderFailure(error, signal)) {
|
|
107
|
+
this.metrics.recordLocationStoreError(operation);
|
|
108
|
+
}
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function isRelocationProviderFailure(error: unknown, signal?: AbortSignal): boolean {
|
|
115
|
+
return (
|
|
116
|
+
isIndeterminateLocationStoreFailure(error, signal) &&
|
|
117
|
+
!(
|
|
118
|
+
error instanceof ZLinkFrameworkException && error.kind !== ZLinkFrameworkErrorKind.Unavailable
|
|
119
|
+
)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { RoutingId } from '../../contracts/Common';
|
|
2
|
+
import type { ZLinkMeshNodeDescriptor } from '../../contracts/Locations/Rows';
|
|
3
|
+
import type { ZLinkLocationOwnerToken } from './internal-location-contracts';
|
|
4
|
+
import { encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
|
|
5
|
+
import { awaitWithAbort, throwIfAborted } from '../abort';
|
|
6
|
+
|
|
7
|
+
/** Source request owner values the first accepting owner records (Location runtime §9.3). */
|
|
8
|
+
export interface ZLinkRequestSourceFence {
|
|
9
|
+
readonly ownerId: string;
|
|
10
|
+
readonly leaseGeneration: bigint;
|
|
11
|
+
readonly nodeRid: RoutingId;
|
|
12
|
+
readonly nodeGeneration: bigint;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ZLinkRequestSourceResolverOptions {
|
|
16
|
+
readonly listLiveMeshNodes: (
|
|
17
|
+
meshName: string,
|
|
18
|
+
signal?: AbortSignal
|
|
19
|
+
) => Promise<readonly ZLinkMeshNodeDescriptor[]>;
|
|
20
|
+
readonly remainingOwnerTokenLeaseMs: (
|
|
21
|
+
owner: ZLinkLocationOwnerToken,
|
|
22
|
+
signal?: AbortSignal
|
|
23
|
+
) => Promise<number>;
|
|
24
|
+
readonly monotonicNowMs?: () => number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface PolledSource {
|
|
28
|
+
readonly fence: ZLinkRequestSourceFence;
|
|
29
|
+
readonly leaseDeadlineMs: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Chooses the descriptor that supplies the source request owner values (Session·Actor binding
|
|
34
|
+
* §4): the admitted sender's descriptor with the exact RID and node lifecycle generation whose
|
|
35
|
+
* owner lease passes the Location runtime §4.1 check. Auto-connect polling keeps the live
|
|
36
|
+
* descriptors here with the local lease deadline computed from the same lease read. A sender
|
|
37
|
+
* missing from them is read from the Store once and kept with them.
|
|
38
|
+
*/
|
|
39
|
+
export class ZLinkRequestSourceResolver {
|
|
40
|
+
private readonly polled = new Map<string, Map<string, PolledSource>>();
|
|
41
|
+
private readonly monotonicNowMs: () => number;
|
|
42
|
+
|
|
43
|
+
constructor(private readonly options: ZLinkRequestSourceResolverOptions) {
|
|
44
|
+
this.monotonicNowMs = options.monotonicNowMs ?? (() => performance.now());
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Replaces the polled descriptors of one mesh with a live descriptor listing. */
|
|
48
|
+
async observeLiveDescriptors(
|
|
49
|
+
meshName: string,
|
|
50
|
+
descriptors: readonly ZLinkMeshNodeDescriptor[],
|
|
51
|
+
signal?: AbortSignal
|
|
52
|
+
): Promise<void> {
|
|
53
|
+
const sources = new Map<string, PolledSource>();
|
|
54
|
+
for (const descriptor of descriptors) {
|
|
55
|
+
const source = await this.polledSource(descriptor, signal);
|
|
56
|
+
if (source !== undefined) sources.set(encodeRoutingIdStorageHex(descriptor.rid), source);
|
|
57
|
+
}
|
|
58
|
+
this.polled.set(meshName, sources);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns the recorded values, undefined when the sender has no live descriptor, or a promise
|
|
63
|
+
* while the Store is read once for a sender the polled descriptors do not contain.
|
|
64
|
+
*/
|
|
65
|
+
accept(
|
|
66
|
+
meshName: string,
|
|
67
|
+
nodeRid: RoutingId,
|
|
68
|
+
nodeGeneration: bigint,
|
|
69
|
+
nodeRidStorageHex: string,
|
|
70
|
+
signal?: AbortSignal
|
|
71
|
+
): ZLinkRequestSourceFence | undefined | Promise<ZLinkRequestSourceFence | undefined> {
|
|
72
|
+
throwIfAborted(signal);
|
|
73
|
+
const known = this.polled.get(meshName)?.get(nodeRidStorageHex);
|
|
74
|
+
if (known !== undefined && known.fence.nodeGeneration === nodeGeneration) {
|
|
75
|
+
return this.monotonicNowMs() < known.leaseDeadlineMs ? known.fence : undefined;
|
|
76
|
+
}
|
|
77
|
+
return this.readOnce(meshName, nodeRid, nodeGeneration, nodeRidStorageHex, signal);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private async readOnce(
|
|
81
|
+
meshName: string,
|
|
82
|
+
nodeRid: RoutingId,
|
|
83
|
+
nodeGeneration: bigint,
|
|
84
|
+
nodeRidStorageHex: string,
|
|
85
|
+
signal?: AbortSignal
|
|
86
|
+
): Promise<ZLinkRequestSourceFence | undefined> {
|
|
87
|
+
// The Store boundary already classifies provider failures as Unavailable. Preserve their
|
|
88
|
+
// cause for the ingress error reporter, and let programming errors propagate unchanged.
|
|
89
|
+
const descriptors = await awaitWithAbort(
|
|
90
|
+
this.options.listLiveMeshNodes(meshName, signal),
|
|
91
|
+
signal
|
|
92
|
+
);
|
|
93
|
+
const descriptor = descriptors.find(
|
|
94
|
+
(value) => routingIdsEqual(value.rid, nodeRid) && value.lifecycleGeneration === nodeGeneration
|
|
95
|
+
);
|
|
96
|
+
const source =
|
|
97
|
+
descriptor === undefined ? undefined : await this.polledSource(descriptor, signal);
|
|
98
|
+
throwIfAborted(signal);
|
|
99
|
+
if (source === undefined) return undefined;
|
|
100
|
+
let sources = this.polled.get(meshName);
|
|
101
|
+
if (sources === undefined) {
|
|
102
|
+
sources = new Map();
|
|
103
|
+
this.polled.set(meshName, sources);
|
|
104
|
+
}
|
|
105
|
+
sources.set(nodeRidStorageHex, source);
|
|
106
|
+
return source.fence;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private async polledSource(
|
|
110
|
+
descriptor: ZLinkMeshNodeDescriptor,
|
|
111
|
+
signal?: AbortSignal
|
|
112
|
+
): Promise<PolledSource | undefined> {
|
|
113
|
+
if (
|
|
114
|
+
descriptor.ownerId.length === 0 ||
|
|
115
|
+
descriptor.leaseGeneration <= 0n ||
|
|
116
|
+
descriptor.lifecycleGeneration <= 0n
|
|
117
|
+
) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
const remainingMs = await awaitWithAbort(
|
|
121
|
+
this.options.remainingOwnerTokenLeaseMs(
|
|
122
|
+
{ ownerId: descriptor.ownerId, leaseGeneration: descriptor.leaseGeneration },
|
|
123
|
+
signal
|
|
124
|
+
),
|
|
125
|
+
signal
|
|
126
|
+
);
|
|
127
|
+
if (remainingMs <= 0) return undefined;
|
|
128
|
+
return {
|
|
129
|
+
fence: {
|
|
130
|
+
ownerId: descriptor.ownerId,
|
|
131
|
+
leaseGeneration: descriptor.leaseGeneration,
|
|
132
|
+
nodeRid: descriptor.rid,
|
|
133
|
+
nodeGeneration: descriptor.lifecycleGeneration
|
|
134
|
+
},
|
|
135
|
+
leaseDeadlineMs: this.monotonicNowMs() + remainingMs
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
createInternalFrameworkException,
|
|
18
18
|
internalFrameworkErrorKind
|
|
19
19
|
} from '../framework-errors-internal';
|
|
20
|
-
import { routingIdsEqual } from '../routing-id';
|
|
20
|
+
import { encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
|
|
21
21
|
import {
|
|
22
22
|
type SpotHandle,
|
|
23
23
|
type ZLinkActorSpotHandleResolver,
|
|
@@ -282,7 +282,7 @@ export class ZLinkStoreLocationResolvers
|
|
|
282
282
|
descriptor.objectRole === ZLinkObjectRole.Server &&
|
|
283
283
|
descriptor.placementWeight > 0 &&
|
|
284
284
|
!routingIdsEqual(descriptor.rid, excludedNodeRid) &&
|
|
285
|
-
!excludedCandidateRids.has(
|
|
285
|
+
!excludedCandidateRids.has(encodeRoutingIdStorageHex(descriptor.rid)) &&
|
|
286
286
|
capacity.active + capacity.reserved < capacity.limit &&
|
|
287
287
|
descriptor.objectCapabilities.some(
|
|
288
288
|
(candidate) => candidate.objectKind === 'actor' && candidate.stableType === actorType
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ZLinkDescriptorPublicationUnconfirmedError } from './descriptor-publication';
|
|
2
|
+
import { isIndeterminateLocationStoreFailure } from './location-store-failure';
|
|
1
3
|
import { listAllMeshNodeDescriptors } from './location-store-pages';
|
|
2
4
|
import { MILLISECONDS_PER_SECOND } from '../diagnostics/runtime-metrics';
|
|
3
5
|
import { ZLINK_PROVIDER_MAX_PAGE_SIZE } from '../../contracts/Locations/Stores';
|
|
@@ -148,7 +150,9 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
148
150
|
private readonly liveRows: ZLinkLiveRowFilter;
|
|
149
151
|
private readonly leaseTracker: ZLinkOwnerLeaseTracker;
|
|
150
152
|
private readonly ownershipLostHandlers = new Set<(event: ZLinkOwnershipLostEvent) => void>();
|
|
151
|
-
private readonly ownerLeaseRenewedHandlers = new Set<
|
|
153
|
+
private readonly ownerLeaseRenewedHandlers = new Set<
|
|
154
|
+
(renewal: ZLinkOwnerLeaseRenewed, wasOwnerLeaseUsable: boolean) => void
|
|
155
|
+
>();
|
|
152
156
|
private readonly ownerLeaseRenewalFailedHandlers = new Set<() => void>();
|
|
153
157
|
private heartbeatTimer: unknown;
|
|
154
158
|
private heartbeatRenewal?: Promise<unknown>;
|
|
@@ -216,9 +220,22 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
216
220
|
return this.ownerToken;
|
|
217
221
|
}
|
|
218
222
|
|
|
223
|
+
/** Location runtime §5: a startup Store request ends within the renew timeout. */
|
|
224
|
+
async writeDescriptor<T>(
|
|
225
|
+
action: (signal?: AbortSignal) => Promise<T>,
|
|
226
|
+
signal?: AbortSignal
|
|
227
|
+
): Promise<T> {
|
|
228
|
+
try {
|
|
229
|
+
return await withTimeout(action, this.options.ownerLeaseRenewTimeoutMs, signal);
|
|
230
|
+
} catch (error) {
|
|
231
|
+
if (!isIndeterminateLocationStoreFailure(error, signal)) throw error;
|
|
232
|
+
throw new ZLinkDescriptorPublicationUnconfirmedError(error);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
219
236
|
closeOwnerLeaseAdmission(error: unknown): void {
|
|
220
237
|
this.ownerLeaseDeadlineMs = undefined;
|
|
221
|
-
this.recordFailure(errorMessage(error)
|
|
238
|
+
this.recordFailure(errorMessage(error));
|
|
222
239
|
}
|
|
223
240
|
|
|
224
241
|
async reclaimOwnerAuthorities(signal?: AbortSignal): Promise<void> {
|
|
@@ -308,11 +325,15 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
308
325
|
this.ownershipLostHandlers.delete(handler);
|
|
309
326
|
}
|
|
310
327
|
|
|
311
|
-
addOwnerLeaseRenewedHandler(
|
|
328
|
+
addOwnerLeaseRenewedHandler(
|
|
329
|
+
handler: (renewal: ZLinkOwnerLeaseRenewed, wasOwnerLeaseUsable: boolean) => void
|
|
330
|
+
): void {
|
|
312
331
|
this.ownerLeaseRenewedHandlers.add(handler);
|
|
313
332
|
}
|
|
314
333
|
|
|
315
|
-
removeOwnerLeaseRenewedHandler(
|
|
334
|
+
removeOwnerLeaseRenewedHandler(
|
|
335
|
+
handler: (renewal: ZLinkOwnerLeaseRenewed, wasOwnerLeaseUsable: boolean) => void
|
|
336
|
+
): void {
|
|
316
337
|
this.ownerLeaseRenewedHandlers.delete(handler);
|
|
317
338
|
}
|
|
318
339
|
|
|
@@ -414,7 +435,6 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
414
435
|
return await this.claimFreshOwnerLease(signal, shutdownSignal);
|
|
415
436
|
}
|
|
416
437
|
|
|
417
|
-
const wasOwnerLeaseUsable = this.ownerLeaseUsable;
|
|
418
438
|
try {
|
|
419
439
|
const renewStartedAtMs = this.monotonicNowMs();
|
|
420
440
|
this.leaseOperationStartedAtMs = renewStartedAtMs;
|
|
@@ -444,6 +464,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
444
464
|
// another heartbeat interval.
|
|
445
465
|
return await this.claimFreshOwnerLease(signal, shutdownSignal);
|
|
446
466
|
}
|
|
467
|
+
const wasOwnerLeaseUsable = this.ownerLeaseUsable;
|
|
447
468
|
this.ownerLeaseHealthy = true;
|
|
448
469
|
this.ownerLeaseRenewedAt = result.storeNow;
|
|
449
470
|
this.setOwnerLeaseDeadline(
|
|
@@ -453,14 +474,14 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
453
474
|
result.storeNow
|
|
454
475
|
);
|
|
455
476
|
this.lastError = undefined;
|
|
456
|
-
|
|
457
|
-
|
|
477
|
+
for (const handler of this.ownerLeaseRenewedHandlers) {
|
|
478
|
+
handler(result, wasOwnerLeaseUsable);
|
|
458
479
|
}
|
|
459
480
|
return true;
|
|
460
481
|
} catch (error) {
|
|
461
482
|
if (signal?.aborted === true) throw error;
|
|
462
483
|
this.recordOwnerLeaseRenewFailure();
|
|
463
|
-
this.recordFailure(errorMessage(error)
|
|
484
|
+
this.recordFailure(errorMessage(error));
|
|
464
485
|
for (const handler of this.ownerLeaseRenewalFailedHandlers) handler();
|
|
465
486
|
return false;
|
|
466
487
|
}
|
|
@@ -484,13 +505,13 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
484
505
|
if (signal?.aborted === true) throw error;
|
|
485
506
|
if (error instanceof ZLinkOwnerLeaseClaimError) throw error;
|
|
486
507
|
this.recordOwnerLeaseRenewFailure();
|
|
487
|
-
this.recordFailure(errorMessage(error)
|
|
508
|
+
this.recordFailure(errorMessage(error));
|
|
488
509
|
return false;
|
|
489
510
|
}
|
|
490
511
|
const claimCompletedAtMs = this.monotonicNowMs();
|
|
491
512
|
if (claim.kind !== 'claimed') {
|
|
492
513
|
const error = new ZLinkOwnerLeaseClaimError(claim.kind);
|
|
493
|
-
this.recordFailure(error.message
|
|
514
|
+
this.recordFailure(error.message);
|
|
494
515
|
throw error;
|
|
495
516
|
}
|
|
496
517
|
try {
|
|
@@ -510,16 +531,19 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
510
531
|
);
|
|
511
532
|
this.lastError = undefined;
|
|
512
533
|
for (const handler of this.ownerLeaseRenewedHandlers) {
|
|
513
|
-
handler(
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
534
|
+
handler(
|
|
535
|
+
{
|
|
536
|
+
kind: 'renewed',
|
|
537
|
+
leaseExpiresAt: claim.leaseExpiresAt,
|
|
538
|
+
storeNow: claim.storeNow
|
|
539
|
+
},
|
|
540
|
+
false
|
|
541
|
+
);
|
|
518
542
|
}
|
|
519
543
|
return true;
|
|
520
544
|
} catch (error) {
|
|
521
545
|
if (signal?.aborted === true) throw error;
|
|
522
|
-
this.recordFailure(errorMessage(error)
|
|
546
|
+
this.recordFailure(errorMessage(error));
|
|
523
547
|
return false;
|
|
524
548
|
}
|
|
525
549
|
}
|
|
@@ -563,7 +587,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
563
587
|
throw new ZLinkOwnerCleanupError(completionError);
|
|
564
588
|
}
|
|
565
589
|
if (!isAbortError(completionError)) {
|
|
566
|
-
this.recordFailure(errorMessage(completionError)
|
|
590
|
+
this.recordFailure(errorMessage(completionError));
|
|
567
591
|
}
|
|
568
592
|
}
|
|
569
593
|
}
|
|
@@ -607,9 +631,9 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
607
631
|
cleanupSignal
|
|
608
632
|
);
|
|
609
633
|
} catch (confirmationError) {
|
|
610
|
-
this.recordFailure(errorMessage(confirmationError)
|
|
634
|
+
this.recordFailure(errorMessage(confirmationError));
|
|
611
635
|
if (cancelled) throw new ZLinkOwnerCleanupError(confirmationError);
|
|
612
|
-
throw confirmationError;
|
|
636
|
+
throw originalError instanceof ZLinkOwnerLeaseClaimError ? originalError : confirmationError;
|
|
613
637
|
}
|
|
614
638
|
if (confirmed.kind !== 'found' || confirmed.token.ownerId !== this.ownerId) {
|
|
615
639
|
throw originalError;
|
|
@@ -625,7 +649,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
625
649
|
cleanupSignal
|
|
626
650
|
);
|
|
627
651
|
} catch (releaseError) {
|
|
628
|
-
this.recordFailure(errorMessage(releaseError)
|
|
652
|
+
this.recordFailure(errorMessage(releaseError));
|
|
629
653
|
throw new ZLinkOwnerCleanupError(releaseError);
|
|
630
654
|
}
|
|
631
655
|
throw originalError;
|
|
@@ -693,7 +717,10 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
693
717
|
updatedAt: new Date()
|
|
694
718
|
};
|
|
695
719
|
let result = await this.guardWrite(() =>
|
|
696
|
-
this.
|
|
720
|
+
this.writeDescriptor(
|
|
721
|
+
(writeSignal) => this.stores.locationStore.updateMeshNode(stamped, intent, writeSignal),
|
|
722
|
+
signal
|
|
723
|
+
)
|
|
697
724
|
);
|
|
698
725
|
if (
|
|
699
726
|
intent === ZLinkLocationWriteIntent.Renew &&
|
|
@@ -705,7 +732,15 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
705
732
|
// NewClaim as a bounded fallback. If another owner has recreated the
|
|
706
733
|
// row, NewClaim remains rejected and the caller keeps the conflict.
|
|
707
734
|
result = await this.guardWrite(() =>
|
|
708
|
-
this.
|
|
735
|
+
this.writeDescriptor(
|
|
736
|
+
(writeSignal) =>
|
|
737
|
+
this.stores.locationStore.updateMeshNode(
|
|
738
|
+
stamped,
|
|
739
|
+
ZLinkLocationWriteIntent.NewClaim,
|
|
740
|
+
writeSignal
|
|
741
|
+
),
|
|
742
|
+
signal
|
|
743
|
+
)
|
|
709
744
|
);
|
|
710
745
|
}
|
|
711
746
|
this.notifyIfStale(
|
|
@@ -912,7 +947,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
912
947
|
}
|
|
913
948
|
|
|
914
949
|
reportDiscoveryFailure(error: unknown): void {
|
|
915
|
-
this.recordFailure(errorMessage(error)
|
|
950
|
+
this.recordFailure(errorMessage(error));
|
|
916
951
|
}
|
|
917
952
|
|
|
918
953
|
async listPeerLocations(
|
|
@@ -945,6 +980,14 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
945
980
|
return live.map((row) => ({ ...row, endpoint: normalizeEndpoint(row.endpoint) }));
|
|
946
981
|
}
|
|
947
982
|
|
|
983
|
+
/** Remaining exact owner lease from the same tracker that filters live descriptors. */
|
|
984
|
+
remainingOwnerTokenLeaseMs(
|
|
985
|
+
owner: ZLinkLocationOwnerToken,
|
|
986
|
+
signal?: AbortSignal
|
|
987
|
+
): Promise<number> {
|
|
988
|
+
return this.leaseTracker.remainingOwnerTokenLeaseMs(owner, signal);
|
|
989
|
+
}
|
|
990
|
+
|
|
948
991
|
async listMeshNodeDescriptors(
|
|
949
992
|
meshName: string,
|
|
950
993
|
page?: ZLinkPageRequest,
|
|
@@ -1269,7 +1312,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
1269
1312
|
this.monotonicNowMs() >= this.ownerLeaseDeadlineMs
|
|
1270
1313
|
) {
|
|
1271
1314
|
this.ownerLeaseHealthy = false;
|
|
1272
|
-
this.recordFailure('Owner lease expired before renewal completed.'
|
|
1315
|
+
this.recordFailure('Owner lease expired before renewal completed.');
|
|
1273
1316
|
for (const handler of this.ownerLeaseRenewalFailedHandlers) handler();
|
|
1274
1317
|
}
|
|
1275
1318
|
const renewal = this.renewOwnerLeaseOnce()
|
|
@@ -1294,7 +1337,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
1294
1337
|
try {
|
|
1295
1338
|
return await write();
|
|
1296
1339
|
} catch (error) {
|
|
1297
|
-
this.recordFailure(errorMessage(error)
|
|
1340
|
+
this.recordFailure(errorMessage(error));
|
|
1298
1341
|
throw error;
|
|
1299
1342
|
}
|
|
1300
1343
|
}
|
|
@@ -1305,7 +1348,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
1305
1348
|
try {
|
|
1306
1349
|
return await write();
|
|
1307
1350
|
} catch (error) {
|
|
1308
|
-
this.recordFailure(errorMessage(error)
|
|
1351
|
+
this.recordFailure(errorMessage(error));
|
|
1309
1352
|
throw error;
|
|
1310
1353
|
}
|
|
1311
1354
|
}
|
|
@@ -1315,12 +1358,6 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
1315
1358
|
kind: ZLinkLocationKind,
|
|
1316
1359
|
key: string
|
|
1317
1360
|
): void {
|
|
1318
|
-
if (
|
|
1319
|
-
result.status === ZLinkLocationWriteStatus.IgnoredStale ||
|
|
1320
|
-
result.status === ZLinkLocationWriteStatus.RejectedConflict
|
|
1321
|
-
) {
|
|
1322
|
-
this.metrics?.recordLocationStoreError('compare_exchange');
|
|
1323
|
-
}
|
|
1324
1361
|
if (result.status !== ZLinkLocationWriteStatus.IgnoredStale) {
|
|
1325
1362
|
return;
|
|
1326
1363
|
}
|
|
@@ -1334,12 +1371,6 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
1334
1371
|
kind: ZLinkLocationKind,
|
|
1335
1372
|
key: string
|
|
1336
1373
|
): void {
|
|
1337
|
-
if (
|
|
1338
|
-
status === ZLinkLocationWriteStatus.IgnoredStale ||
|
|
1339
|
-
status === ZLinkLocationWriteStatus.RejectedConflict
|
|
1340
|
-
) {
|
|
1341
|
-
this.metrics?.recordLocationStoreError('compare_exchange');
|
|
1342
|
-
}
|
|
1343
1374
|
if (status !== ZLinkLocationWriteStatus.IgnoredStale) {
|
|
1344
1375
|
return;
|
|
1345
1376
|
}
|
|
@@ -1348,8 +1379,7 @@ export class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
|
|
|
1348
1379
|
}
|
|
1349
1380
|
}
|
|
1350
1381
|
|
|
1351
|
-
private recordFailure(message: string
|
|
1352
|
-
this.metrics?.recordLocationStoreError(operation);
|
|
1382
|
+
private recordFailure(message: string): void {
|
|
1353
1383
|
this.ownerLeaseHealthy = false;
|
|
1354
1384
|
this.lastError = message;
|
|
1355
1385
|
}
|
|
@@ -17,10 +17,7 @@ import {
|
|
|
17
17
|
materializeZLinkMessageValue,
|
|
18
18
|
readZLinkMessageDeclaredType
|
|
19
19
|
} from '../../contracts/Common/ZLinkMessage';
|
|
20
|
-
import {
|
|
21
|
-
adoptEncodedPayload,
|
|
22
|
-
borrowEncodedPayload
|
|
23
|
-
} from '../../contracts/Common/encoded-payload-storage';
|
|
20
|
+
import { borrowEncodedPayload } from '../../contracts/Common/encoded-payload-storage';
|
|
24
21
|
import { ZLinkConfigurationException } from '../configuration';
|
|
25
22
|
import { parseFrameworkJsonV1, stringifyFrameworkJsonV1 } from './framework-json-v1';
|
|
26
23
|
import type { ZLinkJsonSchema } from '../../contracts/Handlers/JsonContract';
|
|
@@ -434,13 +431,13 @@ function toRuntimeMessage(payload: ZLinkEncodedPayload): Message {
|
|
|
434
431
|
: RuntimeMessage.fromOwned(owned);
|
|
435
432
|
}
|
|
436
433
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
return
|
|
434
|
+
/**
|
|
435
|
+
* Wraps received bytes for a serializer without copying them. Binding receive
|
|
436
|
+
* Buffers keep their storage after the message closes and nothing writes to
|
|
437
|
+
* them, so the payload may adopt them; the public from() and data() still copy.
|
|
438
|
+
*/
|
|
439
|
+
export function encodedPayloadFromOwned(bytes: Uint8Array): ZLinkEncodedPayload {
|
|
440
|
+
return ZLinkEncodedPayload.fromOwned(bytes);
|
|
444
441
|
}
|
|
445
442
|
|
|
446
443
|
function rememberContentType(message: Message, contentType: string): Message {
|
|
@@ -3,56 +3,60 @@ import type { ZLinkRequest } from '../../contracts/Handlers/Attributes';
|
|
|
3
3
|
const completedAdmission = Promise.resolve();
|
|
4
4
|
const ignoreAdmissionFailure = (): void => {};
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const failAdmission = (error: unknown): void => {
|
|
18
|
-
if (admitted === undefined) {
|
|
19
|
-
admitted = Promise.reject(error);
|
|
6
|
+
class RequestAdmission {
|
|
7
|
+
private admitted: Promise<void> | undefined;
|
|
8
|
+
private resolveAdmission: (() => void) | undefined;
|
|
9
|
+
private rejectAdmission: ((error: unknown) => void) | undefined;
|
|
10
|
+
confirm(): void {
|
|
11
|
+
this.admitted ??= completedAdmission;
|
|
12
|
+
this.resolveAdmission?.();
|
|
13
|
+
}
|
|
14
|
+
fail(error: unknown): void {
|
|
15
|
+
if (this.admitted === undefined) {
|
|
16
|
+
this.admitted = Promise.reject(error);
|
|
20
17
|
// Existing callers may observe only the reply Promise. Observing the
|
|
21
18
|
// rejection here leaves the public admission Promise rejected.
|
|
22
|
-
void admitted.catch(ignoreAdmissionFailure);
|
|
19
|
+
void this.admitted.catch(ignoreAdmissionFailure);
|
|
23
20
|
} else {
|
|
24
|
-
rejectAdmission?.(error);
|
|
21
|
+
this.rejectAdmission?.(error);
|
|
25
22
|
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (admitted === undefined) {
|
|
29
|
-
admitted = new Promise<void>((resolve, reject) => {
|
|
30
|
-
resolveAdmission = resolve;
|
|
31
|
-
rejectAdmission = reject;
|
|
23
|
+
}
|
|
24
|
+
observe(): Promise<void> {
|
|
25
|
+
if (this.admitted === undefined) {
|
|
26
|
+
this.admitted = new Promise<void>((resolve, reject) => {
|
|
27
|
+
this.resolveAdmission = resolve;
|
|
28
|
+
this.rejectAdmission = reject;
|
|
32
29
|
});
|
|
33
|
-
void admitted.catch(ignoreAdmissionFailure);
|
|
30
|
+
void this.admitted.catch(ignoreAdmissionFailure);
|
|
34
31
|
}
|
|
35
|
-
return admitted;
|
|
36
|
-
}
|
|
32
|
+
return this.admitted;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function createZLinkRequest<TReply>(
|
|
37
|
+
start: (onAdmitted: () => void) => Promise<TReply>,
|
|
38
|
+
deliverReply?: (reply: Promise<TReply>) => Promise<TReply>
|
|
39
|
+
): ZLinkRequest<TReply> {
|
|
40
|
+
const admission = new RequestAdmission();
|
|
37
41
|
let pending: Promise<TReply>;
|
|
38
42
|
try {
|
|
39
|
-
pending = start(
|
|
43
|
+
pending = start(() => admission.confirm());
|
|
40
44
|
} catch (error) {
|
|
41
45
|
pending = Promise.reject(error);
|
|
42
46
|
}
|
|
43
47
|
const observed = pending.then(
|
|
44
48
|
(value) => {
|
|
45
49
|
// A successful reply proves admission even without an observation callback.
|
|
46
|
-
|
|
50
|
+
admission.confirm();
|
|
47
51
|
return value;
|
|
48
52
|
},
|
|
49
53
|
(error: unknown) => {
|
|
50
|
-
|
|
54
|
+
admission.fail(error);
|
|
51
55
|
throw error;
|
|
52
56
|
}
|
|
53
57
|
);
|
|
54
58
|
const reply = deliverReply?.(observed) ?? observed;
|
|
55
59
|
return Object.defineProperty(reply, 'admitted', {
|
|
56
|
-
get:
|
|
60
|
+
get: () => admission.observe()
|
|
57
61
|
}) as ZLinkRequest<TReply>;
|
|
58
62
|
}
|