@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,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkLocationStoreRepository = void 0;
|
|
4
|
+
const routing_id_1 = require("../routing-id");
|
|
4
5
|
const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
|
|
5
6
|
const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
|
|
6
7
|
const actor_authority_payload_codec_1 = require("../actors/actor-authority-payload-codec");
|
|
@@ -15,7 +16,7 @@ const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/Regis
|
|
|
15
16
|
const Locations_1 = require("../../contracts/Locations");
|
|
16
17
|
const Stores_1 = require("../../contracts/Locations/Stores");
|
|
17
18
|
const actor_join_recovery_codec_1 = require("../foundation/actor-join-recovery-codec");
|
|
18
|
-
const
|
|
19
|
+
const routing_id_2 = require("../routing-id");
|
|
19
20
|
const aggregate_inventory_store_1 = require("./aggregate-inventory-store");
|
|
20
21
|
const authority_key_codec_1 = require("./authority-key-codec");
|
|
21
22
|
const in_memory_location_store_1 = require("./in-memory-location-store");
|
|
@@ -45,28 +46,47 @@ const MAX_OWNER_CLEANUP_BATCH_ROWS = 2_047;
|
|
|
45
46
|
*/
|
|
46
47
|
class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMemoryLocationStore {
|
|
47
48
|
nowProvider;
|
|
49
|
+
metrics;
|
|
48
50
|
provider;
|
|
51
|
+
confirmedCapacities = new Map();
|
|
49
52
|
aggregateInventory;
|
|
50
|
-
constructor(provider, nowProvider = () => new Date()) {
|
|
53
|
+
constructor(provider, nowProvider = () => new Date(), metrics) {
|
|
51
54
|
super(nowProvider);
|
|
52
55
|
this.nowProvider = nowProvider;
|
|
56
|
+
this.metrics = metrics;
|
|
53
57
|
// Classify only failures of the opaque SPI, before interpreting its records.
|
|
58
|
+
const confirm = (key, bytes) => {
|
|
59
|
+
if (this.confirmedCapacities.has(key.value)) {
|
|
60
|
+
this.confirmedCapacities.set(key.value, bytes === undefined ? emptyCapacityRecord() : decodeJson(bytes));
|
|
61
|
+
}
|
|
62
|
+
};
|
|
54
63
|
this.provider = {
|
|
55
64
|
async read(key, signal) {
|
|
65
|
+
let result;
|
|
56
66
|
try {
|
|
57
|
-
|
|
67
|
+
result = await provider.read(key, signal);
|
|
58
68
|
}
|
|
59
69
|
catch (error) {
|
|
60
70
|
throw locationStoreProviderFailure(error, signal);
|
|
61
71
|
}
|
|
72
|
+
confirm(key, result.kind === 'found' ? result.value.bytes : undefined);
|
|
73
|
+
return result;
|
|
62
74
|
},
|
|
63
75
|
async write(request, signal) {
|
|
76
|
+
let result;
|
|
64
77
|
try {
|
|
65
|
-
|
|
78
|
+
result = await provider.write(request, signal);
|
|
66
79
|
}
|
|
67
80
|
catch (error) {
|
|
68
81
|
throw locationStoreProviderFailure(error, signal);
|
|
69
82
|
}
|
|
83
|
+
if (result.kind === 'applied') {
|
|
84
|
+
for (const mutation of request.mutations) {
|
|
85
|
+
if (mutation.kind === 'put')
|
|
86
|
+
confirm(mutation.key, mutation.bytes);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
70
90
|
},
|
|
71
91
|
async scan(request, signal) {
|
|
72
92
|
try {
|
|
@@ -79,7 +99,26 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
79
99
|
};
|
|
80
100
|
this.aggregateInventory = new aggregate_inventory_store_1.ZLinkAggregateInventoryStore(this.provider);
|
|
81
101
|
}
|
|
102
|
+
async observeStore(operation, request) {
|
|
103
|
+
try {
|
|
104
|
+
return await request();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (error instanceof contracts_2.ZLinkFrameworkException &&
|
|
108
|
+
error.kind === contracts_2.ZLinkFrameworkErrorKind.Unavailable) {
|
|
109
|
+
this.metrics?.recordLocationStoreError(operation);
|
|
110
|
+
}
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
confirmedCapacity(key, limits) {
|
|
115
|
+
const record = this.confirmedCapacities.get(capacityKey(key.meshName, String(key.rid)).value);
|
|
116
|
+
return record === undefined ? undefined : projectCapacity(limits, record);
|
|
117
|
+
}
|
|
82
118
|
async readAuthority(key, signal) {
|
|
119
|
+
return this.observeStore('read', () => this.readAuthorityRequest(key, signal));
|
|
120
|
+
}
|
|
121
|
+
async readAuthorityRequest(key, signal) {
|
|
83
122
|
const result = await this.provider.read(authorityKey(key.value), signal);
|
|
84
123
|
if (result.kind === 'missing') {
|
|
85
124
|
return { kind: 'missing', storeNow: result.storeNow };
|
|
@@ -87,6 +126,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
87
126
|
return await this.projectAuthority(decodeAuthorityRecord(result.value.bytes), result.value.version, result.value.storeNow, signal);
|
|
88
127
|
}
|
|
89
128
|
async listAuthorities(prefix, cursor, limit, signal) {
|
|
129
|
+
return this.observeStore('read', () => this.listAuthoritiesRequest(prefix, cursor, limit, signal));
|
|
130
|
+
}
|
|
131
|
+
async listAuthoritiesRequest(prefix, cursor, limit, signal) {
|
|
90
132
|
if (!Number.isInteger(limit) || limit < 1 || limit > Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE) {
|
|
91
133
|
throw new RangeError(`Authority scan limit must be in 1..${Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE}.`);
|
|
92
134
|
}
|
|
@@ -114,6 +156,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
114
156
|
};
|
|
115
157
|
}
|
|
116
158
|
async compareExchangeAuthority(key, expectedStoreVersion, mutation, signal) {
|
|
159
|
+
return this.observeStore('compare_exchange', () => this.compareExchangeAuthorityRequest(key, expectedStoreVersion, mutation, signal));
|
|
160
|
+
}
|
|
161
|
+
async compareExchangeAuthorityRequest(key, expectedStoreVersion, mutation, signal) {
|
|
117
162
|
if (mutation.kind !== 'delete') {
|
|
118
163
|
validatePayloadSize(mutation.payload, 'Authority payload');
|
|
119
164
|
}
|
|
@@ -310,6 +355,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
310
355
|
}
|
|
311
356
|
}
|
|
312
357
|
async prepareAggregate(request, signal) {
|
|
358
|
+
return this.observeStore('compare_exchange', () => this.prepareAggregateRequest(request, signal));
|
|
359
|
+
}
|
|
360
|
+
async prepareAggregateRequest(request, signal) {
|
|
313
361
|
validateProviderAggregateRequest(request);
|
|
314
362
|
const fence = aggregateFence(request.aggregateId, request.aggregateGeneration);
|
|
315
363
|
const rowKey = aggregateKey(fence);
|
|
@@ -550,7 +598,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
550
598
|
const aggregateRecord = decodeJson(aggregateRaced.value.bytes);
|
|
551
599
|
if (aggregateRecord.requestFingerprint === fingerprint &&
|
|
552
600
|
(aggregateRecord.state === 'staging' || aggregateRecord.state === 'prepared')) {
|
|
553
|
-
return await this.
|
|
601
|
+
return await this.prepareAggregateRequest(request, signal);
|
|
554
602
|
}
|
|
555
603
|
}
|
|
556
604
|
await this.clearAggregateMarkers(fence, installed, signal);
|
|
@@ -622,6 +670,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
622
670
|
}
|
|
623
671
|
}
|
|
624
672
|
async commitAggregate(fence, signal) {
|
|
673
|
+
return this.observeStore('compare_exchange', () => this.commitAggregateRequest(fence, signal));
|
|
674
|
+
}
|
|
675
|
+
async commitAggregateRequest(fence, signal) {
|
|
625
676
|
validateAggregateFence(fence);
|
|
626
677
|
return await this.commitAggregateCore(fence, signal);
|
|
627
678
|
}
|
|
@@ -804,6 +855,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
804
855
|
}
|
|
805
856
|
}
|
|
806
857
|
async abortAggregate(fence, signal) {
|
|
858
|
+
return this.observeStore('compare_exchange', () => this.abortAggregateRequest(fence, signal));
|
|
859
|
+
}
|
|
860
|
+
async abortAggregateRequest(fence, signal) {
|
|
807
861
|
validateAggregateFence(fence);
|
|
808
862
|
const rowKey = aggregateKey(fence);
|
|
809
863
|
for (;;) {
|
|
@@ -859,6 +913,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
859
913
|
}
|
|
860
914
|
}
|
|
861
915
|
async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
|
|
916
|
+
return this.observeStore('release', () => this.releaseEndedReservationRequest(key, expectedStoreVersion, signal, request));
|
|
917
|
+
}
|
|
918
|
+
async releaseEndedReservationRequest(key, expectedStoreVersion, signal, request) {
|
|
862
919
|
return ((await this.tryReleaseEndedReservation(key, expectedStoreVersion, signal, request)) ===
|
|
863
920
|
'reclaimed');
|
|
864
921
|
}
|
|
@@ -881,9 +938,8 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
881
938
|
this.provider.read(descriptorKey, signal),
|
|
882
939
|
this.provider.read(capacityRowKey, signal)
|
|
883
940
|
]);
|
|
884
|
-
if (lease.kind === 'found' && lease.value.expiresAt === undefined)
|
|
885
|
-
throw new Error('Location Store owner lease record is invalid.');
|
|
886
941
|
const ownerLive = sameLiveOwner(lease, snapshot);
|
|
942
|
+
let members = [];
|
|
887
943
|
if (snapshot.allocation.state === 'active') {
|
|
888
944
|
if (ownerLive)
|
|
889
945
|
return 'notReclaimable';
|
|
@@ -896,42 +952,10 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
896
952
|
spot.stableType !== request.intent.stableType ||
|
|
897
953
|
spot.spotId !== request.key.globalId ||
|
|
898
954
|
spot.activationRecovery !== undefined;
|
|
899
|
-
if (spot?.kind === 'user_spot'
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
let snapshotHasMember = false;
|
|
904
|
-
let cursor;
|
|
905
|
-
do {
|
|
906
|
-
const page = await this.provider.scan({ prefix, cursor, limit: Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE }, signal);
|
|
907
|
-
if (page.kind === 'expired')
|
|
908
|
-
continue membershipSnapshot;
|
|
909
|
-
for (const item of page.value.items) {
|
|
910
|
-
if (prefix === `${PREFIX}actor:`) {
|
|
911
|
-
const actor = normalizeActor(decodeJson(item.value.bytes).descriptor);
|
|
912
|
-
snapshotHasMember ||=
|
|
913
|
-
actor.spotKind === contracts_1.ZLinkSpotKind.User &&
|
|
914
|
-
String(actor.spotId) === spot.spotId &&
|
|
915
|
-
actor.spotGeneration === snapshot.objectGeneration;
|
|
916
|
-
}
|
|
917
|
-
else {
|
|
918
|
-
const authority = decodeAuthorityRecord(item.value.bytes).snapshot;
|
|
919
|
-
if (authority.allocation.objectKind !== 'actor')
|
|
920
|
-
continue;
|
|
921
|
-
const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(authority.payload));
|
|
922
|
-
snapshotHasMember ||=
|
|
923
|
-
actor?.currentSpotKind === contracts_1.ZLinkSpotKind.User &&
|
|
924
|
-
actor.currentSpotId === spot.spotId &&
|
|
925
|
-
actor.currentSpotGeneration === snapshot.objectGeneration;
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
cursor = page.value.nextCursor;
|
|
929
|
-
} while (cursor !== undefined);
|
|
930
|
-
unavailable ||= snapshotHasMember;
|
|
931
|
-
break;
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
}
|
|
955
|
+
if (spot?.kind === 'user_spot' &&
|
|
956
|
+
!unavailable &&
|
|
957
|
+
request?.actorRelocationPolicy === 'disabled')
|
|
958
|
+
members = await this.readEndedSpotMembers(spot.spotId, snapshot.objectGeneration, signal);
|
|
935
959
|
}
|
|
936
960
|
if (unavailable || request?.actorRelocationPolicy !== 'disabled')
|
|
937
961
|
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'Object owner lease is unavailable.');
|
|
@@ -943,48 +967,136 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
943
967
|
if (snapshot.allocation.state !== 'active' &&
|
|
944
968
|
(record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload)))
|
|
945
969
|
return 'notReclaimable';
|
|
970
|
+
// Location runtime §6.1: the authority and every ended-owner member are released in
|
|
971
|
+
// one conditional batch. Each member is fenced by its row version and the observed
|
|
972
|
+
// (invalid) state of its own owner lease; member capacity is returned like the Spot's.
|
|
973
|
+
const conditions = [
|
|
974
|
+
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
975
|
+
conditionFor(descriptorKey, descriptor)
|
|
976
|
+
];
|
|
946
977
|
const mutations = [
|
|
947
978
|
{ kind: 'delete', key: rowKey }
|
|
948
979
|
];
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
980
|
+
const owners = new Map([[snapshot.ownerId, lease]]);
|
|
981
|
+
for (const member of members) {
|
|
982
|
+
let memberLease = owners.get(member.ownerId);
|
|
983
|
+
if (memberLease === undefined) {
|
|
984
|
+
memberLease = await this.provider.read(ownerKey(member.ownerId), signal);
|
|
985
|
+
owners.set(member.ownerId, memberLease);
|
|
986
|
+
}
|
|
987
|
+
if (memberLease.kind === 'found' &&
|
|
988
|
+
matchesLiveOwnerLease(memberLease, member.ownerId, member.leaseGeneration))
|
|
989
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'User Spot still has a member with a live owner lease.');
|
|
990
|
+
conditions.push({ kind: 'version', key: member.key, expected: member.version });
|
|
991
|
+
mutations.push({ kind: 'delete', key: member.key });
|
|
992
|
+
}
|
|
993
|
+
for (const [ownerId, read] of owners)
|
|
994
|
+
conditions.push(conditionFor(ownerKey(ownerId), read));
|
|
995
|
+
const capacities = new Map([
|
|
996
|
+
[capacityRowKey.value, { read: capacity }]
|
|
997
|
+
]);
|
|
998
|
+
const releases = [
|
|
999
|
+
{ allocation: snapshot.allocation },
|
|
1000
|
+
...members.map((member) => ({ allocation: member.allocation }))
|
|
1001
|
+
];
|
|
1002
|
+
try {
|
|
1003
|
+
for (const { allocation } of releases) {
|
|
1004
|
+
const key = capacityKey(allocation.descriptor.meshName, String(allocation.descriptor.rid));
|
|
1005
|
+
let entry = capacities.get(key.value);
|
|
1006
|
+
if (entry === undefined) {
|
|
1007
|
+
entry = { read: await this.provider.read(key, signal) };
|
|
1008
|
+
capacities.set(key.value, entry);
|
|
1009
|
+
}
|
|
1010
|
+
if (entry.read.kind !== 'found')
|
|
1011
|
+
continue;
|
|
1012
|
+
const stored = entry.next ?? decodeJson(entry.read.value.bytes);
|
|
1013
|
+
entry.next = {
|
|
1014
|
+
active: allocation.state === 'active'
|
|
1015
|
+
? subtractCapacity(stored.active, allocation.capacity)
|
|
1016
|
+
: stored.active,
|
|
1017
|
+
pending: allocation.state === 'reserved'
|
|
1018
|
+
? subtractCapacity(stored.pending, allocation.capacity)
|
|
1019
|
+
: stored.pending
|
|
1020
|
+
};
|
|
964
1021
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
const observed = await this.provider.read(rowKey, signal);
|
|
970
|
-
if (observed.kind === 'missing' ||
|
|
971
|
-
observed.value.version.value !== current.value.version.value)
|
|
972
|
-
return 'conflict';
|
|
1022
|
+
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
if (!(error instanceof contracts_2.ZLinkFrameworkException) ||
|
|
1025
|
+
error.kind !== contracts_2.ZLinkFrameworkErrorKind.DataLost)
|
|
973
1026
|
throw error;
|
|
1027
|
+
for (const authority of [{ key: rowKey, version: current.value.version }, ...members]) {
|
|
1028
|
+
const observed = await this.provider.read(authority.key, signal);
|
|
1029
|
+
if (observed.kind === 'missing' || observed.value.version.value !== authority.version.value)
|
|
1030
|
+
return 'conflict';
|
|
974
1031
|
}
|
|
1032
|
+
throw error;
|
|
975
1033
|
}
|
|
976
|
-
const
|
|
977
|
-
conditions
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
}
|
|
1034
|
+
for (const [key, entry] of capacities) {
|
|
1035
|
+
conditions.push(conditionFor((0, in_memory_provider_location_store_1.storeKey)(key), entry.read));
|
|
1036
|
+
if (entry.next !== undefined)
|
|
1037
|
+
mutations.push({
|
|
1038
|
+
kind: 'put',
|
|
1039
|
+
key: (0, in_memory_provider_location_store_1.storeKey)(key),
|
|
1040
|
+
bytes: encodeJson(entry.next)
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
// Every mutated key is also a condition key, so the condition count is the batch's
|
|
1044
|
+
// unique key count. A release beyond the provider bound changes nothing.
|
|
1045
|
+
if (conditions.length > Stores_1.ZLINK_PROVIDER_MAX_WRITE_KEYS)
|
|
1046
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'User Spot member release exceeds one Location Store batch.');
|
|
1047
|
+
const result = await this.provider.write({ conditions, mutations }, signal);
|
|
985
1048
|
return result.kind === 'applied' ? 'reclaimed' : 'conflict';
|
|
986
1049
|
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Reads every Actor membership of one User Spot incarnation from complete snapshot scans
|
|
1052
|
+
* (location runtime §6.1), from Actor authorities alone. An expired snapshot
|
|
1053
|
+
* discards the earlier pages and restarts; a Store failure propagates. A member authority
|
|
1054
|
+
* that is relocating, part of an aggregate or not yet activated keeps the Spot.
|
|
1055
|
+
*/
|
|
1056
|
+
async readEndedSpotMembers(spotId, spotGeneration, signal) {
|
|
1057
|
+
membershipSnapshot: for (;;) {
|
|
1058
|
+
const members = [];
|
|
1059
|
+
let cursor;
|
|
1060
|
+
do {
|
|
1061
|
+
const page = await this.provider.scan({
|
|
1062
|
+
prefix: `${AUTHORITY_PREIMAGE_PREFIX}actor\0`,
|
|
1063
|
+
cursor,
|
|
1064
|
+
limit: Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE
|
|
1065
|
+
}, signal);
|
|
1066
|
+
if (page.kind === 'expired')
|
|
1067
|
+
continue membershipSnapshot;
|
|
1068
|
+
for (const item of page.value.items) {
|
|
1069
|
+
const record = decodeAuthorityRecord(item.value.bytes);
|
|
1070
|
+
const authority = record.snapshot;
|
|
1071
|
+
if (authority.allocation.objectKind !== 'actor')
|
|
1072
|
+
continue;
|
|
1073
|
+
const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(authority.payload));
|
|
1074
|
+
if (actor?.currentSpotKind !== contracts_1.ZLinkSpotKind.User ||
|
|
1075
|
+
actor.currentSpotId !== spotId ||
|
|
1076
|
+
actor.currentSpotGeneration !== spotGeneration)
|
|
1077
|
+
continue;
|
|
1078
|
+
if (authority.allocation.state !== 'active' ||
|
|
1079
|
+
record.aggregate !== undefined ||
|
|
1080
|
+
hasRelocationAuthority(authority.payload) ||
|
|
1081
|
+
(0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)(authority.payload)?.state !== 'ready')
|
|
1082
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'User Spot still has a relocating or unactivated member.');
|
|
1083
|
+
members.push({
|
|
1084
|
+
key: item.key,
|
|
1085
|
+
version: item.value.version,
|
|
1086
|
+
ownerId: authority.ownerId,
|
|
1087
|
+
leaseGeneration: authority.ownerLeaseGeneration,
|
|
1088
|
+
allocation: authority.allocation
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
cursor = page.value.nextCursor;
|
|
1092
|
+
} while (cursor !== undefined);
|
|
1093
|
+
return members;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
987
1096
|
async reserve(request, signal, deadlineUnixMs) {
|
|
1097
|
+
return this.observeStore('compare_exchange', () => this.reserveRequest(request, signal, deadlineUnixMs));
|
|
1098
|
+
}
|
|
1099
|
+
async reserveRequest(request, signal, deadlineUnixMs) {
|
|
988
1100
|
const encodedAuthorityKey = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
989
1101
|
const reservationId = (0, node_crypto_1.randomUUID)();
|
|
990
1102
|
let reclaimVersion;
|
|
@@ -1112,6 +1224,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1112
1224
|
}
|
|
1113
1225
|
}
|
|
1114
1226
|
async commit(request, signal, deadlineUnixMs) {
|
|
1227
|
+
return this.observeStore('compare_exchange', () => this.commitRequest(request, signal, deadlineUnixMs));
|
|
1228
|
+
}
|
|
1229
|
+
async commitRequest(request, signal, deadlineUnixMs) {
|
|
1115
1230
|
const key = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
1116
1231
|
const rowKey = authorityKey(key.value);
|
|
1117
1232
|
for (;;) {
|
|
@@ -1188,6 +1303,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1188
1303
|
}
|
|
1189
1304
|
}
|
|
1190
1305
|
async abort(request, signal, deadlineUnixMs) {
|
|
1306
|
+
return this.observeStore('compare_exchange', () => this.abortRequest(request, signal, deadlineUnixMs));
|
|
1307
|
+
}
|
|
1308
|
+
async abortRequest(request, signal, deadlineUnixMs) {
|
|
1191
1309
|
const key = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
1192
1310
|
const rowKey = authorityKey(key.value);
|
|
1193
1311
|
for (;;) {
|
|
@@ -1210,12 +1328,6 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1210
1328
|
this.provider.read(leaseKey, signal),
|
|
1211
1329
|
this.provider.read(capacityRowKey, signal)
|
|
1212
1330
|
]);
|
|
1213
|
-
if (leaseRead.kind === 'found' && leaseRead.value.expiresAt === undefined) {
|
|
1214
|
-
// A lease is always written with a positive TTL, so a missing expiry
|
|
1215
|
-
// is a corrupt record. Abort deletes authority state, so refuse
|
|
1216
|
-
// rather than read the absence as expiry.
|
|
1217
|
-
throw new Error('Location Store owner lease record is invalid.');
|
|
1218
|
-
}
|
|
1219
1331
|
if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined)
|
|
1220
1332
|
return { kind: 'stale' };
|
|
1221
1333
|
const capacity = capacityRead.kind === 'missing'
|
|
@@ -1249,6 +1361,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1249
1361
|
}
|
|
1250
1362
|
}
|
|
1251
1363
|
async completeCreation(request, signal) {
|
|
1364
|
+
return this.observeStore('compare_exchange', () => this.completeCreationRequest(request, signal));
|
|
1365
|
+
}
|
|
1366
|
+
async completeCreationRequest(request, signal) {
|
|
1252
1367
|
if (request.key.kind !== 'actor') {
|
|
1253
1368
|
throw new TypeError('completeCreation is reserved for Actor creation.');
|
|
1254
1369
|
}
|
|
@@ -1388,6 +1503,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1388
1503
|
}
|
|
1389
1504
|
}
|
|
1390
1505
|
async readCreationTerminal(operation, signal) {
|
|
1506
|
+
return this.observeStore('read', () => this.readCreationTerminalRequest(operation, signal));
|
|
1507
|
+
}
|
|
1508
|
+
async readCreationTerminalRequest(operation, signal) {
|
|
1391
1509
|
validateCreationOperation(operation);
|
|
1392
1510
|
const result = await this.provider.read(creationTerminalKey(operation), signal);
|
|
1393
1511
|
return result.kind === 'missing'
|
|
@@ -1398,6 +1516,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1398
1516
|
};
|
|
1399
1517
|
}
|
|
1400
1518
|
async claimOwnerLease(ownerId, leaseTtlMs, signal) {
|
|
1519
|
+
return this.observeStore('compare_exchange', () => this.claimOwnerLeaseRequest(ownerId, leaseTtlMs, signal));
|
|
1520
|
+
}
|
|
1521
|
+
async claimOwnerLeaseRequest(ownerId, leaseTtlMs, signal) {
|
|
1401
1522
|
requireOwnerInput(ownerId, leaseTtlMs);
|
|
1402
1523
|
for (;;) {
|
|
1403
1524
|
const [owner, counter] = await Promise.all([
|
|
@@ -1445,21 +1566,28 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1445
1566
|
}
|
|
1446
1567
|
}
|
|
1447
1568
|
async readOwnerLease(ownerId, signal) {
|
|
1569
|
+
return this.observeStore('read', () => this.readOwnerLeaseRequest(ownerId, signal));
|
|
1570
|
+
}
|
|
1571
|
+
async readOwnerLeaseRequest(ownerId, signal) {
|
|
1448
1572
|
const result = await this.provider.read(ownerKey(ownerId), signal);
|
|
1449
1573
|
if (result.kind === 'missing')
|
|
1450
1574
|
return { kind: 'missing' };
|
|
1575
|
+
const leaseExpiresAt = requireOwnerLeaseExpiry(result.value);
|
|
1451
1576
|
const record = decodeOwnerRecord(result.value.bytes);
|
|
1452
|
-
if (record.ownerId !== ownerId
|
|
1577
|
+
if (record.ownerId !== ownerId) {
|
|
1453
1578
|
throw new Error('Location Store owner lease record is invalid.');
|
|
1454
1579
|
}
|
|
1455
1580
|
return {
|
|
1456
1581
|
kind: 'found',
|
|
1457
1582
|
token: { ownerId, leaseGeneration: BigInt(record.leaseGeneration) },
|
|
1458
|
-
leaseExpiresAt
|
|
1583
|
+
leaseExpiresAt,
|
|
1459
1584
|
storeNow: result.value.storeNow
|
|
1460
1585
|
};
|
|
1461
1586
|
}
|
|
1462
1587
|
async renewOwnerLease(token, leaseTtlMs, signal) {
|
|
1588
|
+
return this.observeStore('lease_renew', () => this.renewOwnerLeaseRequest(token, leaseTtlMs, signal));
|
|
1589
|
+
}
|
|
1590
|
+
async renewOwnerLeaseRequest(token, leaseTtlMs, signal) {
|
|
1463
1591
|
requireOwnerInput(token.ownerId, leaseTtlMs);
|
|
1464
1592
|
const key = ownerKey(token.ownerId);
|
|
1465
1593
|
const current = await this.provider.read(key, signal);
|
|
@@ -1488,6 +1616,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1488
1616
|
};
|
|
1489
1617
|
}
|
|
1490
1618
|
async releaseOwnerLease(token, signal) {
|
|
1619
|
+
return this.observeStore('release', () => this.releaseOwnerLeaseRequest(token, signal));
|
|
1620
|
+
}
|
|
1621
|
+
async releaseOwnerLeaseRequest(token, signal) {
|
|
1491
1622
|
const key = ownerKey(token.ownerId);
|
|
1492
1623
|
const current = await this.provider.read(key, signal);
|
|
1493
1624
|
if (current.kind === 'missing')
|
|
@@ -1502,9 +1633,18 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1502
1633
|
return result.kind === 'applied' ? 'released' : 'stale';
|
|
1503
1634
|
}
|
|
1504
1635
|
async updateMeshNode(descriptor, intent, signal) {
|
|
1636
|
+
return this.observeStore('compare_exchange', () => this.updateMeshNodeRequest(descriptor, intent, signal));
|
|
1637
|
+
}
|
|
1638
|
+
async updateMeshNodeRequest(descriptor, intent, signal) {
|
|
1639
|
+
const capacityRowKey = capacityKey(descriptor.meshName, String(descriptor.rid));
|
|
1640
|
+
if (!this.confirmedCapacities.has(capacityRowKey.value))
|
|
1641
|
+
this.confirmedCapacities.set(capacityRowKey.value, undefined);
|
|
1505
1642
|
return this.updateDescriptor(meshKey(descriptor.meshName, descriptor.rid), descriptor, intent, reviveMeshDescriptor, sameMeshDescriptor, canRenewMesh, signal);
|
|
1506
1643
|
}
|
|
1507
1644
|
async removeMeshNode(key, owner, signal) {
|
|
1645
|
+
return this.observeStore('release', () => this.removeMeshNodeRequest(key, owner, signal));
|
|
1646
|
+
}
|
|
1647
|
+
async removeMeshNodeRequest(key, owner, signal) {
|
|
1508
1648
|
const rowKey = meshKey(key.meshName, key.rid);
|
|
1509
1649
|
const current = await this.provider.read(rowKey, signal);
|
|
1510
1650
|
if (current.kind === 'missing')
|
|
@@ -1518,9 +1658,14 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1518
1658
|
conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
|
|
1519
1659
|
mutations: [{ kind: 'delete', key: rowKey }]
|
|
1520
1660
|
}, signal);
|
|
1661
|
+
if (result.kind === 'applied')
|
|
1662
|
+
this.confirmedCapacities.delete(capacityKey(key.meshName, String(key.rid)).value);
|
|
1521
1663
|
return result.kind === 'applied' ? Locations_1.ZLinkLocationWriteStatus.Stored : Locations_1.ZLinkLocationWriteStatus.IgnoredStale;
|
|
1522
1664
|
}
|
|
1523
1665
|
async listMeshNodes(meshName, page = {}, signal) {
|
|
1666
|
+
return this.observeStore('read', () => this.listMeshNodesRequest(meshName, page, signal));
|
|
1667
|
+
}
|
|
1668
|
+
async listMeshNodesRequest(meshName, page = {}, signal) {
|
|
1524
1669
|
const result = await this.provider.scan({
|
|
1525
1670
|
prefix: meshPrefix(meshName),
|
|
1526
1671
|
cursor: page.continuationToken === undefined
|
|
@@ -1539,30 +1684,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1539
1684
|
: decodeJson(capacityRead.value.bytes);
|
|
1540
1685
|
return {
|
|
1541
1686
|
...descriptor,
|
|
1542
|
-
populationCapacity:
|
|
1543
|
-
actors: {
|
|
1544
|
-
...descriptor.populationCapacity.actors,
|
|
1545
|
-
active: capacity.active.actors,
|
|
1546
|
-
reserved: capacity.pending.actors
|
|
1547
|
-
},
|
|
1548
|
-
spots: {
|
|
1549
|
-
...descriptor.populationCapacity.spots,
|
|
1550
|
-
active: capacity.active.spots,
|
|
1551
|
-
reserved: capacity.pending.spots
|
|
1552
|
-
},
|
|
1553
|
-
spotTypes: descriptor.populationCapacity.spotTypes.map((value) => {
|
|
1554
|
-
const key = capacityTypeKey({
|
|
1555
|
-
objectKind: value.objectKind,
|
|
1556
|
-
stableType: value.stableType,
|
|
1557
|
-
count: 0
|
|
1558
|
-
});
|
|
1559
|
-
return {
|
|
1560
|
-
...value,
|
|
1561
|
-
active: capacity.active.spotTypes[key] ?? 0,
|
|
1562
|
-
reserved: capacity.pending.spotTypes[key] ?? 0
|
|
1563
|
-
};
|
|
1564
|
-
})
|
|
1565
|
-
}
|
|
1687
|
+
populationCapacity: projectCapacity(descriptor.populationCapacity, capacity)
|
|
1566
1688
|
};
|
|
1567
1689
|
}));
|
|
1568
1690
|
return {
|
|
@@ -1571,54 +1693,99 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1571
1693
|
};
|
|
1572
1694
|
}
|
|
1573
1695
|
async updateClientServer(descriptor, intent, signal) {
|
|
1696
|
+
return this.observeStore('compare_exchange', () => this.updateClientServerRequest(descriptor, intent, signal));
|
|
1697
|
+
}
|
|
1698
|
+
async updateClientServerRequest(descriptor, intent, signal) {
|
|
1574
1699
|
validateClientServerDescriptor(descriptor);
|
|
1575
1700
|
const normalized = reviveClientServerDescriptor(descriptor);
|
|
1576
1701
|
return this.updateDescriptor(clientServerKey(normalized.channelName, normalized.serverRid), normalized, intent, reviveClientServerDescriptor, sameClientServerDescriptor, canRenewClientServer, signal);
|
|
1577
1702
|
}
|
|
1578
1703
|
async removeClientServer(key, owner, signal) {
|
|
1704
|
+
return this.observeStore('release', () => this.removeClientServerRequest(key, owner, signal));
|
|
1705
|
+
}
|
|
1706
|
+
async removeClientServerRequest(key, owner, signal) {
|
|
1579
1707
|
return this.removeDescriptor(clientServerKey(key.channelName, key.serverRid), owner, reviveClientServerDescriptor, signal);
|
|
1580
1708
|
}
|
|
1581
1709
|
async listClientServers(channelName, page = {}, signal) {
|
|
1710
|
+
return this.observeStore('read', () => this.listClientServersRequest(channelName, page, signal));
|
|
1711
|
+
}
|
|
1712
|
+
async listClientServersRequest(channelName, page = {}, signal) {
|
|
1582
1713
|
return this.listDescriptors(clientServerPrefix(channelName), page, reviveClientServerDescriptor, signal);
|
|
1583
1714
|
}
|
|
1584
1715
|
async updateFanoutPublisher(descriptor, intent, signal) {
|
|
1716
|
+
return this.observeStore('compare_exchange', () => this.updateFanoutPublisherRequest(descriptor, intent, signal));
|
|
1717
|
+
}
|
|
1718
|
+
async updateFanoutPublisherRequest(descriptor, intent, signal) {
|
|
1585
1719
|
validateFanoutPublisherDescriptor(descriptor);
|
|
1586
1720
|
const normalized = reviveFanoutDescriptor(descriptor);
|
|
1587
1721
|
return this.updateDescriptor(fanoutKey(normalized.channelName, normalized.publisherRid), normalized, intent, reviveFanoutDescriptor, sameFanoutDescriptor, canRenewFanout, signal);
|
|
1588
1722
|
}
|
|
1589
1723
|
async removeFanoutPublisher(key, owner, signal) {
|
|
1724
|
+
return this.observeStore('release', () => this.removeFanoutPublisherRequest(key, owner, signal));
|
|
1725
|
+
}
|
|
1726
|
+
async removeFanoutPublisherRequest(key, owner, signal) {
|
|
1590
1727
|
return this.removeDescriptor(fanoutKey(key.channelName, key.publisherRid), owner, reviveFanoutDescriptor, signal);
|
|
1591
1728
|
}
|
|
1592
1729
|
async listFanoutPublishers(channelName, page = {}, signal) {
|
|
1730
|
+
return this.observeStore('read', () => this.listFanoutPublishersRequest(channelName, page, signal));
|
|
1731
|
+
}
|
|
1732
|
+
async listFanoutPublishersRequest(channelName, page = {}, signal) {
|
|
1593
1733
|
return this.listDescriptors(fanoutPrefix(channelName), page, reviveFanoutDescriptor, signal);
|
|
1594
1734
|
}
|
|
1595
1735
|
async updateSpot(location, intent, signal) {
|
|
1736
|
+
return this.observeStore('compare_exchange', () => this.updateSpotRequest(location, intent, signal));
|
|
1737
|
+
}
|
|
1738
|
+
async updateSpotRequest(location, intent, signal) {
|
|
1596
1739
|
return this.updateOwnedLocation(spotKey(location.meshName, String(location.spotId)), normalizeSpot(location), intent, signal);
|
|
1597
1740
|
}
|
|
1598
1741
|
async removeSpot(key, owner, signal) {
|
|
1742
|
+
return this.observeStore('release', () => this.removeSpotRequest(key, owner, signal));
|
|
1743
|
+
}
|
|
1744
|
+
async removeSpotRequest(key, owner, signal) {
|
|
1599
1745
|
return this.removeOwnedLocation(spotKey(key.meshName, String(key.spotId)), owner, signal);
|
|
1600
1746
|
}
|
|
1601
1747
|
async resolveSpot(key, signal) {
|
|
1748
|
+
return this.observeStore('read', () => this.resolveSpotRequest(key, signal));
|
|
1749
|
+
}
|
|
1750
|
+
async resolveSpotRequest(key, signal) {
|
|
1602
1751
|
const value = await this.readOwnedLocation(spotKey(key.meshName, String(key.spotId)), signal);
|
|
1603
1752
|
return value === undefined ? undefined : normalizeSpot(value);
|
|
1604
1753
|
}
|
|
1605
1754
|
async listSpots(filter, page = {}, signal) {
|
|
1755
|
+
return this.observeStore('read', () => this.listSpotsRequest(filter, page, signal));
|
|
1756
|
+
}
|
|
1757
|
+
async listSpotsRequest(filter, page = {}, signal) {
|
|
1606
1758
|
return this.listOwnedLocations(`${PREFIX}spot:`, page, normalizeSpot, (value) => matchesSpot(value, filter), signal);
|
|
1607
1759
|
}
|
|
1608
1760
|
async updateActor(location, intent, signal) {
|
|
1761
|
+
return this.observeStore('compare_exchange', () => this.updateActorRequest(location, intent, signal));
|
|
1762
|
+
}
|
|
1763
|
+
async updateActorRequest(location, intent, signal) {
|
|
1609
1764
|
return this.updateOwnedLocation(actorKey(location.meshName, location.actorId), normalizeActor(location), intent, signal, location);
|
|
1610
1765
|
}
|
|
1611
1766
|
async removeActor(key, owner, signal) {
|
|
1767
|
+
return this.observeStore('release', () => this.removeActorRequest(key, owner, signal));
|
|
1768
|
+
}
|
|
1769
|
+
async removeActorRequest(key, owner, signal) {
|
|
1612
1770
|
return this.removeOwnedLocation(actorKey(key.meshName, key.actorId), owner, signal);
|
|
1613
1771
|
}
|
|
1614
1772
|
async resolveActor(key, signal) {
|
|
1773
|
+
return this.observeStore('read', () => this.resolveActorRequest(key, signal));
|
|
1774
|
+
}
|
|
1775
|
+
async resolveActorRequest(key, signal) {
|
|
1615
1776
|
const value = await this.readOwnedLocation(actorKey(key.meshName, key.actorId), signal);
|
|
1616
1777
|
return value === undefined ? undefined : normalizeActor(value);
|
|
1617
1778
|
}
|
|
1618
1779
|
async listActors(filter, page = {}, signal) {
|
|
1780
|
+
return this.observeStore('read', () => this.listActorsRequest(filter, page, signal));
|
|
1781
|
+
}
|
|
1782
|
+
async listActorsRequest(filter, page = {}, signal) {
|
|
1619
1783
|
return this.listOwnedLocations(`${PREFIX}actor:`, page, normalizeActor, (value) => matchesActor(value, filter), signal);
|
|
1620
1784
|
}
|
|
1621
1785
|
async updateRoute(location, intent, signal) {
|
|
1786
|
+
return this.observeStore('compare_exchange', () => this.updateRouteRequest(location, intent, signal));
|
|
1787
|
+
}
|
|
1788
|
+
async updateRouteRequest(location, intent, signal) {
|
|
1622
1789
|
const rowKey = routeKey(String(location.routeKind), location.routeKey);
|
|
1623
1790
|
const normalized = normalizeRoute(location);
|
|
1624
1791
|
const current = await this.provider.read(rowKey, signal);
|
|
@@ -1673,6 +1840,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1673
1840
|
: rejected(result.storeNow);
|
|
1674
1841
|
}
|
|
1675
1842
|
async removeRoute(key, owner, signal) {
|
|
1843
|
+
return this.observeStore('release', () => this.removeRouteRequest(key, owner, signal));
|
|
1844
|
+
}
|
|
1845
|
+
async removeRouteRequest(key, owner, signal) {
|
|
1676
1846
|
const rowKey = routeKey(String(key.routeKind), key.routeKey);
|
|
1677
1847
|
const current = await this.provider.read(rowKey, signal);
|
|
1678
1848
|
if (current.kind === 'missing')
|
|
@@ -1699,13 +1869,22 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1699
1869
|
: rejected(result.storeNow);
|
|
1700
1870
|
}
|
|
1701
1871
|
async resolveRoute(key, signal) {
|
|
1872
|
+
return this.observeStore('read', () => this.resolveRouteRequest(key, signal));
|
|
1873
|
+
}
|
|
1874
|
+
async resolveRouteRequest(key, signal) {
|
|
1702
1875
|
const value = await this.readOwnedLocation(routeKey(String(key.routeKind), key.routeKey), signal);
|
|
1703
1876
|
return value === undefined ? undefined : normalizeRoute(value);
|
|
1704
1877
|
}
|
|
1705
1878
|
async listRoutes(filter, page = {}, signal) {
|
|
1879
|
+
return this.observeStore('read', () => this.listRoutesRequest(filter, page, signal));
|
|
1880
|
+
}
|
|
1881
|
+
async listRoutesRequest(filter, page = {}, signal) {
|
|
1706
1882
|
return this.listOwnedLocations(`${PREFIX}route:`, page, normalizeRoute, (value) => matchesRoute(value, filter), signal);
|
|
1707
1883
|
}
|
|
1708
1884
|
async removeAllByOwner(owner, signal) {
|
|
1885
|
+
return this.observeStore('release', () => this.removeAllByOwnerRequest(owner, signal));
|
|
1886
|
+
}
|
|
1887
|
+
async removeAllByOwnerRequest(owner, signal) {
|
|
1709
1888
|
const leaseKey = ownerKey(owner.ownerId);
|
|
1710
1889
|
const lease = await this.provider.read(leaseKey, signal);
|
|
1711
1890
|
if (liveOwnerLeaseGeneration(lease) !== owner.leaseGeneration)
|
|
@@ -1792,7 +1971,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1792
1971
|
const encodedAuthority = authorityContractValueFromPreimage(candidate.key.value);
|
|
1793
1972
|
const identity = (0, authority_key_codec_1.decodeAuthorityKey)({ value: encodedAuthority });
|
|
1794
1973
|
if (record.snapshot.allocation.state === 'active') {
|
|
1795
|
-
const result = await this.
|
|
1974
|
+
const result = await this.compareExchangeAuthorityRequest({ value: encodedAuthority }, current.value.version, { kind: 'delete' }, signal);
|
|
1796
1975
|
if (result.kind === 'deleted')
|
|
1797
1976
|
removed += 1n;
|
|
1798
1977
|
continue;
|
|
@@ -1800,7 +1979,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1800
1979
|
const reservationId = record.snapshot.pendingCreation?.reservationId;
|
|
1801
1980
|
if (reservationId === undefined)
|
|
1802
1981
|
continue;
|
|
1803
|
-
const aborted = await this.
|
|
1982
|
+
const aborted = await this.abortRequest({
|
|
1804
1983
|
key: identity,
|
|
1805
1984
|
reservationId,
|
|
1806
1985
|
expectedStoreVersion: current.value.version.value,
|
|
@@ -1922,10 +2101,23 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1922
2101
|
const rowCondition = currentRow.kind === 'found'
|
|
1923
2102
|
? { kind: 'version', key: rowKey, expected: currentRow.value.version }
|
|
1924
2103
|
: { kind: 'missing', key: rowKey };
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
2104
|
+
let result;
|
|
2105
|
+
try {
|
|
2106
|
+
result = await this.provider.write({
|
|
2107
|
+
conditions: [leaseValueCondition(leaseKey, { ownerId, leaseGeneration }), rowCondition],
|
|
2108
|
+
mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
|
|
2109
|
+
}, signal);
|
|
2110
|
+
}
|
|
2111
|
+
catch (failure) {
|
|
2112
|
+
// Location runtime §10: the Store may have applied a write whose result
|
|
2113
|
+
// was lost. Re-read the same key; the same bytes confirm the write.
|
|
2114
|
+
const confirmed = await this.provider.read(rowKey, signal).catch(() => undefined);
|
|
2115
|
+
if (confirmed?.kind === 'found' &&
|
|
2116
|
+
Buffer.from(confirmed.value.bytes).equals(Buffer.from(encodedDescriptor))) {
|
|
2117
|
+
return { status: Locations_1.ZLinkLocationWriteStatus.Stored, generation, updatedAt: confirmed.value.storeNow };
|
|
2118
|
+
}
|
|
2119
|
+
throw failure;
|
|
2120
|
+
}
|
|
1929
2121
|
if (result.kind === 'applied') {
|
|
1930
2122
|
return { status: Locations_1.ZLinkLocationWriteStatus.Stored, generation, updatedAt: result.storeNow };
|
|
1931
2123
|
}
|
|
@@ -2671,6 +2863,11 @@ function reviveCanonical(value, key = '') {
|
|
|
2671
2863
|
}
|
|
2672
2864
|
return value;
|
|
2673
2865
|
}
|
|
2866
|
+
function requireOwnerLeaseExpiry(value) {
|
|
2867
|
+
if (value.expiresAt === undefined)
|
|
2868
|
+
throw new Error('Location Store owner lease record is invalid.');
|
|
2869
|
+
return value.expiresAt;
|
|
2870
|
+
}
|
|
2674
2871
|
function decodeOwnerRecord(bytes) {
|
|
2675
2872
|
const record = decodeJson(bytes);
|
|
2676
2873
|
requireRecordVersion(record, 'owner lease');
|
|
@@ -2710,7 +2907,7 @@ function canonicalDescriptor(descriptor) {
|
|
|
2710
2907
|
if ('serverRid' in descriptor)
|
|
2711
2908
|
return {
|
|
2712
2909
|
channelName: descriptor.channelName,
|
|
2713
|
-
serverRoutingIdHex: (0,
|
|
2910
|
+
serverRoutingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(descriptor.serverRid),
|
|
2714
2911
|
lifecycleGeneration: descriptor.lifecycleGeneration.toString(),
|
|
2715
2912
|
descriptorRevision: descriptor.descriptorRevision.toString(),
|
|
2716
2913
|
endpoint: descriptor.endpoint,
|
|
@@ -2724,7 +2921,7 @@ function canonicalDescriptor(descriptor) {
|
|
|
2724
2921
|
const publisher = descriptor;
|
|
2725
2922
|
return {
|
|
2726
2923
|
channelName: publisher.channelName,
|
|
2727
|
-
publisherRoutingIdHex: (0,
|
|
2924
|
+
publisherRoutingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(publisher.publisherRid),
|
|
2728
2925
|
lifecycleGeneration: publisher.lifecycleGeneration.toString(),
|
|
2729
2926
|
descriptorRevision: publisher.descriptorRevision.toString(),
|
|
2730
2927
|
endpoint: publisher.endpoint,
|
|
@@ -2738,7 +2935,7 @@ function canonicalDescriptor(descriptor) {
|
|
|
2738
2935
|
function canonicalMeshDescriptor(descriptor) {
|
|
2739
2936
|
return {
|
|
2740
2937
|
meshName: descriptor.meshName,
|
|
2741
|
-
routingIdHex: (0,
|
|
2938
|
+
routingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(descriptor.rid),
|
|
2742
2939
|
lifecycleGeneration: descriptor.lifecycleGeneration.toString(),
|
|
2743
2940
|
descriptorRevision: descriptor.descriptorRevision.toString(),
|
|
2744
2941
|
endpoint: descriptor.endpoint,
|
|
@@ -2839,7 +3036,7 @@ function encodeAuthorityRecord(record) {
|
|
|
2839
3036
|
stableType: allocation.stableType,
|
|
2840
3037
|
descriptor: {
|
|
2841
3038
|
meshName: allocation.descriptor.meshName,
|
|
2842
|
-
routingIdHex: (0,
|
|
3039
|
+
routingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(allocation.descriptor.rid)
|
|
2843
3040
|
},
|
|
2844
3041
|
descriptorLifecycleGeneration: allocation.descriptorLifecycleGeneration.toString(),
|
|
2845
3042
|
capacity: canonicalAuthorityCapacity(allocation.capacity)
|
|
@@ -2890,7 +3087,7 @@ function decodeAuthorityRecord(bytes) {
|
|
|
2890
3087
|
stableType: String(allocation.stableType),
|
|
2891
3088
|
descriptor: {
|
|
2892
3089
|
meshName: String(descriptor.meshName),
|
|
2893
|
-
rid: (0,
|
|
3090
|
+
rid: (0, routing_id_2.decodeRoutingId)(String(descriptor.routingIdHex), descriptor.routingIdHex)
|
|
2894
3091
|
},
|
|
2895
3092
|
descriptorLifecycleGeneration: BigInt(String(allocation.descriptorLifecycleGeneration)),
|
|
2896
3093
|
capacity: {
|
|
@@ -3047,20 +3244,22 @@ function authoritySnapshot(snapshot, storeVersion, storeNow) {
|
|
|
3047
3244
|
};
|
|
3048
3245
|
}
|
|
3049
3246
|
function liveTargetDescriptor(descriptorRead, leaseRead, target) {
|
|
3050
|
-
if (
|
|
3247
|
+
if (leaseRead.kind === 'missing')
|
|
3248
|
+
return undefined;
|
|
3249
|
+
const leaseExpiresAt = requireOwnerLeaseExpiry(leaseRead.value);
|
|
3250
|
+
if (descriptorRead.kind === 'missing')
|
|
3051
3251
|
return undefined;
|
|
3052
3252
|
const descriptor = reviveMeshDescriptor(decodeCanonicalDescriptorRecord(descriptorRead.value.bytes).descriptor);
|
|
3053
3253
|
const lease = decodeOwnerRecord(leaseRead.value.bytes);
|
|
3054
3254
|
return descriptor.meshName === target.meshName &&
|
|
3055
|
-
|
|
3255
|
+
(0, routing_id_1.routingIdsEqual)(descriptor.rid, (0, routing_id_1.toBackendRoutingId)(target.nodeRid)) &&
|
|
3056
3256
|
descriptor.lifecycleGeneration === target.nodeLifecycleGeneration &&
|
|
3057
3257
|
descriptor.ownerId === target.owner.ownerId &&
|
|
3058
3258
|
descriptor.leaseGeneration === target.owner.leaseGeneration &&
|
|
3059
3259
|
descriptor.objectRole === contracts_2.ZLinkObjectRole.Server &&
|
|
3060
3260
|
lease.ownerId === target.owner.ownerId &&
|
|
3061
3261
|
BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
|
|
3062
|
-
leaseRead.value.
|
|
3063
|
-
leaseRead.value.expiresAt.getTime() > leaseRead.value.storeNow.getTime()
|
|
3262
|
+
leaseExpiresAt.getTime() > leaseRead.value.storeNow.getTime()
|
|
3064
3263
|
? descriptor
|
|
3065
3264
|
: undefined;
|
|
3066
3265
|
}
|
|
@@ -3148,7 +3347,7 @@ function sameCapacityVector(left, right) {
|
|
|
3148
3347
|
}
|
|
3149
3348
|
function sameCreationTarget(snapshot, target) {
|
|
3150
3349
|
return (snapshot.allocation.descriptor.meshName === target.meshName &&
|
|
3151
|
-
|
|
3350
|
+
(0, routing_id_1.routingIdsEqual)(snapshot.allocation.descriptor.rid, target.nodeRid) &&
|
|
3152
3351
|
snapshot.allocation.descriptorLifecycleGeneration === target.nodeLifecycleGeneration &&
|
|
3153
3352
|
snapshot.ownerId === target.owner.ownerId &&
|
|
3154
3353
|
snapshot.ownerLeaseGeneration === target.owner.leaseGeneration);
|
|
@@ -3163,8 +3362,7 @@ function sameLiveOwner(lease, snapshot) {
|
|
|
3163
3362
|
return matchesLiveOwnerLease(lease, snapshot.ownerId, snapshot.ownerLeaseGeneration);
|
|
3164
3363
|
}
|
|
3165
3364
|
function matchesLiveOwnerLease(lease, ownerId, leaseGeneration) {
|
|
3166
|
-
if (lease.value.
|
|
3167
|
-
lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()) {
|
|
3365
|
+
if (requireOwnerLeaseExpiry(lease.value).getTime() <= lease.value.storeNow.getTime()) {
|
|
3168
3366
|
return false;
|
|
3169
3367
|
}
|
|
3170
3368
|
const owner = decodeOwnerRecord(lease.value.bytes);
|
|
@@ -3177,9 +3375,9 @@ function sameDescriptorPredecessor(expected, current) {
|
|
|
3177
3375
|
return Buffer.from(expected.value.bytes).equals(Buffer.from(current.value.bytes));
|
|
3178
3376
|
}
|
|
3179
3377
|
function liveOwnerLeaseGeneration(lease) {
|
|
3180
|
-
if (lease.kind === 'missing'
|
|
3181
|
-
|
|
3182
|
-
|
|
3378
|
+
if (lease.kind === 'missing')
|
|
3379
|
+
return undefined;
|
|
3380
|
+
if (requireOwnerLeaseExpiry(lease.value).getTime() <= lease.value.storeNow.getTime()) {
|
|
3183
3381
|
return undefined;
|
|
3184
3382
|
}
|
|
3185
3383
|
return BigInt(decodeOwnerRecord(lease.value.bytes).leaseGeneration);
|
|
@@ -3199,16 +3397,13 @@ function canTakeOverStoredLocation(intent, currentOwnerId, currentLeaseGeneratio
|
|
|
3199
3397
|
currentLeaseGeneration !== nextLeaseGeneration &&
|
|
3200
3398
|
liveLeaseGeneration === nextLeaseGeneration);
|
|
3201
3399
|
}
|
|
3202
|
-
function persistMeshDescriptor(descriptor) {
|
|
3203
|
-
return descriptor;
|
|
3204
|
-
}
|
|
3205
3400
|
function reviveMeshDescriptor(descriptor) {
|
|
3206
3401
|
const value = descriptor;
|
|
3207
3402
|
if ('routingIdHex' in value) {
|
|
3208
3403
|
const capacity = value.capacity;
|
|
3209
3404
|
return {
|
|
3210
3405
|
meshName: String(value.meshName),
|
|
3211
|
-
rid: (0,
|
|
3406
|
+
rid: (0, routing_id_2.decodeRoutingId)(String(value.routingIdHex), value.routingIdHex),
|
|
3212
3407
|
lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
|
|
3213
3408
|
descriptorRevision: BigInt(String(value.descriptorRevision)),
|
|
3214
3409
|
endpoint: String(value.endpoint),
|
|
@@ -3240,7 +3435,7 @@ function reviveClientServerDescriptor(descriptor) {
|
|
|
3240
3435
|
if ('serverRoutingIdHex' in value) {
|
|
3241
3436
|
return {
|
|
3242
3437
|
channelName: String(value.channelName),
|
|
3243
|
-
serverRid: (0,
|
|
3438
|
+
serverRid: (0, routing_id_2.decodeRoutingId)(String(value.serverRoutingIdHex), value.serverRoutingIdHex),
|
|
3244
3439
|
lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
|
|
3245
3440
|
descriptorRevision: BigInt(String(value.descriptorRevision)),
|
|
3246
3441
|
endpoint: String(value.endpoint),
|
|
@@ -3263,7 +3458,7 @@ function reviveFanoutDescriptor(descriptor) {
|
|
|
3263
3458
|
if ('publisherRoutingIdHex' in value) {
|
|
3264
3459
|
return {
|
|
3265
3460
|
channelName: String(value.channelName),
|
|
3266
|
-
publisherRid: (0,
|
|
3461
|
+
publisherRid: (0, routing_id_2.decodeRoutingId)(String(value.publisherRoutingIdHex), value.publisherRoutingIdHex),
|
|
3267
3462
|
lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
|
|
3268
3463
|
descriptorRevision: BigInt(String(value.descriptorRevision)),
|
|
3269
3464
|
endpoint: String(value.endpoint),
|
|
@@ -3314,19 +3509,19 @@ function normalizeRoute(value) {
|
|
|
3314
3509
|
function matchesSpot(value, filter) {
|
|
3315
3510
|
return ((filter.meshName === undefined || value.meshName === filter.meshName) &&
|
|
3316
3511
|
(filter.spotType === undefined || value.spotType === filter.spotType) &&
|
|
3317
|
-
(filter.nodeRid === undefined ||
|
|
3512
|
+
(filter.nodeRid === undefined || (0, routing_id_1.routingIdsEqual)(value.ownerNodeRid, filter.nodeRid)) &&
|
|
3318
3513
|
(filter.spotKind === undefined || value.spotKind === filter.spotKind));
|
|
3319
3514
|
}
|
|
3320
3515
|
function matchesActor(value, filter) {
|
|
3321
3516
|
return ((filter.actorType === undefined || value.actorType === filter.actorType) &&
|
|
3322
|
-
(filter.nodeRid === undefined ||
|
|
3517
|
+
(filter.nodeRid === undefined || (0, routing_id_1.routingIdsEqual)(value.ownerNodeRid, filter.nodeRid)) &&
|
|
3323
3518
|
(filter.spotId === undefined || String(value.spotId) === String(filter.spotId)) &&
|
|
3324
3519
|
(filter.locationKind === undefined || value.spotKind === filter.locationKind));
|
|
3325
3520
|
}
|
|
3326
3521
|
function matchesRoute(value, filter) {
|
|
3327
3522
|
return ((filter.routeKind === undefined || value.routeKind === filter.routeKind) &&
|
|
3328
3523
|
(filter.ownerNodeRid === undefined ||
|
|
3329
|
-
|
|
3524
|
+
(0, routing_id_1.routingIdsEqual)(value.ownerNodeRid, filter.ownerNodeRid)) &&
|
|
3330
3525
|
(filter.ownerId === undefined || value.ownerId === filter.ownerId));
|
|
3331
3526
|
}
|
|
3332
3527
|
function locationOwnerGeneration(value) {
|
|
@@ -3343,8 +3538,11 @@ function descriptorOwnerLeaseGeneration(value) {
|
|
|
3343
3538
|
}
|
|
3344
3539
|
return undefined;
|
|
3345
3540
|
}
|
|
3541
|
+
// Location runtime §10: a write whose result was lost is confirmed by reading
|
|
3542
|
+
// the same key. The stored row already is this write when it differs only in
|
|
3543
|
+
// the time the Store stamped, as for every other descriptor kind.
|
|
3346
3544
|
function sameMeshDescriptor(left, right) {
|
|
3347
|
-
return
|
|
3545
|
+
return descriptorFingerprint(left, ['updatedAt']) === descriptorFingerprint(right, ['updatedAt']);
|
|
3348
3546
|
}
|
|
3349
3547
|
function sameClientServerDescriptor(left, right) {
|
|
3350
3548
|
return descriptorFingerprint(left, ['updatedAt']) === descriptorFingerprint(right, ['updatedAt']);
|
|
@@ -3446,7 +3644,7 @@ function requireOwnerInput(ownerId, leaseTtlMs) {
|
|
|
3446
3644
|
function throwIfOperationExpired(signal, deadlineUnixMs) {
|
|
3447
3645
|
signal?.throwIfAborted();
|
|
3448
3646
|
if (deadlineUnixMs !== undefined && Date.now() >= Number(deadlineUnixMs)) {
|
|
3449
|
-
throw new
|
|
3647
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.DeadlineExceeded, 'Operation deadline exceeded.');
|
|
3450
3648
|
}
|
|
3451
3649
|
}
|
|
3452
3650
|
// Store SPI §6: preserve caller failures and classify provider failures once.
|
|
@@ -3458,3 +3656,29 @@ function locationStoreProviderFailure(error, signal) {
|
|
|
3458
3656
|
return error;
|
|
3459
3657
|
return new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'Location Store provider is unavailable.', error);
|
|
3460
3658
|
}
|
|
3659
|
+
function projectCapacity(limits, capacity) {
|
|
3660
|
+
return {
|
|
3661
|
+
actors: {
|
|
3662
|
+
...limits.actors,
|
|
3663
|
+
active: capacity.active.actors,
|
|
3664
|
+
reserved: capacity.pending.actors
|
|
3665
|
+
},
|
|
3666
|
+
spots: {
|
|
3667
|
+
...limits.spots,
|
|
3668
|
+
active: capacity.active.spots,
|
|
3669
|
+
reserved: capacity.pending.spots
|
|
3670
|
+
},
|
|
3671
|
+
spotTypes: limits.spotTypes.map((value) => {
|
|
3672
|
+
const key = capacityTypeKey({
|
|
3673
|
+
objectKind: value.objectKind,
|
|
3674
|
+
stableType: value.stableType,
|
|
3675
|
+
count: 0
|
|
3676
|
+
});
|
|
3677
|
+
return {
|
|
3678
|
+
...value,
|
|
3679
|
+
active: capacity.active.spotTypes[key] ?? 0,
|
|
3680
|
+
reserved: capacity.pending.spotTypes[key] ?? 0
|
|
3681
|
+
};
|
|
3682
|
+
})
|
|
3683
|
+
};
|
|
3684
|
+
}
|