@zlink-systems/framework 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActorClient.d.ts +1 -1
- package/dist/contracts/Channels/Calls.d.ts +1 -1
- package/dist/contracts/Common/CoreTypes.d.ts +6 -0
- package/dist/contracts/Common/CoreTypes.js +7 -0
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/index.js +0 -1
- package/dist/contracts/Configuration/Builders.d.ts +0 -1
- package/dist/contracts/Configuration/Configs.d.ts +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
- package/dist/contracts/Configuration/InternalDefaults.js +9 -1
- package/dist/contracts/Configuration/Registration.d.ts +13 -2
- package/dist/contracts/Configuration/Registration.js +58 -36
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
- package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
- package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -5
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -14
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
- package/dist/contracts/Handlers/JsonContract.js +10 -4
- package/dist/contracts/Locations/Authority.d.ts +1 -1
- package/dist/contracts/Locations/Authority.js +3 -2
- package/dist/contracts/Locations/Options.js +1 -1
- package/dist/contracts/Locations/Stores.d.ts +12 -0
- package/dist/contracts/Locations/Stores.js +9 -0
- package/dist/contracts/Spots/Contracts.d.ts +2 -2
- package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
- package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +15 -1
- package/dist/nest-integration.d.ts +4 -2
- package/dist/nest-integration.js +14 -4
- package/dist/runtime/abort.d.ts +1 -0
- package/dist/runtime/abort.js +8 -5
- package/dist/runtime/activation-admission.d.ts +1 -2
- package/dist/runtime/activation-admission.js +2 -6
- package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
- package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
- package/dist/runtime/actors/actor-client.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +49 -153
- package/dist/runtime/actors/actor-context.d.ts +3 -5
- package/dist/runtime/actors/actor-context.js +13 -11
- package/dist/runtime/actors/actor-handoff.d.ts +4 -4
- package/dist/runtime/actors/actor-handoff.js +8 -8
- package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
- package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
- package/dist/runtime/actors/actor-local-native-join.js +83 -105
- package/dist/runtime/actors/actor-native-lookup.js +2 -8
- package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
- package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
- package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
- package/dist/runtime/actors/actor-remote-joiner.js +5 -9
- package/dist/runtime/actors/actor-remote-wire.js +5 -3
- package/dist/runtime/actors/actor-request-deadline.d.ts +1 -0
- package/dist/runtime/actors/actor-request-deadline.js +6 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
- package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
- package/dist/runtime/actors/deferred-join-completion.js +1 -0
- package/dist/runtime/actors/index.d.ts +9 -7
- package/dist/runtime/actors/index.js +87 -69
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
- package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
- package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
- package/dist/runtime/admission.d.ts +2 -0
- package/dist/runtime/admission.js +7 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
- package/dist/runtime/backend/contracts/index.d.ts +7 -27
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.js +51 -10
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.js +41 -34
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
- package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/runtime-values.d.ts +4 -1
- package/dist/runtime/backend/runtime-values.js +2 -0
- package/dist/runtime/channels/channel-clients.d.ts +20 -8
- package/dist/runtime/channels/channel-clients.js +73 -59
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.d.ts +1 -1
- package/dist/runtime/channels/channel-envelope.js +51 -39
- package/dist/runtime/channels/channel-outbound-operations.d.ts +5 -2
- package/dist/runtime/channels/channel-outbound-operations.js +25 -42
- package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
- package/dist/runtime/channels/channel-receive-loops.js +27 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
- package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
- package/dist/runtime/channels/channel-runtime-manager.js +13 -10
- package/dist/runtime/channels/channel-socket-options.js +3 -12
- package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
- package/dist/runtime/channels/channel-socket-registry.js +240 -177
- package/dist/runtime/channels/channel-transports.d.ts +21 -31
- package/dist/runtime/channels/channel-transports.js +80 -62
- package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/client-server-location-runtime.js +10 -11
- package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
- package/dist/runtime/channels/client-server-service-wire.js +32 -11
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
- package/dist/runtime/channels/fanout-location-runtime.js +130 -72
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +1 -3
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
- package/dist/runtime/channels/source-spot-router.d.ts +1 -1
- package/dist/runtime/channels/source-spot-router.js +2 -4
- package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
- package/dist/runtime/channels/spot-direct-envelope.js +4 -3
- package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
- package/dist/runtime/channels/spot-node-route-transport.js +5 -5
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
- package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
- package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
- package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
- package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
- package/dist/runtime/diagnostics/flow-context.js +16 -2
- package/dist/runtime/diagnostics/index.d.ts +4 -2
- package/dist/runtime/diagnostics/index.js +14 -4
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
- package/dist/runtime/diagnostics/message-flow.js +10 -19
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
- package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
- package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
- package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
- package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
- package/dist/runtime/disposal.d.ts +5 -0
- package/dist/runtime/disposal.js +22 -0
- package/dist/runtime/execution/index.d.ts +12 -9
- package/dist/runtime/execution/index.js +58 -14
- package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
- package/dist/runtime/execution/serial-execution-queue.js +54 -15
- package/dist/runtime/execution/state-lane.d.ts +8 -1
- package/dist/runtime/execution/state-lane.js +118 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
- package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
- package/dist/runtime/foundation/event-loop-resources.js +6 -119
- package/dist/runtime/foundation/operation-identity.d.ts +2 -0
- package/dist/runtime/foundation/operation-identity.js +9 -5
- package/dist/runtime/foundation/operation-registry.d.ts +5 -7
- package/dist/runtime/foundation/operation-registry.js +34 -44
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +79 -94
- package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
- package/dist/runtime/foundation/runtime-state-projections.js +8 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +22 -3
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
- package/dist/runtime/foundation/service-liveness-registry.js +2 -1
- package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
- package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
- package/dist/runtime/foundation/service-metadata-codec.js +3 -3
- package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
- package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
- package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
- package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +10 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
- package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
- package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
- package/dist/runtime/foundation/service-topology-registry.js +17 -32
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
- package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
- package/dist/runtime/foundation/service-wire-codec.js +10 -8
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
- package/dist/runtime/framework-errors-internal.d.ts +2 -1
- package/dist/runtime/framework-errors-internal.js +343 -122
- package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
- package/dist/runtime/handlers/handler-instance-scope.js +61 -74
- package/dist/runtime/host/actor-packet-relay.d.ts +11 -8
- package/dist/runtime/host/actor-packet-relay.js +54 -99
- package/dist/runtime/host/actor-placement-coordinator.js +7 -5
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
- package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
- package/dist/runtime/host/actor-transfer-runtime.js +143 -176
- package/dist/runtime/host/application-job-queue.js +16 -33
- package/dist/runtime/host/bound-session-relay.js +1 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
- package/dist/runtime/host/index.d.ts +14 -13
- package/dist/runtime/host/index.js +190 -171
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
- package/dist/runtime/host/instance-activation-authority.js +17 -45
- package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
- package/dist/runtime/host/location-runtime-owner.js +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
- package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
- package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
- package/dist/runtime/host/remote-bound-session-relay.js +15 -28
- package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
- package/dist/runtime/host/route-mesh-runtime.js +171 -252
- package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
- package/dist/runtime/host/runtime-shutdown.js +18 -21
- package/dist/runtime/host/service-relocation-control.js +6 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
- package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
- package/dist/runtime/host/spot-address-transport.d.ts +3 -12
- package/dist/runtime/host/spot-address-transport.js +78 -220
- package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
- package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
- package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
- package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
- package/dist/runtime/locations/authority-key-codec.js +4 -3
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
- package/dist/runtime/locations/creation-operation-id.js +6 -4
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
- package/dist/runtime/locations/in-memory-authority-store.js +31 -15
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +17 -14
- package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
- package/dist/runtime/locations/key-codec.js +3 -2
- package/dist/runtime/locations/lease-tracker.d.ts +3 -5
- package/dist/runtime/locations/lease-tracker.js +7 -11
- package/dist/runtime/locations/lifecycle.d.ts +4 -9
- package/dist/runtime/locations/lifecycle.js +2 -31
- package/dist/runtime/locations/location-store-failure.d.ts +2 -0
- package/dist/runtime/locations/location-store-failure.js +7 -0
- package/dist/runtime/locations/location-store-pages.d.ts +3 -0
- package/dist/runtime/locations/location-store-pages.js +13 -0
- package/dist/runtime/locations/location-store-repository.d.ts +5 -7
- package/dist/runtime/locations/location-store-repository.js +309 -336
- package/dist/runtime/locations/relocation-blob.js +18 -5
- package/dist/runtime/locations/resolvers.d.ts +5 -5
- package/dist/runtime/locations/resolvers.js +37 -28
- package/dist/runtime/locations/runtime.d.ts +5 -4
- package/dist/runtime/locations/runtime.js +123 -92
- package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
- package/dist/runtime/locations/spot-location-claims.js +42 -1
- package/dist/runtime/messaging/payload-codec.js +26 -20
- package/dist/runtime/messaging/request-deadline.d.ts +3 -0
- package/dist/runtime/messaging/request-deadline.js +39 -0
- package/dist/runtime/messaging/submission-result.d.ts +4 -0
- package/dist/runtime/messaging/submission-result.js +56 -1
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
- package/dist/runtime/spots/index.d.ts +14 -20
- package/dist/runtime/spots/index.js +302 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
- package/dist/runtime/spots/spot-activation-registry.js +14 -50
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +2 -2
- package/dist/runtime/spots/spot-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-activation.js +49 -32
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
- package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
- package/dist/runtime/spots/spot-actor-membership.js +22 -45
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
- package/dist/runtime/spots/spot-context.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +9 -20
- package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
- package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
- package/dist/runtime/spots/spot-manager-public.js +5 -4
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
- package/dist/runtime/spots/spot-outbound.d.ts +7 -8
- package/dist/runtime/spots/spot-outbound.js +21 -23
- package/dist/runtime/spots/spot-remote-codec.js +5 -3
- package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
- package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
- package/dist/runtime/spots/spot-route-replies.js +3 -1
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
- package/dist/runtime/spots/spot-serial-executor.js +2 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
- package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.js +65 -41
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +12 -2
- package/dist/runtime/streams/index.d.ts +16 -17
- package/dist/runtime/streams/index.js +22 -23
- package/dist/runtime/streams/managed-stream.d.ts +5 -2
- package/dist/runtime/streams/managed-stream.js +20 -13
- package/dist/runtime/streams/native-fallback-bound-session.js +14 -19
- package/dist/runtime/streams/protocol.d.ts +6 -33
- package/dist/runtime/streams/protocol.js +38 -110
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
- package/dist/runtime/streams/session-actor-coordinator.js +12 -4
- package/dist/runtime/streams/session-calls.d.ts +6 -8
- package/dist/runtime/streams/session-calls.js +6 -22
- package/dist/runtime/streams/session-context.d.ts +10 -10
- package/dist/runtime/streams/session-context.js +25 -10
- package/dist/runtime/streams/session-requests.js +2 -1
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
- package/dist/runtime/streams/stream-frame-factory.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
- package/dist/runtime/streams/stream-session-runtime.js +25 -33
- package/dist/runtime/workers/index.d.ts +2 -2
- package/dist/runtime/workers/index.js +5 -4
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
- package/src/contracts/Channels/Calls.ts +1 -1
- package/src/contracts/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Configuration/Builders.ts +0 -1
- package/src/contracts/Configuration/Configs.ts +0 -1
- package/src/contracts/Configuration/InternalDefaults.ts +12 -0
- package/src/contracts/Configuration/Registration.ts +92 -48
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +77 -71
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -5
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -17
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Handlers/JsonContract.ts +14 -4
- package/src/contracts/Locations/Authority.ts +7 -3
- package/src/contracts/Locations/Options.ts +1 -1
- package/src/contracts/Locations/Stores.ts +14 -0
- package/src/contracts/Spots/Contracts.ts +2 -2
- package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
- package/src/contracts/Streams/IZLinkSession.ts +2 -3
- package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
- package/src/internal.ts +14 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +2 -8
- package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
- package/src/runtime/actors/actor-client.ts +85 -218
- package/src/runtime/actors/actor-context.ts +39 -33
- package/src/runtime/actors/actor-handoff.ts +24 -22
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +172 -174
- package/src/runtime/actors/actor-native-lookup.ts +2 -9
- package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
- package/src/runtime/actors/actor-remote-joiner.ts +9 -11
- package/src/runtime/actors/actor-remote-wire.ts +5 -3
- package/src/runtime/actors/actor-request-deadline.ts +4 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
- package/src/runtime/actors/actor-runtime-state.ts +85 -247
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +10 -6
- package/src/runtime/actors/index.ts +100 -79
- package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
- package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
- package/src/runtime/admission.ts +8 -1
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +14 -37
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-support.ts +67 -10
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
- package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +44 -49
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +4 -3
- package/src/runtime/backend/raw-binding-port.ts +1 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +139 -102
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +74 -57
- package/src/runtime/channels/channel-outbound-operations.ts +40 -55
- package/src/runtime/channels/channel-receive-loops.ts +39 -7
- package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
- package/src/runtime/channels/channel-runtime-manager.ts +12 -30
- package/src/runtime/channels/channel-socket-options.ts +8 -15
- package/src/runtime/channels/channel-socket-registry.ts +291 -196
- package/src/runtime/channels/channel-transports.ts +168 -145
- package/src/runtime/channels/client-server-location-runtime.ts +17 -17
- package/src/runtime/channels/client-server-service-wire.ts +40 -12
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
- package/src/runtime/channels/fanout-location-runtime.ts +172 -91
- package/src/runtime/channels/local-spot-route-transport.ts +1 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
- package/src/runtime/channels/source-spot-router.ts +2 -9
- package/src/runtime/channels/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +7 -9
- package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
- package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
- package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
- package/src/runtime/diagnostics/flow-context.ts +16 -2
- package/src/runtime/diagnostics/index.ts +27 -17
- package/src/runtime/diagnostics/message-flow.ts +15 -25
- package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
- package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
- package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
- package/src/runtime/disposal.ts +19 -0
- package/src/runtime/execution/index.ts +60 -20
- package/src/runtime/execution/serial-execution-queue.ts +131 -18
- package/src/runtime/execution/state-lane.ts +142 -4
- package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
- package/src/runtime/foundation/event-loop-resources.ts +5 -122
- package/src/runtime/foundation/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +127 -125
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
- package/src/runtime/foundation/service-discovery-registry.ts +32 -3
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
- package/src/runtime/foundation/service-liveness-registry.ts +2 -1
- package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
- package/src/runtime/foundation/service-metadata-codec.ts +2 -2
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
- package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
- package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
- package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
- package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
- package/src/runtime/foundation/service-topology-registry.ts +23 -32
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
- package/src/runtime/foundation/service-wire-codec.ts +15 -8
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
- package/src/runtime/framework-errors-internal.ts +380 -134
- package/src/runtime/handlers/handler-instance-scope.ts +68 -95
- package/src/runtime/host/actor-packet-relay.ts +63 -160
- package/src/runtime/host/actor-placement-coordinator.ts +8 -5
- package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
- package/src/runtime/host/actor-transfer-runtime.ts +180 -260
- package/src/runtime/host/application-job-queue.ts +28 -34
- package/src/runtime/host/bound-session-relay.ts +1 -2
- package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
- package/src/runtime/host/index.ts +327 -320
- package/src/runtime/host/instance-activation-authority.ts +89 -109
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
- package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
- package/src/runtime/host/remote-bound-session-relay.ts +16 -57
- package/src/runtime/host/route-mesh-runtime.ts +228 -271
- package/src/runtime/host/runtime-shutdown.ts +17 -21
- package/src/runtime/host/service-relocation-control.ts +14 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
- package/src/runtime/host/spot-address-transport.ts +175 -356
- package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
- package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
- package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
- package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
- package/src/runtime/locations/authority-key-codec.ts +7 -3
- package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
- package/src/runtime/locations/creation-operation-id.ts +6 -3
- package/src/runtime/locations/domain-store-contract.ts +12 -3
- package/src/runtime/locations/in-memory-authority-store.ts +44 -15
- package/src/runtime/locations/in-memory-location-store.ts +50 -39
- package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +13 -43
- package/src/runtime/locations/location-store-failure.ts +4 -0
- package/src/runtime/locations/location-store-pages.ts +18 -0
- package/src/runtime/locations/location-store-repository.ts +457 -482
- package/src/runtime/locations/relocation-blob.ts +17 -6
- package/src/runtime/locations/resolvers.ts +75 -49
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +58 -1
- package/src/runtime/messaging/payload-codec.ts +35 -24
- package/src/runtime/messaging/request-deadline.ts +58 -0
- package/src/runtime/messaging/submission-result.ts +72 -2
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
- package/src/runtime/spots/index.ts +433 -229
- package/src/runtime/spots/spot-activation-registry.ts +30 -69
- package/src/runtime/spots/spot-activation-state.ts +2 -2
- package/src/runtime/spots/spot-activation.ts +67 -37
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
- package/src/runtime/spots/spot-actor-membership.ts +40 -72
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
- package/src/runtime/spots/spot-context.ts +3 -3
- package/src/runtime/spots/spot-entry-activation.ts +13 -30
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +21 -17
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
- package/src/runtime/spots/spot-outbound.ts +59 -47
- package/src/runtime/spots/spot-remote-codec.ts +7 -3
- package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
- package/src/runtime/spots/spot-route-replies.ts +6 -4
- package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +5 -27
- package/src/runtime/spots/spot-serial-executor.ts +2 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +98 -66
- package/src/runtime/streams/bound-session-service.ts +22 -2
- package/src/runtime/streams/index.ts +78 -68
- package/src/runtime/streams/managed-stream.ts +32 -23
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -28
- package/src/runtime/streams/protocol.ts +34 -88
- package/src/runtime/streams/session-actor-coordinator.ts +17 -5
- package/src/runtime/streams/session-calls.ts +11 -36
- package/src/runtime/streams/session-context.ts +60 -25
- package/src/runtime/streams/session-requests.ts +2 -1
- package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
- package/src/runtime/streams/stream-frame-factory.ts +2 -3
- package/src/runtime/streams/stream-session-runtime.ts +57 -59
- package/src/runtime/workers/index.ts +13 -12
- package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
- package/dist/runtime/actors/post-commit-actor-location.js +0 -72
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
- package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
- package/src/runtime/actors/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -1,87 +1,104 @@
|
|
|
1
|
+
import { UINT64_MAX } from '@zlink-systems/stream-wire';
|
|
1
2
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
ZLinkStoreWriteRequest,
|
|
19
|
-
|
|
20
|
-
|
|
3
|
+
import { zlinkRuntimeDefaultLocationOptions } from '../../contracts/Locations/Options';
|
|
4
|
+
import {
|
|
5
|
+
type ZLinkClientServerServerDescriptor,
|
|
6
|
+
type ZLinkClientServerServerDescriptorKey,
|
|
7
|
+
type ZLinkFanoutPublisherDescriptor,
|
|
8
|
+
type ZLinkFanoutPublisherDescriptorKey,
|
|
9
|
+
type ZLinkLocationPage,
|
|
10
|
+
type ZLinkLocationStore,
|
|
11
|
+
type ZLinkMeshNodeDescriptor,
|
|
12
|
+
type ZLinkMeshNodeDescriptorKey,
|
|
13
|
+
type ZLinkPageRequest,
|
|
14
|
+
type ZLinkStoreCondition,
|
|
15
|
+
type ZLinkStoreKey,
|
|
16
|
+
type ZLinkStoreReadResult,
|
|
17
|
+
type ZLinkStoreScanCursor,
|
|
18
|
+
type ZLinkStoreVersion,
|
|
19
|
+
type ZLinkStoreWriteRequest,
|
|
20
|
+
ZLinkFrameworkRuntimeState,
|
|
21
|
+
ZLinkObjectRole
|
|
21
22
|
} from '../../contracts';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
ZLinkAuthorityScanCursor,
|
|
34
|
-
ZLinkAuthorityScanResult,
|
|
35
|
-
ZLinkAuthoritySnapshot,
|
|
36
|
-
ZLinkAuthorityStoreVersion,
|
|
37
|
-
ZLinkCapacityVector,
|
|
38
|
-
ZLinkCreationOperationIdentity,
|
|
39
|
-
ZLinkCreationTerminalReadResult,
|
|
40
|
-
ZLinkCreationTerminalRecord,
|
|
41
|
-
ZLinkLocationOwnerToken,
|
|
42
|
-
ZLinkLocationWriteResult,
|
|
43
|
-
ZLinkLocationWriteStatus,
|
|
44
|
-
ZLinkObjectCommitRequest,
|
|
45
|
-
ZLinkObjectCommitResult,
|
|
46
|
-
ZLinkObjectAbortRequest,
|
|
47
|
-
ZLinkObjectAbortResult,
|
|
48
|
-
ZLinkObjectCreationCompleteRequest,
|
|
49
|
-
ZLinkObjectCreationCompleteResult,
|
|
50
|
-
ZLinkObjectReserveRequest,
|
|
51
|
-
ZLinkObjectReserveResult,
|
|
52
|
-
ZLinkOwnerLeaseClaimResult,
|
|
53
|
-
ZLinkOwnerLeaseReadResult,
|
|
54
|
-
ZLinkOwnerLeaseReleaseResult,
|
|
55
|
-
ZLinkOwnerLeaseRenewResult,
|
|
56
|
-
ZLinkPlacementAllocation
|
|
57
|
-
} from './internal-location-contracts';
|
|
58
|
-
import { ZLinkLocationWriteIntent } from './internal-location-contracts';
|
|
59
|
-
import type {
|
|
60
|
-
ZLinkActorLocation,
|
|
61
|
-
ZLinkActorLocationFilter,
|
|
62
|
-
ZLinkActorLocationKey,
|
|
63
|
-
ZLinkRouteLocation,
|
|
64
|
-
ZLinkRouteLocationFilter,
|
|
65
|
-
ZLinkRouteLocationKey,
|
|
66
|
-
ZLinkSpotLocation,
|
|
67
|
-
ZLinkSpotLocationFilter,
|
|
68
|
-
ZLinkSpotLocationKey
|
|
69
|
-
} from './internal-location-contracts';
|
|
70
|
-
import { ZLinkFrameworkRuntimeState, ZLinkObjectRole } from '../../contracts';
|
|
23
|
+
|
|
24
|
+
import { type RoutingId, ZLINK_MAX_ROUTING_ID_BYTES } from '../../contracts/Common/CoreTypes';
|
|
25
|
+
|
|
26
|
+
import {
|
|
27
|
+
AUTHORITY_ENVELOPE_MAX_BYTES,
|
|
28
|
+
CREATION_TERMINAL_ENVELOPE_MAX_BYTES
|
|
29
|
+
} from '../../contracts/Configuration/InternalDefaults';
|
|
30
|
+
import {
|
|
31
|
+
isValidPublicWeight,
|
|
32
|
+
ZLINK_MAX_PUBLIC_WEIGHT
|
|
33
|
+
} from '../../contracts/Configuration/RegistrationBuilderPolicy';
|
|
71
34
|
import { ZLinkLocationWriteStatus as WriteStatus } from '../../contracts/Locations';
|
|
35
|
+
import {
|
|
36
|
+
ZLINK_PROVIDER_MAX_PAGE_SIZE,
|
|
37
|
+
ZLINK_PROVIDER_MAX_VALUE_BYTES
|
|
38
|
+
} from '../../contracts/Locations/Stores';
|
|
39
|
+
import { SHA256_DIGEST_BYTES } from '../foundation/actor-join-recovery-codec';
|
|
40
|
+
import { decodeRoutingId, encodeRoutingIdStorageHex } from '../routing-id';
|
|
41
|
+
import { ZLinkAggregateInventoryStore } from './aggregate-inventory-store';
|
|
42
|
+
import { decodeAuthorityKey, encodeAuthorityKey } from './authority-key-codec';
|
|
72
43
|
import { ZLinkInMemoryLocationStore } from './in-memory-location-store';
|
|
73
|
-
import { storeKey } from './in-memory-provider-location-store';
|
|
44
|
+
import { PROVIDER_STORAGE_NAMESPACE_PREFIX, storeKey } from './in-memory-provider-location-store';
|
|
45
|
+
import {
|
|
46
|
+
type ZLinkActorLocation,
|
|
47
|
+
type ZLinkActorLocationFilter,
|
|
48
|
+
type ZLinkActorLocationKey,
|
|
49
|
+
type ZLinkAggregateAbortResult,
|
|
50
|
+
type ZLinkAggregateCommitResult,
|
|
51
|
+
type ZLinkAggregateFence,
|
|
52
|
+
type ZLinkAggregateId,
|
|
53
|
+
type ZLinkAggregatePrepareRequest,
|
|
54
|
+
type ZLinkAggregatePrepareResult,
|
|
55
|
+
type ZLinkAuthorityCompareExchangeResult,
|
|
56
|
+
type ZLinkAuthorityKey,
|
|
57
|
+
type ZLinkAuthorityMutation,
|
|
58
|
+
type ZLinkAuthorityReadResult,
|
|
59
|
+
type ZLinkAuthorityScanCursor,
|
|
60
|
+
type ZLinkAuthorityScanResult,
|
|
61
|
+
type ZLinkAuthoritySnapshot,
|
|
62
|
+
type ZLinkAuthorityStoreVersion,
|
|
63
|
+
type ZLinkCapacityVector,
|
|
64
|
+
type ZLinkCreationOperationIdentity,
|
|
65
|
+
type ZLinkCreationTerminalReadResult,
|
|
66
|
+
type ZLinkCreationTerminalRecord,
|
|
67
|
+
type ZLinkLocationOwnerToken,
|
|
68
|
+
type ZLinkLocationWriteResult,
|
|
69
|
+
type ZLinkLocationWriteStatus,
|
|
70
|
+
type ZLinkObjectAbortRequest,
|
|
71
|
+
type ZLinkObjectAbortResult,
|
|
72
|
+
type ZLinkObjectCommitRequest,
|
|
73
|
+
type ZLinkObjectCommitResult,
|
|
74
|
+
type ZLinkObjectCreationCompleteRequest,
|
|
75
|
+
type ZLinkObjectCreationCompleteResult,
|
|
76
|
+
type ZLinkObjectReserveRequest,
|
|
77
|
+
type ZLinkObjectReserveResult,
|
|
78
|
+
type ZLinkOwnerLeaseClaimResult,
|
|
79
|
+
type ZLinkOwnerLeaseReadResult,
|
|
80
|
+
type ZLinkOwnerLeaseReleaseResult,
|
|
81
|
+
type ZLinkOwnerLeaseRenewResult,
|
|
82
|
+
type ZLinkPlacementAllocation,
|
|
83
|
+
type ZLinkRouteLocation,
|
|
84
|
+
type ZLinkRouteLocationFilter,
|
|
85
|
+
type ZLinkRouteLocationKey,
|
|
86
|
+
type ZLinkSpotLocation,
|
|
87
|
+
type ZLinkSpotLocationFilter,
|
|
88
|
+
type ZLinkSpotLocationKey,
|
|
89
|
+
ZLinkLocationWriteIntent
|
|
90
|
+
} from './internal-location-contracts';
|
|
91
|
+
|
|
74
92
|
import {
|
|
75
93
|
creationTerminalPreimage,
|
|
76
94
|
opaqueRecordPreimage,
|
|
77
95
|
routingIdHexSegment
|
|
78
96
|
} from './opaque-record-key';
|
|
79
|
-
|
|
80
|
-
import { ZLinkAggregateInventoryStore } from './aggregate-inventory-store';
|
|
81
|
-
import type { RoutingId } from '../../contracts/Common/CoreTypes';
|
|
82
|
-
import { decodeRoutingId, encodeRoutingIdStorageHex } from '../routing-id';
|
|
97
|
+
const LOCATION_STORE_WRITE_CONCURRENCY = 64;
|
|
83
98
|
|
|
84
|
-
const
|
|
99
|
+
const LOCATION_RECORD_VERSION = 1;
|
|
100
|
+
|
|
101
|
+
const PREFIX = PROVIDER_STORAGE_NAMESPACE_PREFIX;
|
|
85
102
|
const OWNER_COUNTER_KEY = storeKey(`${PREFIX}owner-counter`);
|
|
86
103
|
// These counters are store-wide fences. They deliberately are not derived
|
|
87
104
|
// from an authority identity: deleting and recreating an authority must never
|
|
@@ -89,11 +106,9 @@ const OWNER_COUNTER_KEY = storeKey(`${PREFIX}owner-counter`);
|
|
|
89
106
|
const OBJECT_COUNTER_KEY = storeKey(`${PREFIX}object-counter`);
|
|
90
107
|
const AUTHORITY_OWNER_COUNTER_KEY = storeKey(`${PREFIX}authority-owner-counter`);
|
|
91
108
|
const MAX_GENERATION = 0x7fff_ffff_ffff_ffffn;
|
|
92
|
-
const MAX_U64 =
|
|
93
|
-
|
|
109
|
+
const MAX_U64 = UINT64_MAX;
|
|
110
|
+
|
|
94
111
|
const CREATION_TERMINAL_RETENTION_MS = 5 * 60 * 1000;
|
|
95
|
-
const AGGREGATE_COMMIT_RETRY_WINDOW_MS = 5_000;
|
|
96
|
-
const MAX_AGGREGATE_COMMIT_CONFLICT_RETRIES = 64;
|
|
97
112
|
const MAX_DESCRIPTOR_WRITE_RETRIES = 3;
|
|
98
113
|
|
|
99
114
|
type StoredAuthoritySnapshot = Omit<ZLinkAuthoritySnapshot, 'kind' | 'storeVersion' | 'storeNow'>;
|
|
@@ -142,7 +157,7 @@ interface AggregateRecord {
|
|
|
142
157
|
}
|
|
143
158
|
|
|
144
159
|
interface OwnerRecord {
|
|
145
|
-
readonly recordVersion:
|
|
160
|
+
readonly recordVersion: typeof LOCATION_RECORD_VERSION;
|
|
146
161
|
readonly ownerId: string;
|
|
147
162
|
readonly leaseGeneration: string;
|
|
148
163
|
}
|
|
@@ -153,7 +168,7 @@ interface DescriptorRecord<T> {
|
|
|
153
168
|
}
|
|
154
169
|
|
|
155
170
|
interface CanonicalDescriptorRecord<T> {
|
|
156
|
-
readonly recordVersion:
|
|
171
|
+
readonly recordVersion: typeof LOCATION_RECORD_VERSION;
|
|
157
172
|
/** Legacy Node-private row generation. Canonical v1 records omit this. */
|
|
158
173
|
readonly generation?: string;
|
|
159
174
|
readonly ownerId: string;
|
|
@@ -189,7 +204,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
189
204
|
private readonly nowProvider: () => Date = () => new Date()
|
|
190
205
|
) {
|
|
191
206
|
super(nowProvider);
|
|
192
|
-
this.provider =
|
|
207
|
+
this.provider = provider;
|
|
193
208
|
this.aggregateInventory = new ZLinkAggregateInventoryStore(this.provider);
|
|
194
209
|
}
|
|
195
210
|
|
|
@@ -215,8 +230,8 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
215
230
|
limit: number,
|
|
216
231
|
signal?: AbortSignal
|
|
217
232
|
): Promise<ZLinkAuthorityScanResult> {
|
|
218
|
-
if (!Number.isInteger(limit) || limit < 1 || limit >
|
|
219
|
-
throw new RangeError(
|
|
233
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > ZLINK_PROVIDER_MAX_PAGE_SIZE) {
|
|
234
|
+
throw new RangeError(`Authority scan limit must be in 1..${ZLINK_PROVIDER_MAX_PAGE_SIZE}.`);
|
|
220
235
|
}
|
|
221
236
|
const scan = await this.provider.scan(
|
|
222
237
|
{
|
|
@@ -323,7 +338,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
323
338
|
conditions: [
|
|
324
339
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
325
340
|
versionCondition(descriptorKey, descriptorRead),
|
|
326
|
-
|
|
341
|
+
leaseValueCondition(ownerKey(mutation.targetOwner.ownerId), mutation.targetOwner)
|
|
327
342
|
],
|
|
328
343
|
mutations: [{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord) }]
|
|
329
344
|
},
|
|
@@ -358,6 +373,19 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
358
373
|
);
|
|
359
374
|
const capacityRead =
|
|
360
375
|
mutation.kind === 'delete' ? await this.provider.read(capacityRowKey, signal) : undefined;
|
|
376
|
+
const generations =
|
|
377
|
+
mutation.kind === 'put' && mutation.generationTransition === 'reincarnate'
|
|
378
|
+
? await Promise.all([
|
|
379
|
+
this.provider.read(OBJECT_COUNTER_KEY, signal),
|
|
380
|
+
this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
|
|
381
|
+
])
|
|
382
|
+
: undefined;
|
|
383
|
+
if (
|
|
384
|
+
generations !== undefined &&
|
|
385
|
+
generations.some((counter) => counterNextValue(counter) >= MAX_GENERATION)
|
|
386
|
+
) {
|
|
387
|
+
return { kind: 'generationExhausted' };
|
|
388
|
+
}
|
|
361
389
|
const nextRecord: AuthorityRecord | undefined =
|
|
362
390
|
mutation.kind === 'delete'
|
|
363
391
|
? undefined
|
|
@@ -366,6 +394,12 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
366
394
|
visibleStoreVersion: undefined,
|
|
367
395
|
snapshot: {
|
|
368
396
|
...record.snapshot,
|
|
397
|
+
...(generations === undefined
|
|
398
|
+
? {}
|
|
399
|
+
: {
|
|
400
|
+
objectGeneration: counterNextValue(generations[0]),
|
|
401
|
+
authorityOwnerGeneration: counterNextValue(generations[1])
|
|
402
|
+
}),
|
|
369
403
|
payload: Buffer.from(mutation.payload)
|
|
370
404
|
}
|
|
371
405
|
};
|
|
@@ -373,8 +407,21 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
373
407
|
{
|
|
374
408
|
conditions: [
|
|
375
409
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
376
|
-
...(mutation.kind === 'restore'
|
|
377
|
-
|
|
410
|
+
...(mutation.kind === 'restore'
|
|
411
|
+
? []
|
|
412
|
+
: [
|
|
413
|
+
leaseValueCondition(leaseKey, {
|
|
414
|
+
ownerId: record.snapshot.ownerId,
|
|
415
|
+
leaseGeneration: record.snapshot.ownerLeaseGeneration
|
|
416
|
+
})
|
|
417
|
+
]),
|
|
418
|
+
...(capacityRead === undefined ? [] : [conditionFor(capacityRowKey, capacityRead)]),
|
|
419
|
+
...(generations === undefined
|
|
420
|
+
? []
|
|
421
|
+
: [
|
|
422
|
+
conditionFor(OBJECT_COUNTER_KEY, generations[0]),
|
|
423
|
+
conditionFor(AUTHORITY_OWNER_COUNTER_KEY, generations[1])
|
|
424
|
+
])
|
|
378
425
|
],
|
|
379
426
|
mutations:
|
|
380
427
|
mutation.kind === 'delete'
|
|
@@ -397,7 +444,23 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
397
444
|
} satisfies CapacityRecord)
|
|
398
445
|
}
|
|
399
446
|
]
|
|
400
|
-
: [
|
|
447
|
+
: [
|
|
448
|
+
{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord!) },
|
|
449
|
+
...(generations === undefined
|
|
450
|
+
? []
|
|
451
|
+
: [
|
|
452
|
+
{
|
|
453
|
+
kind: 'put' as const,
|
|
454
|
+
key: OBJECT_COUNTER_KEY,
|
|
455
|
+
bytes: encodeText((counterNextValue(generations[0]) + 1n).toString())
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
kind: 'put' as const,
|
|
459
|
+
key: AUTHORITY_OWNER_COUNTER_KEY,
|
|
460
|
+
bytes: encodeText((counterNextValue(generations[1]) + 1n).toString())
|
|
461
|
+
}
|
|
462
|
+
])
|
|
463
|
+
]
|
|
401
464
|
},
|
|
402
465
|
signal
|
|
403
466
|
);
|
|
@@ -483,26 +546,30 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
483
546
|
if (entries.length !== request.participants.length) {
|
|
484
547
|
throw new Error('Aggregate inventory count changed after staging.');
|
|
485
548
|
}
|
|
486
|
-
await parallelForEach(
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
entry
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
549
|
+
await parallelForEach(
|
|
550
|
+
request.participants,
|
|
551
|
+
LOCATION_STORE_WRITE_CONCURRENCY,
|
|
552
|
+
async (participant, index) => {
|
|
553
|
+
const entry = entries[index]!;
|
|
554
|
+
if (
|
|
555
|
+
entry.authorityKey !== participant.authorityKey.value ||
|
|
556
|
+
entry.expectedStoreVersion !== participant.expectedStoreVersion.value ||
|
|
557
|
+
entry.ownerTransition !== participant.ownerTransition
|
|
558
|
+
) {
|
|
559
|
+
throw new Error('Aggregate inventory differs from its participant request.');
|
|
560
|
+
}
|
|
561
|
+
await this.putImmutable(
|
|
562
|
+
aggregateParticipantPayloadKey(fence, index),
|
|
563
|
+
participant.authorityPayload,
|
|
564
|
+
signal
|
|
565
|
+
);
|
|
566
|
+
await this.putImmutable(
|
|
567
|
+
aggregateParticipantMembershipKey(fence, index),
|
|
568
|
+
participant.membershipMutation,
|
|
569
|
+
signal
|
|
570
|
+
);
|
|
494
571
|
}
|
|
495
|
-
|
|
496
|
-
aggregateParticipantPayloadKey(fence, index),
|
|
497
|
-
participant.authorityPayload,
|
|
498
|
-
signal
|
|
499
|
-
);
|
|
500
|
-
await this.putImmutable(
|
|
501
|
-
aggregateParticipantMembershipKey(fence, index),
|
|
502
|
-
participant.membershipMutation,
|
|
503
|
-
signal
|
|
504
|
-
);
|
|
505
|
-
});
|
|
572
|
+
);
|
|
506
573
|
|
|
507
574
|
const targetDescriptorKey = meshKey(
|
|
508
575
|
request.targetDescriptor.meshName,
|
|
@@ -744,7 +811,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
744
811
|
conditions: [
|
|
745
812
|
{ kind: 'version', key: rowKey, expected: aggregateRead.value.version },
|
|
746
813
|
versionCondition(targetDescriptorKey, descriptorRead),
|
|
747
|
-
|
|
814
|
+
leaseValueCondition(targetLeaseKey, request.targetOwner),
|
|
748
815
|
conditionFor(targetCapacityKey, targetCapacityRead)
|
|
749
816
|
],
|
|
750
817
|
mutations: [
|
|
@@ -788,195 +855,190 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
788
855
|
signal?: AbortSignal
|
|
789
856
|
): Promise<ZLinkAggregateCommitResult> {
|
|
790
857
|
validateAggregateFence(fence);
|
|
791
|
-
return await this.commitAggregateCore(
|
|
792
|
-
fence,
|
|
793
|
-
0,
|
|
794
|
-
performance.now() + AGGREGATE_COMMIT_RETRY_WINDOW_MS,
|
|
795
|
-
signal
|
|
796
|
-
);
|
|
858
|
+
return await this.commitAggregateCore(fence, signal);
|
|
797
859
|
}
|
|
798
860
|
|
|
799
861
|
private async commitAggregateCore(
|
|
800
862
|
fence: ZLinkAggregateFence,
|
|
801
|
-
retryAttempt: number,
|
|
802
|
-
retryDeadlineAtMs: number,
|
|
803
863
|
signal?: AbortSignal
|
|
804
864
|
): Promise<ZLinkAggregateCommitResult> {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
const
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
const
|
|
839
|
-
if (
|
|
840
|
-
|
|
841
|
-
|
|
865
|
+
for (;;) {
|
|
866
|
+
signal?.throwIfAborted();
|
|
867
|
+
const rowKey = aggregateKey(fence);
|
|
868
|
+
let aggregateRead = await this.provider.read(rowKey, signal);
|
|
869
|
+
if (aggregateRead.kind === 'missing') return { kind: 'stale' };
|
|
870
|
+
let aggregate = decodeJson<AggregateRecord>(aggregateRead.value.bytes);
|
|
871
|
+
if (aggregate.state === 'aborted' || aggregate.state === 'staging') {
|
|
872
|
+
return { kind: 'stale' };
|
|
873
|
+
}
|
|
874
|
+
if (aggregate.state === 'committed') {
|
|
875
|
+
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
876
|
+
return { kind: 'alreadyCommitted' };
|
|
877
|
+
}
|
|
878
|
+
const entries = await this.aggregateInventory.read(
|
|
879
|
+
fence,
|
|
880
|
+
Buffer.from(aggregate.inventoryDigest),
|
|
881
|
+
signal
|
|
882
|
+
);
|
|
883
|
+
if (entries.length !== aggregate.participantCount) {
|
|
884
|
+
throw new Error('Aggregate inventory count differs from its authority record.');
|
|
885
|
+
}
|
|
886
|
+
const authorityRows = [];
|
|
887
|
+
for (let index = 0; index < entries.length; index++) {
|
|
888
|
+
const entry = entries[index]!;
|
|
889
|
+
const rowKeyForParticipant = authorityKey(entry.authorityKey);
|
|
890
|
+
const current = await this.provider.read(rowKeyForParticipant, signal);
|
|
891
|
+
if (current.kind === 'missing') return { kind: 'stale' };
|
|
892
|
+
const record = decodeAuthorityRecord(current.value.bytes);
|
|
893
|
+
if (!sameAggregateMarkerEntry(record.aggregate, fence, index, entry)) {
|
|
894
|
+
// A competing committer may already have published the aggregate and
|
|
895
|
+
// normalized this participant before this reader reached it. The
|
|
896
|
+
// committed aggregate is the terminal outcome to adopt, not a stale
|
|
897
|
+
// failure caused by observing the post-normalization row.
|
|
898
|
+
const latest = await this.provider.read(rowKey, signal);
|
|
899
|
+
if (latest.kind === 'found') {
|
|
900
|
+
const latestAggregate = decodeJson<AggregateRecord>(latest.value.bytes);
|
|
901
|
+
if (latestAggregate.state === 'committed') {
|
|
902
|
+
await this.normalizeCommittedAggregate(fence, latestAggregate, signal);
|
|
903
|
+
return { kind: 'alreadyCommitted' };
|
|
904
|
+
}
|
|
842
905
|
}
|
|
906
|
+
return { kind: 'stale' };
|
|
843
907
|
}
|
|
844
|
-
|
|
908
|
+
const [payload, membership] = await Promise.all([
|
|
909
|
+
requireProviderBytes(this.provider, aggregateParticipantPayloadKey(fence, index), signal),
|
|
910
|
+
requireProviderBytes(
|
|
911
|
+
this.provider,
|
|
912
|
+
aggregateParticipantMembershipKey(fence, index),
|
|
913
|
+
signal
|
|
914
|
+
)
|
|
915
|
+
]);
|
|
916
|
+
if (
|
|
917
|
+
sha256Hex(payload) !== entry.authorityPayloadSha256 ||
|
|
918
|
+
sha256Hex(membership) !== entry.membershipMutationSha256
|
|
919
|
+
) {
|
|
920
|
+
throw new Error('Aggregate participant staging checksum does not match inventory.');
|
|
921
|
+
}
|
|
922
|
+
authorityRows.push({ key: rowKeyForParticipant, current, record, entry });
|
|
845
923
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
924
|
+
|
|
925
|
+
const targetDescriptorKey = meshKey(
|
|
926
|
+
aggregate.targetDescriptor.meshName,
|
|
927
|
+
aggregate.targetDescriptor.rid
|
|
928
|
+
);
|
|
929
|
+
const targetLeaseKey = ownerKey(aggregate.targetOwner.ownerId);
|
|
930
|
+
const targetCapacityKey = capacityKey(
|
|
931
|
+
aggregate.targetDescriptor.meshName,
|
|
932
|
+
String(aggregate.targetDescriptor.rid)
|
|
933
|
+
);
|
|
934
|
+
const [descriptorRead, leaseRead] = await Promise.all([
|
|
935
|
+
this.provider.read(targetDescriptorKey, signal),
|
|
936
|
+
this.provider.read(targetLeaseKey, signal)
|
|
849
937
|
]);
|
|
850
938
|
if (
|
|
851
|
-
|
|
852
|
-
|
|
939
|
+
liveTargetDescriptor(descriptorRead, leaseRead, aggregateTargetFromRecord(aggregate)) ===
|
|
940
|
+
undefined
|
|
853
941
|
) {
|
|
854
|
-
|
|
942
|
+
return { kind: 'stale' };
|
|
855
943
|
}
|
|
856
|
-
authorityRows.push({ key: rowKeyForParticipant, current, record, entry });
|
|
857
|
-
}
|
|
858
944
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
liveTargetDescriptor(descriptorRead, leaseRead, aggregateTargetFromRecord(aggregate)) ===
|
|
874
|
-
undefined
|
|
875
|
-
) {
|
|
876
|
-
return { kind: 'stale' };
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
const capacityDeltas = new Map<string, ZLinkCapacityVector>();
|
|
880
|
-
for (const row of authorityRows) {
|
|
881
|
-
if (row.entry.ownerTransition !== 'newOwner') continue;
|
|
882
|
-
const key = capacityKey(
|
|
883
|
-
row.record.snapshot.allocation.descriptor.meshName,
|
|
884
|
-
String(row.record.snapshot.allocation.descriptor.rid)
|
|
885
|
-
).value;
|
|
886
|
-
capacityDeltas.set(
|
|
887
|
-
key,
|
|
888
|
-
addCapacityVector(
|
|
889
|
-
capacityDeltas.get(key) ?? { actors: 0, spots: 0 },
|
|
890
|
-
row.record.snapshot.allocation.capacity
|
|
891
|
-
)
|
|
892
|
-
);
|
|
893
|
-
}
|
|
894
|
-
const capacityKeys = new Map<string, ZLinkStoreKey>();
|
|
895
|
-
capacityKeys.set(targetCapacityKey.value, targetCapacityKey);
|
|
896
|
-
for (const value of capacityDeltas.keys()) capacityKeys.set(value, storeKey(value));
|
|
897
|
-
const capacityReads = new Map<string, Extract<ZLinkStoreReadResult, { kind: 'found' }>>();
|
|
898
|
-
for (const [value, key] of capacityKeys) {
|
|
899
|
-
const read = await this.provider.read(key, signal);
|
|
900
|
-
if (read.kind === 'missing') {
|
|
901
|
-
// Capacity rows are provider-private. A foreign source legitimately
|
|
902
|
-
// has no row under this provider's key encoding; its source runtime
|
|
903
|
-
// releases that capacity after observing the committed authority.
|
|
904
|
-
// The target row remains mandatory because this provider reserved it
|
|
905
|
-
// during prepare and must consume it atomically with commit.
|
|
906
|
-
if (value === targetCapacityKey.value) return { kind: 'stale' };
|
|
907
|
-
capacityKeys.delete(value);
|
|
908
|
-
continue;
|
|
945
|
+
const capacityDeltas = new Map<string, ZLinkCapacityVector>();
|
|
946
|
+
for (const row of authorityRows) {
|
|
947
|
+
if (row.entry.ownerTransition !== 'newOwner') continue;
|
|
948
|
+
const key = capacityKey(
|
|
949
|
+
row.record.snapshot.allocation.descriptor.meshName,
|
|
950
|
+
String(row.record.snapshot.allocation.descriptor.rid)
|
|
951
|
+
).value;
|
|
952
|
+
capacityDeltas.set(
|
|
953
|
+
key,
|
|
954
|
+
addCapacityVector(
|
|
955
|
+
capacityDeltas.get(key) ?? { actors: 0, spots: 0 },
|
|
956
|
+
row.record.snapshot.allocation.capacity
|
|
957
|
+
)
|
|
958
|
+
);
|
|
909
959
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
const
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
960
|
+
const capacityKeys = new Map<string, ZLinkStoreKey>();
|
|
961
|
+
capacityKeys.set(targetCapacityKey.value, targetCapacityKey);
|
|
962
|
+
for (const value of capacityDeltas.keys()) capacityKeys.set(value, storeKey(value));
|
|
963
|
+
const capacityReads = new Map<string, Extract<ZLinkStoreReadResult, { kind: 'found' }>>();
|
|
964
|
+
for (const [value, key] of capacityKeys) {
|
|
965
|
+
const read = await this.provider.read(key, signal);
|
|
966
|
+
if (read.kind === 'missing') {
|
|
967
|
+
// Capacity rows are provider-private. A foreign source legitimately
|
|
968
|
+
// has no row under this provider's key encoding; its source runtime
|
|
969
|
+
// releases that capacity after observing the committed authority.
|
|
970
|
+
// The target row remains mandatory because this provider reserved it
|
|
971
|
+
// during prepare and must consume it atomically with commit.
|
|
972
|
+
if (value === targetCapacityKey.value) return { kind: 'stale' };
|
|
973
|
+
capacityKeys.delete(value);
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
capacityReads.set(value, read);
|
|
922
977
|
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
978
|
+
const capacityMutations = [];
|
|
979
|
+
for (const [value, key] of capacityKeys) {
|
|
980
|
+
const read = capacityReads.get(value)!;
|
|
981
|
+
let capacity = decodeJson<CapacityRecord>(read.value.bytes);
|
|
982
|
+
const sourceDelta = capacityDeltas.get(value);
|
|
983
|
+
if (sourceDelta !== undefined) {
|
|
984
|
+
capacity = {
|
|
985
|
+
active: subtractCapacity(capacity.active, sourceDelta),
|
|
986
|
+
pending: capacity.pending
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
if (value === targetCapacityKey.value) {
|
|
990
|
+
capacity = {
|
|
991
|
+
active: addCapacity(capacity.active, aggregate.capacity),
|
|
992
|
+
pending: subtractCapacity(capacity.pending, aggregate.capacity)
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
capacityMutations.push({
|
|
996
|
+
kind: 'put' as const,
|
|
997
|
+
key,
|
|
998
|
+
bytes: encodeJson(capacity)
|
|
999
|
+
});
|
|
928
1000
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
aggregate.state
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
) {
|
|
967
|
-
// The commit CAS also fences the target's live owner lease, descriptor,
|
|
968
|
-
// and capacity rows. Re-read the whole prepared fence after an
|
|
969
|
-
// auxiliary-row race; a changed aggregate or participant fence exits
|
|
970
|
-
// through the normal stale checks on the next attempt.
|
|
971
|
-
await waitForAggregateCommitRetry(retryAttempt, retryDeadlineAtMs, signal);
|
|
972
|
-
return await this.commitAggregateCore(fence, retryAttempt + 1, retryDeadlineAtMs, signal);
|
|
1001
|
+
const published = await this.provider.write(
|
|
1002
|
+
{
|
|
1003
|
+
conditions: [
|
|
1004
|
+
{ kind: 'version', key: rowKey, expected: aggregateRead.value.version },
|
|
1005
|
+
versionCondition(targetDescriptorKey, descriptorRead),
|
|
1006
|
+
leaseValueCondition(targetLeaseKey, aggregate.targetOwner),
|
|
1007
|
+
...[...capacityReads.entries()].map(([value, read]) => ({
|
|
1008
|
+
kind: 'version' as const,
|
|
1009
|
+
key: capacityKeys.get(value)!,
|
|
1010
|
+
expected: read.value.version
|
|
1011
|
+
}))
|
|
1012
|
+
],
|
|
1013
|
+
mutations: [
|
|
1014
|
+
{
|
|
1015
|
+
kind: 'put',
|
|
1016
|
+
key: rowKey,
|
|
1017
|
+
bytes: encodeJson({ ...aggregate, state: 'committed' } satisfies AggregateRecord)
|
|
1018
|
+
},
|
|
1019
|
+
...capacityMutations
|
|
1020
|
+
]
|
|
1021
|
+
},
|
|
1022
|
+
signal
|
|
1023
|
+
);
|
|
1024
|
+
if (published.kind === 'conflict') {
|
|
1025
|
+
aggregateRead = await this.provider.read(rowKey, signal);
|
|
1026
|
+
if (aggregateRead.kind === 'missing') return { kind: 'stale' };
|
|
1027
|
+
aggregate = decodeJson<AggregateRecord>(aggregateRead.value.bytes);
|
|
1028
|
+
if (aggregate.state === 'prepared') {
|
|
1029
|
+
// The commit CAS also fences the target's live owner lease, descriptor,
|
|
1030
|
+
// and capacity rows. Re-read the whole prepared fence after an
|
|
1031
|
+
// auxiliary-row race; a changed aggregate or participant fence exits
|
|
1032
|
+
// through the normal stale checks on the next attempt.
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
if (aggregate.state !== 'committed') return { kind: 'stale' };
|
|
1036
|
+
} else {
|
|
1037
|
+
aggregate = { ...aggregate, state: 'committed' };
|
|
973
1038
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
aggregate = { ...aggregate, state: 'committed' };
|
|
1039
|
+
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
1040
|
+
return { kind: 'committed' };
|
|
977
1041
|
}
|
|
978
|
-
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
979
|
-
return { kind: 'committed' };
|
|
980
1042
|
}
|
|
981
1043
|
|
|
982
1044
|
override async abortAggregate(
|
|
@@ -1039,30 +1101,18 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1039
1101
|
|
|
1040
1102
|
override async reserve(
|
|
1041
1103
|
request: ZLinkObjectReserveRequest,
|
|
1042
|
-
signal?: AbortSignal
|
|
1104
|
+
signal?: AbortSignal,
|
|
1105
|
+
deadlineUnixMs?: bigint
|
|
1043
1106
|
): Promise<ZLinkObjectReserveResult> {
|
|
1044
1107
|
const encodedAuthorityKey = encodeAuthorityKey(request.key.kind, request.key.globalId);
|
|
1108
|
+
const reservationId = randomUUID();
|
|
1045
1109
|
for (;;) {
|
|
1046
|
-
signal
|
|
1110
|
+
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
1047
1111
|
const rowKey = authorityKey(encodedAuthorityKey.value);
|
|
1048
1112
|
const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
|
|
1049
1113
|
const leaseKey = ownerKey(request.target.owner.ownerId);
|
|
1050
1114
|
const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
|
|
1051
|
-
const
|
|
1052
|
-
current,
|
|
1053
|
-
descriptorRead,
|
|
1054
|
-
leaseRead,
|
|
1055
|
-
capacityRead,
|
|
1056
|
-
objectGenerationRead,
|
|
1057
|
-
authorityOwnerGenerationRead
|
|
1058
|
-
] = await Promise.all([
|
|
1059
|
-
this.provider.read(rowKey, signal),
|
|
1060
|
-
this.provider.read(descriptorKey, signal),
|
|
1061
|
-
this.provider.read(leaseKey, signal),
|
|
1062
|
-
this.provider.read(capacityRowKey, signal),
|
|
1063
|
-
this.provider.read(OBJECT_COUNTER_KEY, signal),
|
|
1064
|
-
this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
|
|
1065
|
-
]);
|
|
1115
|
+
const current = await this.provider.read(rowKey, signal);
|
|
1066
1116
|
if (current.kind === 'found') {
|
|
1067
1117
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
1068
1118
|
const snapshot = authoritySnapshot(
|
|
@@ -1138,10 +1188,19 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1138
1188
|
);
|
|
1139
1189
|
continue;
|
|
1140
1190
|
}
|
|
1191
|
+
const [descriptorRead, leaseRead] = await Promise.all([
|
|
1192
|
+
this.provider.read(descriptorKey, signal),
|
|
1193
|
+
this.provider.read(leaseKey, signal)
|
|
1194
|
+
]);
|
|
1141
1195
|
const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
|
|
1142
|
-
if (descriptor === undefined) {
|
|
1196
|
+
if (descriptor === undefined || descriptor.state !== ZLinkFrameworkRuntimeState.Serving) {
|
|
1143
1197
|
return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
|
|
1144
1198
|
}
|
|
1199
|
+
const [capacityRead, objectGenerationRead, authorityOwnerGenerationRead] = await Promise.all([
|
|
1200
|
+
this.provider.read(capacityRowKey, signal),
|
|
1201
|
+
this.provider.read(OBJECT_COUNTER_KEY, signal),
|
|
1202
|
+
this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
|
|
1203
|
+
]);
|
|
1145
1204
|
const capacity =
|
|
1146
1205
|
capacityRead.kind === 'missing'
|
|
1147
1206
|
? emptyCapacityRecord()
|
|
@@ -1157,7 +1216,6 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1157
1216
|
if (generation >= MAX_GENERATION || authorityOwnerGeneration >= MAX_GENERATION) {
|
|
1158
1217
|
return { kind: 'generationExhausted' };
|
|
1159
1218
|
}
|
|
1160
|
-
const reservationId = randomUUID();
|
|
1161
1219
|
const allocation: ZLinkPlacementAllocation = {
|
|
1162
1220
|
state: 'reserved',
|
|
1163
1221
|
objectKind: request.key.kind,
|
|
@@ -1190,7 +1248,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1190
1248
|
conditions: [
|
|
1191
1249
|
{ kind: 'missing', key: rowKey },
|
|
1192
1250
|
versionCondition(descriptorKey, descriptorRead),
|
|
1193
|
-
|
|
1251
|
+
leaseValueCondition(leaseKey, request.target.owner),
|
|
1194
1252
|
conditionFor(capacityRowKey, capacityRead),
|
|
1195
1253
|
conditionFor(OBJECT_COUNTER_KEY, objectGenerationRead),
|
|
1196
1254
|
conditionFor(AUTHORITY_OWNER_COUNTER_KEY, authorityOwnerGenerationRead)
|
|
@@ -1232,12 +1290,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1232
1290
|
|
|
1233
1291
|
override async commit(
|
|
1234
1292
|
request: ZLinkObjectCommitRequest,
|
|
1235
|
-
signal?: AbortSignal
|
|
1293
|
+
signal?: AbortSignal,
|
|
1294
|
+
deadlineUnixMs?: bigint
|
|
1236
1295
|
): Promise<ZLinkObjectCommitResult> {
|
|
1237
1296
|
const key = encodeAuthorityKey(request.key.kind, request.key.globalId);
|
|
1238
1297
|
const rowKey = authorityKey(key.value);
|
|
1239
1298
|
for (;;) {
|
|
1240
|
-
signal
|
|
1299
|
+
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
1241
1300
|
const current = await this.provider.read(rowKey, signal);
|
|
1242
1301
|
if (current.kind === 'missing') return { kind: 'stale' };
|
|
1243
1302
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
@@ -1288,7 +1347,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1288
1347
|
conditions: [
|
|
1289
1348
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1290
1349
|
versionCondition(descriptorKey, descriptorRead),
|
|
1291
|
-
|
|
1350
|
+
leaseValueCondition(leaseKey, request.target.owner),
|
|
1292
1351
|
conditionFor(capacityRowKey, capacityRead)
|
|
1293
1352
|
],
|
|
1294
1353
|
mutations: [
|
|
@@ -1317,12 +1376,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1317
1376
|
|
|
1318
1377
|
override async abort(
|
|
1319
1378
|
request: ZLinkObjectAbortRequest,
|
|
1320
|
-
signal?: AbortSignal
|
|
1379
|
+
signal?: AbortSignal,
|
|
1380
|
+
deadlineUnixMs?: bigint
|
|
1321
1381
|
): Promise<ZLinkObjectAbortResult> {
|
|
1322
1382
|
const key = encodeAuthorityKey(request.key.kind, request.key.globalId);
|
|
1323
1383
|
const rowKey = authorityKey(key.value);
|
|
1324
1384
|
for (;;) {
|
|
1325
|
-
signal
|
|
1385
|
+
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
1326
1386
|
const current = await this.provider.read(rowKey, signal);
|
|
1327
1387
|
if (current.kind === 'missing') return { kind: 'stale' };
|
|
1328
1388
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
@@ -1334,9 +1394,11 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1334
1394
|
) {
|
|
1335
1395
|
return { kind: 'stale' };
|
|
1336
1396
|
}
|
|
1397
|
+
const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
|
|
1337
1398
|
const leaseKey = ownerKey(request.target.owner.ownerId);
|
|
1338
1399
|
const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
|
|
1339
|
-
const [leaseRead, capacityRead] = await Promise.all([
|
|
1400
|
+
const [descriptorRead, leaseRead, capacityRead] = await Promise.all([
|
|
1401
|
+
this.provider.read(descriptorKey, signal),
|
|
1340
1402
|
this.provider.read(leaseKey, signal),
|
|
1341
1403
|
this.provider.read(capacityRowKey, signal)
|
|
1342
1404
|
]);
|
|
@@ -1346,7 +1408,8 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1346
1408
|
// rather than read the absence as expiry.
|
|
1347
1409
|
throw new Error('Location Store owner lease record is invalid.');
|
|
1348
1410
|
}
|
|
1349
|
-
if (
|
|
1411
|
+
if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined)
|
|
1412
|
+
return { kind: 'stale' };
|
|
1350
1413
|
const capacity =
|
|
1351
1414
|
capacityRead.kind === 'missing'
|
|
1352
1415
|
? emptyCapacityRecord()
|
|
@@ -1355,7 +1418,11 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1355
1418
|
{
|
|
1356
1419
|
conditions: [
|
|
1357
1420
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1358
|
-
versionCondition(
|
|
1421
|
+
versionCondition(descriptorKey, descriptorRead),
|
|
1422
|
+
leaseValueCondition(leaseKey, {
|
|
1423
|
+
ownerId: record.snapshot.ownerId,
|
|
1424
|
+
leaseGeneration: record.snapshot.ownerLeaseGeneration
|
|
1425
|
+
}),
|
|
1359
1426
|
conditionFor(capacityRowKey, capacityRead)
|
|
1360
1427
|
],
|
|
1361
1428
|
mutations: [
|
|
@@ -1388,11 +1455,11 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1388
1455
|
const rowKey = authorityKey(encodeAuthorityKey(request.key.kind, request.key.globalId).value);
|
|
1389
1456
|
const terminalRowKey = creationTerminalKey(terminal.operation);
|
|
1390
1457
|
for (;;) {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1458
|
+
throwIfOperationExpired(
|
|
1459
|
+
signal,
|
|
1460
|
+
BigInt(request.completion.terminal.operationDeadline.getTime())
|
|
1461
|
+
);
|
|
1462
|
+
const existingTerminal = await this.provider.read(terminalRowKey, signal);
|
|
1396
1463
|
if (existingTerminal.kind === 'found') {
|
|
1397
1464
|
return {
|
|
1398
1465
|
kind: 'alreadyCompleted',
|
|
@@ -1404,6 +1471,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1404
1471
|
)
|
|
1405
1472
|
};
|
|
1406
1473
|
}
|
|
1474
|
+
const current = await this.provider.read(rowKey, signal);
|
|
1407
1475
|
if (current.kind === 'missing') return { kind: 'stale' };
|
|
1408
1476
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
1409
1477
|
if (
|
|
@@ -1417,14 +1485,14 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1417
1485
|
const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
|
|
1418
1486
|
const leaseKey = ownerKey(request.target.owner.ownerId);
|
|
1419
1487
|
const capacityRowKey = capacityKey(request.target.meshName, request.target.nodeRid);
|
|
1420
|
-
const [descriptorRead, leaseRead
|
|
1488
|
+
const [descriptorRead, leaseRead] = await Promise.all([
|
|
1421
1489
|
this.provider.read(descriptorKey, signal),
|
|
1422
|
-
this.provider.read(leaseKey, signal)
|
|
1423
|
-
this.provider.read(capacityRowKey, signal)
|
|
1490
|
+
this.provider.read(leaseKey, signal)
|
|
1424
1491
|
]);
|
|
1425
1492
|
if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined) {
|
|
1426
1493
|
return { kind: 'stale' };
|
|
1427
1494
|
}
|
|
1495
|
+
const capacityRead = await this.provider.read(capacityRowKey, signal);
|
|
1428
1496
|
const capacity =
|
|
1429
1497
|
capacityRead.kind === 'missing'
|
|
1430
1498
|
? emptyCapacityRecord()
|
|
@@ -1481,7 +1549,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1481
1549
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1482
1550
|
{ kind: 'missing', key: terminalRowKey },
|
|
1483
1551
|
versionCondition(descriptorKey, descriptorRead),
|
|
1484
|
-
|
|
1552
|
+
leaseValueCondition(leaseKey, request.target.owner),
|
|
1485
1553
|
conditionFor(capacityRowKey, capacityRead)
|
|
1486
1554
|
],
|
|
1487
1555
|
mutations: [
|
|
@@ -1718,7 +1786,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
1718
1786
|
page.continuationToken === undefined
|
|
1719
1787
|
? undefined
|
|
1720
1788
|
: ({ value: page.continuationToken } as ZLinkStoreScanCursor),
|
|
1721
|
-
limit: page.pageSize ??
|
|
1789
|
+
limit: page.pageSize ?? zlinkRuntimeDefaultLocationOptions.listPageSize
|
|
1722
1790
|
},
|
|
1723
1791
|
signal
|
|
1724
1792
|
);
|
|
@@ -2346,7 +2414,6 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2346
2414
|
leaseKey,
|
|
2347
2415
|
descriptor.ownerId,
|
|
2348
2416
|
descriptor.leaseGeneration,
|
|
2349
|
-
lease,
|
|
2350
2417
|
rowKey,
|
|
2351
2418
|
current,
|
|
2352
2419
|
encodeCanonicalDescriptorRecord(generation, descriptor),
|
|
@@ -2359,14 +2426,12 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2359
2426
|
leaseKey: ZLinkStoreKey,
|
|
2360
2427
|
ownerId: string,
|
|
2361
2428
|
leaseGeneration: bigint,
|
|
2362
|
-
liveLease: Extract<ZLinkStoreReadResult, { kind: 'found' }>,
|
|
2363
2429
|
rowKey: ZLinkStoreKey,
|
|
2364
2430
|
predecessor: ZLinkStoreReadResult,
|
|
2365
2431
|
encodedDescriptor: Uint8Array,
|
|
2366
2432
|
generation: bigint,
|
|
2367
2433
|
signal?: AbortSignal
|
|
2368
2434
|
): Promise<ZLinkLocationWriteResult> {
|
|
2369
|
-
let currentLease = liveLease;
|
|
2370
2435
|
let currentRow = predecessor;
|
|
2371
2436
|
|
|
2372
2437
|
for (let attempt = 0; attempt <= MAX_DESCRIPTOR_WRITE_RETRIES; attempt += 1) {
|
|
@@ -2376,10 +2441,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2376
2441
|
: { kind: 'missing', key: rowKey };
|
|
2377
2442
|
const result = await this.provider.write(
|
|
2378
2443
|
{
|
|
2379
|
-
conditions: [
|
|
2380
|
-
{ kind: 'version', key: leaseKey, expected: currentLease.value.version },
|
|
2381
|
-
rowCondition
|
|
2382
|
-
],
|
|
2444
|
+
conditions: [leaseValueCondition(leaseKey, { ownerId, leaseGeneration }), rowCondition],
|
|
2383
2445
|
mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
|
|
2384
2446
|
},
|
|
2385
2447
|
signal
|
|
@@ -2401,7 +2463,6 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2401
2463
|
return ignoredStale(result.storeNow);
|
|
2402
2464
|
}
|
|
2403
2465
|
|
|
2404
|
-
currentLease = refreshedLease;
|
|
2405
2466
|
currentRow = refreshedRow;
|
|
2406
2467
|
}
|
|
2407
2468
|
throw new Error('Descriptor write retry loop exhausted unexpectedly.');
|
|
@@ -2445,7 +2506,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2445
2506
|
page.continuationToken === undefined
|
|
2446
2507
|
? undefined
|
|
2447
2508
|
: ({ value: page.continuationToken } as ZLinkStoreScanCursor),
|
|
2448
|
-
limit: page.pageSize ??
|
|
2509
|
+
limit: page.pageSize ?? zlinkRuntimeDefaultLocationOptions.listPageSize
|
|
2449
2510
|
},
|
|
2450
2511
|
signal
|
|
2451
2512
|
);
|
|
@@ -2521,7 +2582,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2521
2582
|
const result = await this.provider.write(
|
|
2522
2583
|
{
|
|
2523
2584
|
conditions: [
|
|
2524
|
-
|
|
2585
|
+
leaseValueCondition(leaseKey, {
|
|
2586
|
+
ownerId: location.ownerId,
|
|
2587
|
+
leaseGeneration: locationOwnerGeneration(location)
|
|
2588
|
+
}),
|
|
2525
2589
|
rowCondition
|
|
2526
2590
|
],
|
|
2527
2591
|
mutations: [
|
|
@@ -2585,7 +2649,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2585
2649
|
matches: (value: T) => boolean,
|
|
2586
2650
|
signal?: AbortSignal
|
|
2587
2651
|
): Promise<ZLinkLocationPage<T>> {
|
|
2588
|
-
const requested = page.pageSize ??
|
|
2652
|
+
const requested = page.pageSize ?? zlinkRuntimeDefaultLocationOptions.listPageSize;
|
|
2589
2653
|
let cursor =
|
|
2590
2654
|
page.continuationToken === undefined
|
|
2591
2655
|
? undefined
|
|
@@ -2690,7 +2754,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2690
2754
|
Buffer.from(aggregate.inventoryDigest),
|
|
2691
2755
|
signal
|
|
2692
2756
|
);
|
|
2693
|
-
await parallelForEach(entries,
|
|
2757
|
+
await parallelForEach(entries, LOCATION_STORE_WRITE_CONCURRENCY, async (entry, index) => {
|
|
2694
2758
|
const rowKey = authorityKey(entry.authorityKey);
|
|
2695
2759
|
for (;;) {
|
|
2696
2760
|
const current = await this.provider.read(rowKey, signal);
|
|
@@ -2779,8 +2843,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2779
2843
|
bytes: Uint8Array,
|
|
2780
2844
|
signal?: AbortSignal
|
|
2781
2845
|
): Promise<void> {
|
|
2782
|
-
if (bytes.byteLength >
|
|
2783
|
-
throw new RangeError(
|
|
2846
|
+
if (bytes.byteLength > ZLINK_PROVIDER_MAX_VALUE_BYTES) {
|
|
2847
|
+
throw new RangeError(
|
|
2848
|
+
`Aggregate participant staging value exceeds ${ZLINK_PROVIDER_MAX_VALUE_BYTES / (1024 * 1024)} MiB.`
|
|
2849
|
+
);
|
|
2784
2850
|
}
|
|
2785
2851
|
const result = await this.provider.write(
|
|
2786
2852
|
{
|
|
@@ -2838,7 +2904,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2838
2904
|
}[],
|
|
2839
2905
|
signal?: AbortSignal
|
|
2840
2906
|
): Promise<void> {
|
|
2841
|
-
await parallelForEach(installed,
|
|
2907
|
+
await parallelForEach(installed, LOCATION_STORE_WRITE_CONCURRENCY, async (value) => {
|
|
2842
2908
|
await this.clearAggregateMarker(fence, value.key, signal);
|
|
2843
2909
|
});
|
|
2844
2910
|
}
|
|
@@ -2868,7 +2934,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2868
2934
|
record.aggregate.aggregateGeneration === fence.aggregateGeneration
|
|
2869
2935
|
);
|
|
2870
2936
|
});
|
|
2871
|
-
await parallelForEach(matching,
|
|
2937
|
+
await parallelForEach(matching, LOCATION_STORE_WRITE_CONCURRENCY, async (item) => {
|
|
2872
2938
|
await this.clearAggregateMarker(fence, item.key, signal);
|
|
2873
2939
|
});
|
|
2874
2940
|
if (result.value.nextCursor === undefined) return;
|
|
@@ -2913,97 +2979,6 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
|
|
|
2913
2979
|
}
|
|
2914
2980
|
}
|
|
2915
2981
|
|
|
2916
|
-
const AMBIGUOUS_WRITE_RECONCILIATION_TIMEOUT_MS = 5_000;
|
|
2917
|
-
|
|
2918
|
-
/**
|
|
2919
|
-
* Keeps provider failures private while preserving the opaque Store contract.
|
|
2920
|
-
*
|
|
2921
|
-
* A write response can be lost after the provider applied the atomic batch.
|
|
2922
|
-
* The Framework confirms every mutation by an independent exact read. A put
|
|
2923
|
-
* must retain the requested bytes and a version different from the conditioned
|
|
2924
|
-
* version; a delete must remain absent. Any mismatch is a normal conflict, so
|
|
2925
|
-
* the domain repository can reread its authoritative record and classify the
|
|
2926
|
-
* operation without exposing a provider-specific retry API.
|
|
2927
|
-
*/
|
|
2928
|
-
class AmbiguousWriteReconcilingLocationStore implements ZLinkLocationStore {
|
|
2929
|
-
constructor(private readonly inner: ZLinkLocationStore) {}
|
|
2930
|
-
|
|
2931
|
-
read(key: ZLinkStoreKey, signal?: AbortSignal): Promise<ZLinkStoreReadResult> {
|
|
2932
|
-
return this.inner.read(key, signal);
|
|
2933
|
-
}
|
|
2934
|
-
|
|
2935
|
-
scan(request: ZLinkStoreScanRequest, signal?: AbortSignal): Promise<ZLinkStoreScanResult> {
|
|
2936
|
-
return this.inner.scan(request, signal);
|
|
2937
|
-
}
|
|
2938
|
-
|
|
2939
|
-
async write(
|
|
2940
|
-
request: ZLinkStoreWriteRequest,
|
|
2941
|
-
signal?: AbortSignal
|
|
2942
|
-
): Promise<ZLinkStoreWriteResult> {
|
|
2943
|
-
try {
|
|
2944
|
-
return await this.inner.write(request, signal);
|
|
2945
|
-
} catch (failure) {
|
|
2946
|
-
try {
|
|
2947
|
-
return await this.reconcile(request);
|
|
2948
|
-
} catch {
|
|
2949
|
-
throw failure;
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
}
|
|
2953
|
-
|
|
2954
|
-
private async reconcile(request: ZLinkStoreWriteRequest): Promise<ZLinkStoreWriteResult> {
|
|
2955
|
-
if (request.mutations.length === 0) {
|
|
2956
|
-
throw new Error('Cannot reconcile an opaque Store write without mutations.');
|
|
2957
|
-
}
|
|
2958
|
-
const reconciliationSignal = AbortSignal.timeout(AMBIGUOUS_WRITE_RECONCILIATION_TIMEOUT_MS);
|
|
2959
|
-
const reads = await Promise.all(
|
|
2960
|
-
request.mutations.map((mutation) => this.inner.read(mutation.key, reconciliationSignal))
|
|
2961
|
-
);
|
|
2962
|
-
const putVersions: Array<{
|
|
2963
|
-
readonly key: ZLinkStoreKey;
|
|
2964
|
-
readonly version: ZLinkStoreVersion;
|
|
2965
|
-
}> = [];
|
|
2966
|
-
let storeNow = new Date(0);
|
|
2967
|
-
|
|
2968
|
-
for (let index = 0; index < request.mutations.length; index += 1) {
|
|
2969
|
-
const mutation = request.mutations[index];
|
|
2970
|
-
const read = reads[index];
|
|
2971
|
-
storeNow =
|
|
2972
|
-
read.kind === 'found'
|
|
2973
|
-
? latestDate(storeNow, read.value.storeNow)
|
|
2974
|
-
: latestDate(storeNow, read.storeNow);
|
|
2975
|
-
|
|
2976
|
-
if (mutation.kind === 'delete') {
|
|
2977
|
-
if (read.kind !== 'missing') return { kind: 'conflict', storeNow };
|
|
2978
|
-
continue;
|
|
2979
|
-
}
|
|
2980
|
-
if (
|
|
2981
|
-
read.kind !== 'found' ||
|
|
2982
|
-
!Buffer.from(read.value.bytes).equals(Buffer.from(mutation.bytes)) ||
|
|
2983
|
-
!versionAdvanced(request.conditions, mutation.key, read.value.version)
|
|
2984
|
-
) {
|
|
2985
|
-
return { kind: 'conflict', storeNow };
|
|
2986
|
-
}
|
|
2987
|
-
putVersions.push({ key: mutation.key, version: read.value.version });
|
|
2988
|
-
}
|
|
2989
|
-
|
|
2990
|
-
return { kind: 'applied', putVersions, storeNow };
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
|
|
2994
|
-
function versionAdvanced(
|
|
2995
|
-
conditions: readonly ZLinkStoreCondition[],
|
|
2996
|
-
key: ZLinkStoreKey,
|
|
2997
|
-
current: ZLinkStoreVersion
|
|
2998
|
-
): boolean {
|
|
2999
|
-
const condition = conditions.find((candidate) => candidate.key.value === key.value);
|
|
3000
|
-
return condition?.kind !== 'version' || condition.expected.value !== current.value;
|
|
3001
|
-
}
|
|
3002
|
-
|
|
3003
|
-
function latestDate(left: Date, right: Date): Date {
|
|
3004
|
-
return left.getTime() >= right.getTime() ? left : right;
|
|
3005
|
-
}
|
|
3006
|
-
|
|
3007
2982
|
type OwnedDescriptor =
|
|
3008
2983
|
ZLinkMeshNodeDescriptor | ZLinkClientServerServerDescriptor | ZLinkFanoutPublisherDescriptor;
|
|
3009
2984
|
|
|
@@ -3016,8 +2991,8 @@ function validateProviderAggregateRequest(request: ZLinkAggregatePrepareRequest)
|
|
|
3016
2991
|
if (request.aggregateGeneration < 1n || request.participants.length < 1) {
|
|
3017
2992
|
throw new RangeError('Aggregate generation and participant count are invalid.');
|
|
3018
2993
|
}
|
|
3019
|
-
if (request.inventoryDigest.byteLength !==
|
|
3020
|
-
throw new TypeError(
|
|
2994
|
+
if (request.inventoryDigest.byteLength !== SHA256_DIGEST_BYTES) {
|
|
2995
|
+
throw new TypeError(`Aggregate inventory digest must contain ${SHA256_DIGEST_BYTES} bytes.`);
|
|
3021
2996
|
}
|
|
3022
2997
|
const keys = request.participants.map((value) => value.authorityKey.value);
|
|
3023
2998
|
if (
|
|
@@ -3030,10 +3005,12 @@ function validateProviderAggregateRequest(request: ZLinkAggregatePrepareRequest)
|
|
|
3030
3005
|
requireText(participant.authorityKey.value, 'aggregate authority key');
|
|
3031
3006
|
requireText(participant.expectedStoreVersion.value, 'aggregate expected Store version');
|
|
3032
3007
|
if (
|
|
3033
|
-
participant.authorityPayload.byteLength >
|
|
3034
|
-
participant.membershipMutation.byteLength >
|
|
3008
|
+
participant.authorityPayload.byteLength > ZLINK_PROVIDER_MAX_VALUE_BYTES ||
|
|
3009
|
+
participant.membershipMutation.byteLength > ZLINK_PROVIDER_MAX_VALUE_BYTES
|
|
3035
3010
|
) {
|
|
3036
|
-
throw new RangeError(
|
|
3011
|
+
throw new RangeError(
|
|
3012
|
+
`Aggregate participant value exceeds ${ZLINK_PROVIDER_MAX_VALUE_BYTES / (1024 * 1024)} MiB.`
|
|
3013
|
+
);
|
|
3037
3014
|
}
|
|
3038
3015
|
}
|
|
3039
3016
|
}
|
|
@@ -3186,33 +3163,6 @@ async function parallelForEach<T>(
|
|
|
3186
3163
|
);
|
|
3187
3164
|
}
|
|
3188
3165
|
|
|
3189
|
-
async function waitForAggregateCommitRetry(
|
|
3190
|
-
retryAttempt: number,
|
|
3191
|
-
deadlineAtMs: number,
|
|
3192
|
-
signal?: AbortSignal
|
|
3193
|
-
): Promise<void> {
|
|
3194
|
-
signal?.throwIfAborted();
|
|
3195
|
-
const remainingMs = deadlineAtMs - performance.now();
|
|
3196
|
-
if (remainingMs <= 0) return;
|
|
3197
|
-
const exponentialMs = Math.min(100, 2 << Math.min(retryAttempt, 5));
|
|
3198
|
-
const delayMs = Math.min(
|
|
3199
|
-
remainingMs,
|
|
3200
|
-
exponentialMs + Math.floor(Math.random() * (exponentialMs + 1))
|
|
3201
|
-
);
|
|
3202
|
-
await new Promise<void>((resolve, reject) => {
|
|
3203
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
3204
|
-
const aborted = () => {
|
|
3205
|
-
if (timer !== undefined) clearTimeout(timer);
|
|
3206
|
-
reject(signal?.reason ?? new Error('Aggregate commit was aborted.'));
|
|
3207
|
-
};
|
|
3208
|
-
signal?.addEventListener('abort', aborted, { once: true });
|
|
3209
|
-
timer = setTimeout(() => {
|
|
3210
|
-
signal?.removeEventListener('abort', aborted);
|
|
3211
|
-
resolve();
|
|
3212
|
-
}, delayMs);
|
|
3213
|
-
});
|
|
3214
|
-
}
|
|
3215
|
-
|
|
3216
3166
|
function sha256Hex(bytes: Uint8Array): string {
|
|
3217
3167
|
return createHash('sha256').update(bytes).digest('hex');
|
|
3218
3168
|
}
|
|
@@ -3443,7 +3393,7 @@ function requireRecordVersion(value: unknown, kind: string): void {
|
|
|
3443
3393
|
if (
|
|
3444
3394
|
value === null ||
|
|
3445
3395
|
typeof value !== 'object' ||
|
|
3446
|
-
(value as { recordVersion?: unknown }).recordVersion !==
|
|
3396
|
+
(value as { recordVersion?: unknown }).recordVersion !== LOCATION_RECORD_VERSION
|
|
3447
3397
|
) {
|
|
3448
3398
|
throw new Error(`Location Store ${kind} record has an unrecognized recordVersion.`);
|
|
3449
3399
|
}
|
|
@@ -3462,21 +3412,23 @@ function canonicalize(value: unknown): unknown {
|
|
|
3462
3412
|
return value;
|
|
3463
3413
|
}
|
|
3464
3414
|
|
|
3415
|
+
const GENERATION_KEYS = new Set([
|
|
3416
|
+
'generation',
|
|
3417
|
+
'leaseGeneration',
|
|
3418
|
+
'ownerLeaseGeneration',
|
|
3419
|
+
'objectGeneration',
|
|
3420
|
+
'authorityOwnerGeneration',
|
|
3421
|
+
'targetAuthorityOwnerGeneration',
|
|
3422
|
+
'aggregateGeneration',
|
|
3423
|
+
'lifecycleGeneration',
|
|
3424
|
+
'descriptorRevision',
|
|
3425
|
+
'nodeGeneration',
|
|
3426
|
+
'applicationVersion',
|
|
3427
|
+
'requestEncodedSize'
|
|
3428
|
+
]);
|
|
3429
|
+
|
|
3465
3430
|
function reviveCanonical(value: unknown, key = ''): unknown {
|
|
3466
|
-
|
|
3467
|
-
'generation',
|
|
3468
|
-
'leaseGeneration',
|
|
3469
|
-
'ownerLeaseGeneration',
|
|
3470
|
-
'objectGeneration',
|
|
3471
|
-
'authorityOwnerGeneration',
|
|
3472
|
-
'aggregateGeneration',
|
|
3473
|
-
'lifecycleGeneration',
|
|
3474
|
-
'descriptorRevision',
|
|
3475
|
-
'nodeGeneration',
|
|
3476
|
-
'applicationVersion',
|
|
3477
|
-
'requestEncodedSize'
|
|
3478
|
-
]);
|
|
3479
|
-
if (typeof value === 'string' && generationKeys.has(key)) return BigInt(value);
|
|
3431
|
+
if (typeof value === 'string' && GENERATION_KEYS.has(key)) return BigInt(value);
|
|
3480
3432
|
if (Array.isArray(value)) return value.map((item) => reviveCanonical(item));
|
|
3481
3433
|
if (value !== null && typeof value === 'object') {
|
|
3482
3434
|
return Object.fromEntries(
|
|
@@ -3494,7 +3446,7 @@ function decodeOwnerRecord(bytes: Uint8Array): OwnerRecord {
|
|
|
3494
3446
|
|
|
3495
3447
|
function encodeOwnerRecord(ownerId: string, leaseGeneration: bigint): Uint8Array {
|
|
3496
3448
|
return encodeJson<OwnerRecord>({
|
|
3497
|
-
recordVersion:
|
|
3449
|
+
recordVersion: LOCATION_RECORD_VERSION,
|
|
3498
3450
|
ownerId,
|
|
3499
3451
|
leaseGeneration: leaseGeneration.toString()
|
|
3500
3452
|
});
|
|
@@ -3510,7 +3462,7 @@ function encodeCanonicalDescriptorRecord<T extends OwnedDescriptor>(
|
|
|
3510
3462
|
void generation;
|
|
3511
3463
|
return Buffer.from(
|
|
3512
3464
|
JSON.stringify({
|
|
3513
|
-
recordVersion:
|
|
3465
|
+
recordVersion: LOCATION_RECORD_VERSION,
|
|
3514
3466
|
ownerId: descriptor.ownerId,
|
|
3515
3467
|
leaseGeneration: descriptor.leaseGeneration.toString(),
|
|
3516
3468
|
descriptorRevision: descriptor.descriptorRevision.toString(),
|
|
@@ -3525,7 +3477,7 @@ function decodeCanonicalDescriptorRecord<T extends OwnedDescriptor>(
|
|
|
3525
3477
|
): CanonicalDescriptorRecord<T> {
|
|
3526
3478
|
const record = JSON.parse(decodeText(bytes)) as CanonicalDescriptorRecord<unknown>;
|
|
3527
3479
|
requireRecordVersion(record, 'descriptor');
|
|
3528
|
-
return
|
|
3480
|
+
return record as CanonicalDescriptorRecord<T>;
|
|
3529
3481
|
}
|
|
3530
3482
|
|
|
3531
3483
|
function descriptorStoreGeneration(
|
|
@@ -3668,7 +3620,7 @@ function encodeAuthorityRecord(record: AuthorityRecord): Uint8Array {
|
|
|
3668
3620
|
const snapshot = record.snapshot;
|
|
3669
3621
|
const allocation = snapshot.allocation;
|
|
3670
3622
|
const envelope: Record<string, unknown> = {
|
|
3671
|
-
recordVersion:
|
|
3623
|
+
recordVersion: LOCATION_RECORD_VERSION,
|
|
3672
3624
|
payload: Buffer.from(snapshot.payload).toString('base64'),
|
|
3673
3625
|
objectGeneration: snapshot.objectGeneration.toString(),
|
|
3674
3626
|
authorityOwnerGeneration: snapshot.authorityOwnerGeneration.toString(),
|
|
@@ -3822,8 +3774,10 @@ function createTerminalRecord(
|
|
|
3822
3774
|
): ZLinkCreationTerminalRecord {
|
|
3823
3775
|
const publication = request.completion.terminal;
|
|
3824
3776
|
validateCreationOperation(publication.operation);
|
|
3825
|
-
if (publication.terminalEnvelope.byteLength >
|
|
3826
|
-
throw new RangeError(
|
|
3777
|
+
if (publication.terminalEnvelope.byteLength > CREATION_TERMINAL_ENVELOPE_MAX_BYTES) {
|
|
3778
|
+
throw new RangeError(
|
|
3779
|
+
`Creation terminal envelope must not exceed ${CREATION_TERMINAL_ENVELOPE_MAX_BYTES / (1024 * 1024)} MiB.`
|
|
3780
|
+
);
|
|
3827
3781
|
}
|
|
3828
3782
|
const deadlineMs = publication.operationDeadline.getTime();
|
|
3829
3783
|
const expiresAtMs = deadlineMs + CREATION_TERMINAL_RETENTION_MS;
|
|
@@ -3875,9 +3829,13 @@ function retainedCreationTerminal(
|
|
|
3875
3829
|
function validateCreationOperation(operation: ZLinkCreationOperationIdentity): void {
|
|
3876
3830
|
const sourceRid = String(operation.sourceNodeRid);
|
|
3877
3831
|
const sourceRidBytes = Buffer.byteLength(sourceRid, 'utf8');
|
|
3878
|
-
if (
|
|
3832
|
+
if (
|
|
3833
|
+
sourceRidBytes < 1 ||
|
|
3834
|
+
sourceRidBytes > ZLINK_MAX_ROUTING_ID_BYTES ||
|
|
3835
|
+
sourceRid.includes('\0')
|
|
3836
|
+
) {
|
|
3879
3837
|
throw new TypeError(
|
|
3880
|
-
|
|
3838
|
+
`Creation terminal source node RID must contain 1..${ZLINK_MAX_ROUTING_ID_BYTES} UTF-8 bytes without NUL.`
|
|
3881
3839
|
);
|
|
3882
3840
|
}
|
|
3883
3841
|
if (
|
|
@@ -3894,8 +3852,10 @@ function validateCreationOperation(operation: ZLinkCreationOperationIdentity): v
|
|
|
3894
3852
|
}
|
|
3895
3853
|
|
|
3896
3854
|
function validatePayloadSize(value: Uint8Array, name: string): void {
|
|
3897
|
-
if (value.byteLength >
|
|
3898
|
-
throw new RangeError(
|
|
3855
|
+
if (value.byteLength > AUTHORITY_ENVELOPE_MAX_BYTES) {
|
|
3856
|
+
throw new RangeError(
|
|
3857
|
+
`${name} must not exceed ${AUTHORITY_ENVELOPE_MAX_BYTES / (1024 * 1024)} MiB.`
|
|
3858
|
+
);
|
|
3899
3859
|
}
|
|
3900
3860
|
}
|
|
3901
3861
|
|
|
@@ -3948,7 +3908,6 @@ function liveTargetDescriptor(
|
|
|
3948
3908
|
descriptor.ownerId === target.owner.ownerId &&
|
|
3949
3909
|
descriptor.leaseGeneration === target.owner.leaseGeneration &&
|
|
3950
3910
|
descriptor.objectRole === ZLinkObjectRole.Server &&
|
|
3951
|
-
descriptor.state === ZLinkFrameworkRuntimeState.Serving &&
|
|
3952
3911
|
lease.ownerId === target.owner.ownerId &&
|
|
3953
3912
|
BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
|
|
3954
3913
|
leaseRead.value.expiresAt !== undefined &&
|
|
@@ -3970,6 +3929,13 @@ function versionCondition(key: ZLinkStoreKey, read: ZLinkStoreReadResult): ZLink
|
|
|
3970
3929
|
return { kind: 'version', key, expected: read.value.version };
|
|
3971
3930
|
}
|
|
3972
3931
|
|
|
3932
|
+
function leaseValueCondition(
|
|
3933
|
+
key: ZLinkStoreKey,
|
|
3934
|
+
owner: ZLinkLocationOwnerToken
|
|
3935
|
+
): ZLinkStoreCondition {
|
|
3936
|
+
return { kind: 'value', key, expected: encodeOwnerRecord(owner.ownerId, owner.leaseGeneration) };
|
|
3937
|
+
}
|
|
3938
|
+
|
|
3973
3939
|
function emptyCapacityRecord(): CapacityRecord {
|
|
3974
3940
|
return {
|
|
3975
3941
|
active: { actors: 0, spots: 0, spotTypes: {} },
|
|
@@ -4404,8 +4370,10 @@ function validateClientServerDescriptor(descriptor: ZLinkClientServerServerDescr
|
|
|
4404
4370
|
'ClientServer'
|
|
4405
4371
|
);
|
|
4406
4372
|
validateDescriptorGenerations(descriptor, 'ClientServer');
|
|
4407
|
-
if (!
|
|
4408
|
-
throw new RangeError(
|
|
4373
|
+
if (!isValidPublicWeight(descriptor.weight)) {
|
|
4374
|
+
throw new RangeError(
|
|
4375
|
+
`ClientServer descriptor weight must be an integer in 0..${ZLINK_MAX_PUBLIC_WEIGHT}.`
|
|
4376
|
+
);
|
|
4409
4377
|
}
|
|
4410
4378
|
}
|
|
4411
4379
|
|
|
@@ -4466,3 +4434,10 @@ function requireOwnerInput(ownerId: string, leaseTtlMs: number): void {
|
|
|
4466
4434
|
throw new RangeError('Owner lease TTL must be a positive safe integer.');
|
|
4467
4435
|
}
|
|
4468
4436
|
}
|
|
4437
|
+
|
|
4438
|
+
function throwIfOperationExpired(signal?: AbortSignal, deadlineUnixMs?: bigint): void {
|
|
4439
|
+
signal?.throwIfAborted();
|
|
4440
|
+
if (deadlineUnixMs !== undefined && Date.now() >= Number(deadlineUnixMs)) {
|
|
4441
|
+
throw new DOMException('Operation deadline exceeded.', 'TimeoutError');
|
|
4442
|
+
}
|
|
4443
|
+
}
|