@zlink-systems/framework 0.26.0 → 0.27.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/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/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 -0
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
- 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 +1 -1
- 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 +42 -143
- 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 +3 -0
- package/dist/runtime/actors/actor-request-deadline.js +31 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- 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 +6 -23
- 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 +1 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -6
- 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 +40 -16
- 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 +3 -2
- 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 +68 -52
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.js +47 -29
- package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
- package/dist/runtime/channels/channel-outbound-operations.js +9 -10
- 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.js +5 -2
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
- package/dist/runtime/channels/channel-socket-registry.js +248 -174
- package/dist/runtime/channels/channel-transports.d.ts +11 -17
- package/dist/runtime/channels/channel-transports.js +68 -47
- 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/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.js +3 -2
- 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 +62 -83
- 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 +9 -6
- package/dist/runtime/host/actor-packet-relay.js +48 -91
- 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 -157
- 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 +7 -20
- 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 +2 -3
- package/dist/runtime/host/spot-address-transport.js +34 -136
- 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 +303 -332
- 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/submission-result.d.ts +3 -0
- package/dist/runtime/messaging/submission-result.js +48 -0
- 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 +4 -3
- package/dist/runtime/spots/spot-outbound.js +9 -8
- 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 +6 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +11 -1
- package/dist/runtime/streams/index.d.ts +14 -15
- package/dist/runtime/streams/index.js +20 -21
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +17 -8
- package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
- 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 +1 -1
- package/dist/runtime/streams/session-calls.js +5 -4
- package/dist/runtime/streams/session-context.d.ts +6 -6
- package/dist/runtime/streams/session-context.js +22 -4
- 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/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -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 -68
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
- 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 +1 -1
- 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 +77 -204
- 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 +49 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- 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 +13 -29
- 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 +23 -6
- 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 +41 -20
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +3 -2
- 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 +132 -85
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +58 -29
- package/src/runtime/channels/channel-outbound-operations.ts +10 -23
- 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 +6 -2
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +301 -192
- package/src/runtime/channels/channel-transports.ts +161 -112
- 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/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +5 -2
- 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 +110 -111
- 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 +57 -147
- 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 -296
- 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 +8 -41
- 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 +73 -195
- 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 +450 -478
- 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/submission-result.ts +57 -1
- 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 +45 -23
- 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 +89 -43
- package/src/runtime/streams/bound-session-service.ts +21 -1
- package/src/runtime/streams/index.ts +76 -64
- package/src/runtime/streams/managed-stream.ts +29 -10
- package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
- 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 +6 -5
- package/src/runtime/streams/session-context.ts +54 -10
- 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,17 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkLocationStoreRepository = void 0;
|
|
4
|
+
const stream_wire_1 = require("@zlink-systems/stream-wire");
|
|
4
5
|
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const
|
|
6
|
+
const Options_1 = require("../../contracts/Locations/Options");
|
|
6
7
|
const contracts_1 = require("../../contracts");
|
|
8
|
+
const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
|
|
9
|
+
const InternalDefaults_1 = require("../../contracts/Configuration/InternalDefaults");
|
|
10
|
+
const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/RegistrationBuilderPolicy");
|
|
7
11
|
const Locations_1 = require("../../contracts/Locations");
|
|
12
|
+
const Stores_1 = require("../../contracts/Locations/Stores");
|
|
13
|
+
const actor_join_recovery_codec_1 = require("../foundation/actor-join-recovery-codec");
|
|
14
|
+
const routing_id_1 = require("../routing-id");
|
|
15
|
+
const aggregate_inventory_store_1 = require("./aggregate-inventory-store");
|
|
16
|
+
const authority_key_codec_1 = require("./authority-key-codec");
|
|
8
17
|
const in_memory_location_store_1 = require("./in-memory-location-store");
|
|
9
18
|
const in_memory_provider_location_store_1 = require("./in-memory-provider-location-store");
|
|
19
|
+
const internal_location_contracts_1 = require("./internal-location-contracts");
|
|
10
20
|
const opaque_record_key_1 = require("./opaque-record-key");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const PREFIX = 'zlink:v11:';
|
|
21
|
+
const LOCATION_STORE_WRITE_CONCURRENCY = 64;
|
|
22
|
+
const LOCATION_RECORD_VERSION = 1;
|
|
23
|
+
const PREFIX = in_memory_provider_location_store_1.PROVIDER_STORAGE_NAMESPACE_PREFIX;
|
|
15
24
|
const OWNER_COUNTER_KEY = (0, in_memory_provider_location_store_1.storeKey)(`${PREFIX}owner-counter`);
|
|
16
25
|
// These counters are store-wide fences. They deliberately are not derived
|
|
17
26
|
// from an authority identity: deleting and recreating an authority must never
|
|
@@ -19,11 +28,8 @@ const OWNER_COUNTER_KEY = (0, in_memory_provider_location_store_1.storeKey)(`${P
|
|
|
19
28
|
const OBJECT_COUNTER_KEY = (0, in_memory_provider_location_store_1.storeKey)(`${PREFIX}object-counter`);
|
|
20
29
|
const AUTHORITY_OWNER_COUNTER_KEY = (0, in_memory_provider_location_store_1.storeKey)(`${PREFIX}authority-owner-counter`);
|
|
21
30
|
const MAX_GENERATION = 0x7fffffffffffffffn;
|
|
22
|
-
const MAX_U64 =
|
|
23
|
-
const MAX_CREATION_TERMINAL_BYTES = 1024 * 1024;
|
|
31
|
+
const MAX_U64 = stream_wire_1.UINT64_MAX;
|
|
24
32
|
const CREATION_TERMINAL_RETENTION_MS = 5 * 60 * 1000;
|
|
25
|
-
const AGGREGATE_COMMIT_RETRY_WINDOW_MS = 5_000;
|
|
26
|
-
const MAX_AGGREGATE_COMMIT_CONFLICT_RETRIES = 64;
|
|
27
33
|
const MAX_DESCRIPTOR_WRITE_RETRIES = 3;
|
|
28
34
|
const MAX_OWNER_CLEANUP_BATCH_ROWS = 2_047;
|
|
29
35
|
/**
|
|
@@ -40,7 +46,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
40
46
|
constructor(provider, nowProvider = () => new Date()) {
|
|
41
47
|
super(nowProvider);
|
|
42
48
|
this.nowProvider = nowProvider;
|
|
43
|
-
this.provider =
|
|
49
|
+
this.provider = provider;
|
|
44
50
|
this.aggregateInventory = new aggregate_inventory_store_1.ZLinkAggregateInventoryStore(this.provider);
|
|
45
51
|
}
|
|
46
52
|
async readAuthority(key, signal) {
|
|
@@ -51,8 +57,8 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
51
57
|
return await this.projectAuthority(decodeAuthorityRecord(result.value.bytes), result.value.version, result.value.storeNow, signal);
|
|
52
58
|
}
|
|
53
59
|
async listAuthorities(prefix, cursor, limit, signal) {
|
|
54
|
-
if (!Number.isInteger(limit) || limit < 1 || limit >
|
|
55
|
-
throw new RangeError(
|
|
60
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE) {
|
|
61
|
+
throw new RangeError(`Authority scan limit must be in 1..${Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE}.`);
|
|
56
62
|
}
|
|
57
63
|
const scan = await this.provider.scan({
|
|
58
64
|
prefix: AUTHORITY_PREIMAGE_PREFIX,
|
|
@@ -130,7 +136,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
130
136
|
conditions: [
|
|
131
137
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
132
138
|
versionCondition(descriptorKey, descriptorRead),
|
|
133
|
-
|
|
139
|
+
leaseValueCondition(ownerKey(mutation.targetOwner.ownerId), mutation.targetOwner)
|
|
134
140
|
],
|
|
135
141
|
mutations: [{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord) }]
|
|
136
142
|
}, signal);
|
|
@@ -156,6 +162,16 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
156
162
|
}
|
|
157
163
|
const capacityRowKey = capacityKey(record.snapshot.allocation.descriptor.meshName, String(record.snapshot.allocation.descriptor.rid));
|
|
158
164
|
const capacityRead = mutation.kind === 'delete' ? await this.provider.read(capacityRowKey, signal) : undefined;
|
|
165
|
+
const generations = mutation.kind === 'put' && mutation.generationTransition === 'reincarnate'
|
|
166
|
+
? await Promise.all([
|
|
167
|
+
this.provider.read(OBJECT_COUNTER_KEY, signal),
|
|
168
|
+
this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
|
|
169
|
+
])
|
|
170
|
+
: undefined;
|
|
171
|
+
if (generations !== undefined &&
|
|
172
|
+
generations.some((counter) => counterNextValue(counter) >= MAX_GENERATION)) {
|
|
173
|
+
return { kind: 'generationExhausted' };
|
|
174
|
+
}
|
|
159
175
|
const nextRecord = mutation.kind === 'delete'
|
|
160
176
|
? undefined
|
|
161
177
|
: {
|
|
@@ -163,14 +179,33 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
163
179
|
visibleStoreVersion: undefined,
|
|
164
180
|
snapshot: {
|
|
165
181
|
...record.snapshot,
|
|
182
|
+
...(generations === undefined
|
|
183
|
+
? {}
|
|
184
|
+
: {
|
|
185
|
+
objectGeneration: counterNextValue(generations[0]),
|
|
186
|
+
authorityOwnerGeneration: counterNextValue(generations[1])
|
|
187
|
+
}),
|
|
166
188
|
payload: Buffer.from(mutation.payload)
|
|
167
189
|
}
|
|
168
190
|
};
|
|
169
191
|
const result = await this.provider.write({
|
|
170
192
|
conditions: [
|
|
171
193
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
172
|
-
...(mutation.kind === 'restore'
|
|
173
|
-
|
|
194
|
+
...(mutation.kind === 'restore'
|
|
195
|
+
? []
|
|
196
|
+
: [
|
|
197
|
+
leaseValueCondition(leaseKey, {
|
|
198
|
+
ownerId: record.snapshot.ownerId,
|
|
199
|
+
leaseGeneration: record.snapshot.ownerLeaseGeneration
|
|
200
|
+
})
|
|
201
|
+
]),
|
|
202
|
+
...(capacityRead === undefined ? [] : [conditionFor(capacityRowKey, capacityRead)]),
|
|
203
|
+
...(generations === undefined
|
|
204
|
+
? []
|
|
205
|
+
: [
|
|
206
|
+
conditionFor(OBJECT_COUNTER_KEY, generations[0]),
|
|
207
|
+
conditionFor(AUTHORITY_OWNER_COUNTER_KEY, generations[1])
|
|
208
|
+
])
|
|
174
209
|
],
|
|
175
210
|
mutations: mutation.kind === 'delete'
|
|
176
211
|
? [
|
|
@@ -188,7 +223,23 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
188
223
|
})
|
|
189
224
|
}
|
|
190
225
|
]
|
|
191
|
-
: [
|
|
226
|
+
: [
|
|
227
|
+
{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord) },
|
|
228
|
+
...(generations === undefined
|
|
229
|
+
? []
|
|
230
|
+
: [
|
|
231
|
+
{
|
|
232
|
+
kind: 'put',
|
|
233
|
+
key: OBJECT_COUNTER_KEY,
|
|
234
|
+
bytes: encodeText((counterNextValue(generations[0]) + 1n).toString())
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
kind: 'put',
|
|
238
|
+
key: AUTHORITY_OWNER_COUNTER_KEY,
|
|
239
|
+
bytes: encodeText((counterNextValue(generations[1]) + 1n).toString())
|
|
240
|
+
}
|
|
241
|
+
])
|
|
242
|
+
]
|
|
192
243
|
}, signal);
|
|
193
244
|
if (result.kind === 'conflict')
|
|
194
245
|
continue;
|
|
@@ -266,7 +317,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
266
317
|
if (entries.length !== request.participants.length) {
|
|
267
318
|
throw new Error('Aggregate inventory count changed after staging.');
|
|
268
319
|
}
|
|
269
|
-
await parallelForEach(request.participants,
|
|
320
|
+
await parallelForEach(request.participants, LOCATION_STORE_WRITE_CONCURRENCY, async (participant, index) => {
|
|
270
321
|
const entry = entries[index];
|
|
271
322
|
if (entry.authorityKey !== participant.authorityKey.value ||
|
|
272
323
|
entry.expectedStoreVersion !== participant.expectedStoreVersion.value ||
|
|
@@ -485,7 +536,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
485
536
|
conditions: [
|
|
486
537
|
{ kind: 'version', key: rowKey, expected: aggregateRead.value.version },
|
|
487
538
|
versionCondition(targetDescriptorKey, descriptorRead),
|
|
488
|
-
|
|
539
|
+
leaseValueCondition(targetLeaseKey, request.targetOwner),
|
|
489
540
|
conditionFor(targetCapacityKey, targetCapacityRead)
|
|
490
541
|
],
|
|
491
542
|
mutations: [
|
|
@@ -524,162 +575,162 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
524
575
|
}
|
|
525
576
|
async commitAggregate(fence, signal) {
|
|
526
577
|
validateAggregateFence(fence);
|
|
527
|
-
return await this.commitAggregateCore(fence,
|
|
578
|
+
return await this.commitAggregateCore(fence, signal);
|
|
528
579
|
}
|
|
529
|
-
async commitAggregateCore(fence,
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if (aggregate.state === 'aborted' || aggregate.state === 'staging') {
|
|
536
|
-
return { kind: 'stale' };
|
|
537
|
-
}
|
|
538
|
-
if (aggregate.state === 'committed') {
|
|
539
|
-
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
540
|
-
return { kind: 'alreadyCommitted' };
|
|
541
|
-
}
|
|
542
|
-
const entries = await this.aggregateInventory.read(fence, Buffer.from(aggregate.inventoryDigest), signal);
|
|
543
|
-
if (entries.length !== aggregate.participantCount) {
|
|
544
|
-
throw new Error('Aggregate inventory count differs from its authority record.');
|
|
545
|
-
}
|
|
546
|
-
const authorityRows = [];
|
|
547
|
-
for (let index = 0; index < entries.length; index++) {
|
|
548
|
-
const entry = entries[index];
|
|
549
|
-
const rowKeyForParticipant = authorityKey(entry.authorityKey);
|
|
550
|
-
const current = await this.provider.read(rowKeyForParticipant, signal);
|
|
551
|
-
if (current.kind === 'missing')
|
|
580
|
+
async commitAggregateCore(fence, signal) {
|
|
581
|
+
for (;;) {
|
|
582
|
+
signal?.throwIfAborted();
|
|
583
|
+
const rowKey = aggregateKey(fence);
|
|
584
|
+
let aggregateRead = await this.provider.read(rowKey, signal);
|
|
585
|
+
if (aggregateRead.kind === 'missing')
|
|
552
586
|
return { kind: 'stale' };
|
|
553
|
-
|
|
554
|
-
if (
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
587
|
+
let aggregate = decodeJson(aggregateRead.value.bytes);
|
|
588
|
+
if (aggregate.state === 'aborted' || aggregate.state === 'staging') {
|
|
589
|
+
return { kind: 'stale' };
|
|
590
|
+
}
|
|
591
|
+
if (aggregate.state === 'committed') {
|
|
592
|
+
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
593
|
+
return { kind: 'alreadyCommitted' };
|
|
594
|
+
}
|
|
595
|
+
const entries = await this.aggregateInventory.read(fence, Buffer.from(aggregate.inventoryDigest), signal);
|
|
596
|
+
if (entries.length !== aggregate.participantCount) {
|
|
597
|
+
throw new Error('Aggregate inventory count differs from its authority record.');
|
|
598
|
+
}
|
|
599
|
+
const authorityRows = [];
|
|
600
|
+
for (let index = 0; index < entries.length; index++) {
|
|
601
|
+
const entry = entries[index];
|
|
602
|
+
const rowKeyForParticipant = authorityKey(entry.authorityKey);
|
|
603
|
+
const current = await this.provider.read(rowKeyForParticipant, signal);
|
|
604
|
+
if (current.kind === 'missing')
|
|
605
|
+
return { kind: 'stale' };
|
|
606
|
+
const record = decodeAuthorityRecord(current.value.bytes);
|
|
607
|
+
if (!sameAggregateMarkerEntry(record.aggregate, fence, index, entry)) {
|
|
608
|
+
// A competing committer may already have published the aggregate and
|
|
609
|
+
// normalized this participant before this reader reached it. The
|
|
610
|
+
// committed aggregate is the terminal outcome to adopt, not a stale
|
|
611
|
+
// failure caused by observing the post-normalization row.
|
|
612
|
+
const latest = await this.provider.read(rowKey, signal);
|
|
613
|
+
if (latest.kind === 'found') {
|
|
614
|
+
const latestAggregate = decodeJson(latest.value.bytes);
|
|
615
|
+
if (latestAggregate.state === 'committed') {
|
|
616
|
+
await this.normalizeCommittedAggregate(fence, latestAggregate, signal);
|
|
617
|
+
return { kind: 'alreadyCommitted' };
|
|
618
|
+
}
|
|
565
619
|
}
|
|
620
|
+
return { kind: 'stale' };
|
|
566
621
|
}
|
|
567
|
-
|
|
622
|
+
const [payload, membership] = await Promise.all([
|
|
623
|
+
requireProviderBytes(this.provider, aggregateParticipantPayloadKey(fence, index), signal),
|
|
624
|
+
requireProviderBytes(this.provider, aggregateParticipantMembershipKey(fence, index), signal)
|
|
625
|
+
]);
|
|
626
|
+
if (sha256Hex(payload) !== entry.authorityPayloadSha256 ||
|
|
627
|
+
sha256Hex(membership) !== entry.membershipMutationSha256) {
|
|
628
|
+
throw new Error('Aggregate participant staging checksum does not match inventory.');
|
|
629
|
+
}
|
|
630
|
+
authorityRows.push({ key: rowKeyForParticipant, current, record, entry });
|
|
568
631
|
}
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
632
|
+
const targetDescriptorKey = meshKey(aggregate.targetDescriptor.meshName, aggregate.targetDescriptor.rid);
|
|
633
|
+
const targetLeaseKey = ownerKey(aggregate.targetOwner.ownerId);
|
|
634
|
+
const targetCapacityKey = capacityKey(aggregate.targetDescriptor.meshName, String(aggregate.targetDescriptor.rid));
|
|
635
|
+
const [descriptorRead, leaseRead] = await Promise.all([
|
|
636
|
+
this.provider.read(targetDescriptorKey, signal),
|
|
637
|
+
this.provider.read(targetLeaseKey, signal)
|
|
572
638
|
]);
|
|
573
|
-
if (
|
|
574
|
-
|
|
575
|
-
|
|
639
|
+
if (liveTargetDescriptor(descriptorRead, leaseRead, aggregateTargetFromRecord(aggregate)) ===
|
|
640
|
+
undefined) {
|
|
641
|
+
return { kind: 'stale' };
|
|
576
642
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
643
|
+
const capacityDeltas = new Map();
|
|
644
|
+
for (const row of authorityRows) {
|
|
645
|
+
if (row.entry.ownerTransition !== 'newOwner')
|
|
646
|
+
continue;
|
|
647
|
+
const key = capacityKey(row.record.snapshot.allocation.descriptor.meshName, String(row.record.snapshot.allocation.descriptor.rid)).value;
|
|
648
|
+
capacityDeltas.set(key, addCapacityVector(capacityDeltas.get(key) ?? { actors: 0, spots: 0 }, row.record.snapshot.allocation.capacity));
|
|
649
|
+
}
|
|
650
|
+
const capacityKeys = new Map();
|
|
651
|
+
capacityKeys.set(targetCapacityKey.value, targetCapacityKey);
|
|
652
|
+
for (const value of capacityDeltas.keys())
|
|
653
|
+
capacityKeys.set(value, (0, in_memory_provider_location_store_1.storeKey)(value));
|
|
654
|
+
const capacityReads = new Map();
|
|
655
|
+
for (const [value, key] of capacityKeys) {
|
|
656
|
+
const read = await this.provider.read(key, signal);
|
|
657
|
+
if (read.kind === 'missing') {
|
|
658
|
+
// Capacity rows are provider-private. A foreign source legitimately
|
|
659
|
+
// has no row under this provider's key encoding; its source runtime
|
|
660
|
+
// releases that capacity after observing the committed authority.
|
|
661
|
+
// The target row remains mandatory because this provider reserved it
|
|
662
|
+
// during prepare and must consume it atomically with commit.
|
|
663
|
+
if (value === targetCapacityKey.value)
|
|
664
|
+
return { kind: 'stale' };
|
|
665
|
+
capacityKeys.delete(value);
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
capacityReads.set(value, read);
|
|
669
|
+
}
|
|
670
|
+
const capacityMutations = [];
|
|
671
|
+
for (const [value, key] of capacityKeys) {
|
|
672
|
+
const read = capacityReads.get(value);
|
|
673
|
+
let capacity = decodeJson(read.value.bytes);
|
|
674
|
+
const sourceDelta = capacityDeltas.get(value);
|
|
675
|
+
if (sourceDelta !== undefined) {
|
|
676
|
+
capacity = {
|
|
677
|
+
active: subtractCapacity(capacity.active, sourceDelta),
|
|
678
|
+
pending: capacity.pending
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
if (value === targetCapacityKey.value) {
|
|
682
|
+
capacity = {
|
|
683
|
+
active: addCapacity(capacity.active, aggregate.capacity),
|
|
684
|
+
pending: subtractCapacity(capacity.pending, aggregate.capacity)
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
capacityMutations.push({
|
|
688
|
+
kind: 'put',
|
|
689
|
+
key,
|
|
690
|
+
bytes: encodeJson(capacity)
|
|
691
|
+
});
|
|
614
692
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
693
|
+
const published = await this.provider.write({
|
|
694
|
+
conditions: [
|
|
695
|
+
{ kind: 'version', key: rowKey, expected: aggregateRead.value.version },
|
|
696
|
+
versionCondition(targetDescriptorKey, descriptorRead),
|
|
697
|
+
leaseValueCondition(targetLeaseKey, aggregate.targetOwner),
|
|
698
|
+
...[...capacityReads.entries()].map(([value, read]) => ({
|
|
699
|
+
kind: 'version',
|
|
700
|
+
key: capacityKeys.get(value),
|
|
701
|
+
expected: read.value.version
|
|
702
|
+
}))
|
|
703
|
+
],
|
|
704
|
+
mutations: [
|
|
705
|
+
{
|
|
706
|
+
kind: 'put',
|
|
707
|
+
key: rowKey,
|
|
708
|
+
bytes: encodeJson({ ...aggregate, state: 'committed' })
|
|
709
|
+
},
|
|
710
|
+
...capacityMutations
|
|
711
|
+
]
|
|
712
|
+
}, signal);
|
|
713
|
+
if (published.kind === 'conflict') {
|
|
714
|
+
aggregateRead = await this.provider.read(rowKey, signal);
|
|
715
|
+
if (aggregateRead.kind === 'missing')
|
|
716
|
+
return { kind: 'stale' };
|
|
717
|
+
aggregate = decodeJson(aggregateRead.value.bytes);
|
|
718
|
+
if (aggregate.state === 'prepared') {
|
|
719
|
+
// The commit CAS also fences the target's live owner lease, descriptor,
|
|
720
|
+
// and capacity rows. Re-read the whole prepared fence after an
|
|
721
|
+
// auxiliary-row race; a changed aggregate or participant fence exits
|
|
722
|
+
// through the normal stale checks on the next attempt.
|
|
723
|
+
continue;
|
|
724
|
+
}
|
|
725
|
+
if (aggregate.state !== 'committed')
|
|
726
|
+
return { kind: 'stale' };
|
|
627
727
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
active: addCapacity(capacity.active, aggregate.capacity),
|
|
631
|
-
pending: subtractCapacity(capacity.pending, aggregate.capacity)
|
|
632
|
-
};
|
|
728
|
+
else {
|
|
729
|
+
aggregate = { ...aggregate, state: 'committed' };
|
|
633
730
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
key,
|
|
637
|
-
bytes: encodeJson(capacity)
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
const published = await this.provider.write({
|
|
641
|
-
conditions: [
|
|
642
|
-
{ kind: 'version', key: rowKey, expected: aggregateRead.value.version },
|
|
643
|
-
versionCondition(targetDescriptorKey, descriptorRead),
|
|
644
|
-
versionCondition(targetLeaseKey, leaseRead),
|
|
645
|
-
...[...capacityReads.entries()].map(([value, read]) => ({
|
|
646
|
-
kind: 'version',
|
|
647
|
-
key: capacityKeys.get(value),
|
|
648
|
-
expected: read.value.version
|
|
649
|
-
}))
|
|
650
|
-
],
|
|
651
|
-
mutations: [
|
|
652
|
-
{
|
|
653
|
-
kind: 'put',
|
|
654
|
-
key: rowKey,
|
|
655
|
-
bytes: encodeJson({ ...aggregate, state: 'committed' })
|
|
656
|
-
},
|
|
657
|
-
...capacityMutations
|
|
658
|
-
]
|
|
659
|
-
}, signal);
|
|
660
|
-
if (published.kind === 'conflict') {
|
|
661
|
-
aggregateRead = await this.provider.read(rowKey, signal);
|
|
662
|
-
if (aggregateRead.kind === 'missing')
|
|
663
|
-
return { kind: 'stale' };
|
|
664
|
-
aggregate = decodeJson(aggregateRead.value.bytes);
|
|
665
|
-
if (aggregate.state === 'prepared' &&
|
|
666
|
-
retryAttempt < MAX_AGGREGATE_COMMIT_CONFLICT_RETRIES &&
|
|
667
|
-
performance.now() < retryDeadlineAtMs) {
|
|
668
|
-
// The commit CAS also fences the target's live owner lease, descriptor,
|
|
669
|
-
// and capacity rows. Re-read the whole prepared fence after an
|
|
670
|
-
// auxiliary-row race; a changed aggregate or participant fence exits
|
|
671
|
-
// through the normal stale checks on the next attempt.
|
|
672
|
-
await waitForAggregateCommitRetry(retryAttempt, retryDeadlineAtMs, signal);
|
|
673
|
-
return await this.commitAggregateCore(fence, retryAttempt + 1, retryDeadlineAtMs, signal);
|
|
674
|
-
}
|
|
675
|
-
if (aggregate.state !== 'committed')
|
|
676
|
-
return { kind: 'stale' };
|
|
677
|
-
}
|
|
678
|
-
else {
|
|
679
|
-
aggregate = { ...aggregate, state: 'committed' };
|
|
731
|
+
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
732
|
+
return { kind: 'committed' };
|
|
680
733
|
}
|
|
681
|
-
await this.normalizeCommittedAggregate(fence, aggregate, signal);
|
|
682
|
-
return { kind: 'committed' };
|
|
683
734
|
}
|
|
684
735
|
async abortAggregate(fence, signal) {
|
|
685
736
|
validateAggregateFence(fence);
|
|
@@ -736,22 +787,16 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
736
787
|
return { kind: 'aborted' };
|
|
737
788
|
}
|
|
738
789
|
}
|
|
739
|
-
async reserve(request, signal) {
|
|
790
|
+
async reserve(request, signal, deadlineUnixMs) {
|
|
740
791
|
const encodedAuthorityKey = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
792
|
+
const reservationId = (0, node_crypto_1.randomUUID)();
|
|
741
793
|
for (;;) {
|
|
742
|
-
signal
|
|
794
|
+
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
743
795
|
const rowKey = authorityKey(encodedAuthorityKey.value);
|
|
744
796
|
const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
|
|
745
797
|
const leaseKey = ownerKey(request.target.owner.ownerId);
|
|
746
798
|
const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
|
|
747
|
-
const
|
|
748
|
-
this.provider.read(rowKey, signal),
|
|
749
|
-
this.provider.read(descriptorKey, signal),
|
|
750
|
-
this.provider.read(leaseKey, signal),
|
|
751
|
-
this.provider.read(capacityRowKey, signal),
|
|
752
|
-
this.provider.read(OBJECT_COUNTER_KEY, signal),
|
|
753
|
-
this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
|
|
754
|
-
]);
|
|
799
|
+
const current = await this.provider.read(rowKey, signal);
|
|
755
800
|
if (current.kind === 'found') {
|
|
756
801
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
757
802
|
const snapshot = authoritySnapshot(record.snapshot, current.value.version, current.value.storeNow);
|
|
@@ -809,10 +854,19 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
809
854
|
}, signal);
|
|
810
855
|
continue;
|
|
811
856
|
}
|
|
857
|
+
const [descriptorRead, leaseRead] = await Promise.all([
|
|
858
|
+
this.provider.read(descriptorKey, signal),
|
|
859
|
+
this.provider.read(leaseKey, signal)
|
|
860
|
+
]);
|
|
812
861
|
const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
|
|
813
862
|
if (descriptor === undefined) {
|
|
814
863
|
return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
|
|
815
864
|
}
|
|
865
|
+
const [capacityRead, objectGenerationRead, authorityOwnerGenerationRead] = await Promise.all([
|
|
866
|
+
this.provider.read(capacityRowKey, signal),
|
|
867
|
+
this.provider.read(OBJECT_COUNTER_KEY, signal),
|
|
868
|
+
this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
|
|
869
|
+
]);
|
|
816
870
|
const capacity = capacityRead.kind === 'missing'
|
|
817
871
|
? emptyCapacityRecord()
|
|
818
872
|
: decodeJson(capacityRead.value.bytes);
|
|
@@ -827,7 +881,6 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
827
881
|
if (generation >= MAX_GENERATION || authorityOwnerGeneration >= MAX_GENERATION) {
|
|
828
882
|
return { kind: 'generationExhausted' };
|
|
829
883
|
}
|
|
830
|
-
const reservationId = (0, node_crypto_1.randomUUID)();
|
|
831
884
|
const allocation = {
|
|
832
885
|
state: 'reserved',
|
|
833
886
|
objectKind: request.key.kind,
|
|
@@ -859,7 +912,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
859
912
|
conditions: [
|
|
860
913
|
{ kind: 'missing', key: rowKey },
|
|
861
914
|
versionCondition(descriptorKey, descriptorRead),
|
|
862
|
-
|
|
915
|
+
leaseValueCondition(leaseKey, request.target.owner),
|
|
863
916
|
conditionFor(capacityRowKey, capacityRead),
|
|
864
917
|
conditionFor(OBJECT_COUNTER_KEY, objectGenerationRead),
|
|
865
918
|
conditionFor(AUTHORITY_OWNER_COUNTER_KEY, authorityOwnerGenerationRead)
|
|
@@ -898,11 +951,11 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
898
951
|
};
|
|
899
952
|
}
|
|
900
953
|
}
|
|
901
|
-
async commit(request, signal) {
|
|
954
|
+
async commit(request, signal, deadlineUnixMs) {
|
|
902
955
|
const key = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
903
956
|
const rowKey = authorityKey(key.value);
|
|
904
957
|
for (;;) {
|
|
905
|
-
signal
|
|
958
|
+
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
906
959
|
const current = await this.provider.read(rowKey, signal);
|
|
907
960
|
if (current.kind === 'missing')
|
|
908
961
|
return { kind: 'stale' };
|
|
@@ -948,7 +1001,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
948
1001
|
conditions: [
|
|
949
1002
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
950
1003
|
versionCondition(descriptorKey, descriptorRead),
|
|
951
|
-
|
|
1004
|
+
leaseValueCondition(leaseKey, request.target.owner),
|
|
952
1005
|
conditionFor(capacityRowKey, capacityRead)
|
|
953
1006
|
],
|
|
954
1007
|
mutations: [
|
|
@@ -974,11 +1027,11 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
974
1027
|
};
|
|
975
1028
|
}
|
|
976
1029
|
}
|
|
977
|
-
async abort(request, signal) {
|
|
1030
|
+
async abort(request, signal, deadlineUnixMs) {
|
|
978
1031
|
const key = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
979
1032
|
const rowKey = authorityKey(key.value);
|
|
980
1033
|
for (;;) {
|
|
981
|
-
signal
|
|
1034
|
+
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
982
1035
|
const current = await this.provider.read(rowKey, signal);
|
|
983
1036
|
if (current.kind === 'missing')
|
|
984
1037
|
return { kind: 'stale' };
|
|
@@ -1009,7 +1062,10 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1009
1062
|
const result = await this.provider.write({
|
|
1010
1063
|
conditions: [
|
|
1011
1064
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1012
|
-
|
|
1065
|
+
leaseValueCondition(leaseKey, {
|
|
1066
|
+
ownerId: record.snapshot.ownerId,
|
|
1067
|
+
leaseGeneration: record.snapshot.ownerLeaseGeneration
|
|
1068
|
+
}),
|
|
1013
1069
|
conditionFor(capacityRowKey, capacityRead)
|
|
1014
1070
|
],
|
|
1015
1071
|
mutations: [
|
|
@@ -1037,17 +1093,15 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1037
1093
|
const rowKey = authorityKey((0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId).value);
|
|
1038
1094
|
const terminalRowKey = creationTerminalKey(terminal.operation);
|
|
1039
1095
|
for (;;) {
|
|
1040
|
-
signal
|
|
1041
|
-
const
|
|
1042
|
-
this.provider.read(rowKey, signal),
|
|
1043
|
-
this.provider.read(terminalRowKey, signal)
|
|
1044
|
-
]);
|
|
1096
|
+
throwIfOperationExpired(signal, BigInt(request.completion.terminal.operationDeadline.getTime()));
|
|
1097
|
+
const existingTerminal = await this.provider.read(terminalRowKey, signal);
|
|
1045
1098
|
if (existingTerminal.kind === 'found') {
|
|
1046
1099
|
return {
|
|
1047
1100
|
kind: 'alreadyCompleted',
|
|
1048
1101
|
terminal: retainedCreationTerminal(terminal.operation, existingTerminal.value.bytes, existingTerminal.value.expiresAt, existingTerminal.value.storeNow)
|
|
1049
1102
|
};
|
|
1050
1103
|
}
|
|
1104
|
+
const current = await this.provider.read(rowKey, signal);
|
|
1051
1105
|
if (current.kind === 'missing')
|
|
1052
1106
|
return { kind: 'stale' };
|
|
1053
1107
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
@@ -1060,14 +1114,14 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1060
1114
|
const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
|
|
1061
1115
|
const leaseKey = ownerKey(request.target.owner.ownerId);
|
|
1062
1116
|
const capacityRowKey = capacityKey(request.target.meshName, request.target.nodeRid);
|
|
1063
|
-
const [descriptorRead, leaseRead
|
|
1117
|
+
const [descriptorRead, leaseRead] = await Promise.all([
|
|
1064
1118
|
this.provider.read(descriptorKey, signal),
|
|
1065
|
-
this.provider.read(leaseKey, signal)
|
|
1066
|
-
this.provider.read(capacityRowKey, signal)
|
|
1119
|
+
this.provider.read(leaseKey, signal)
|
|
1067
1120
|
]);
|
|
1068
1121
|
if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined) {
|
|
1069
1122
|
return { kind: 'stale' };
|
|
1070
1123
|
}
|
|
1124
|
+
const capacityRead = await this.provider.read(capacityRowKey, signal);
|
|
1071
1125
|
const capacity = capacityRead.kind === 'missing'
|
|
1072
1126
|
? emptyCapacityRecord()
|
|
1073
1127
|
: decodeJson(capacityRead.value.bytes);
|
|
@@ -1119,7 +1173,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1119
1173
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1120
1174
|
{ kind: 'missing', key: terminalRowKey },
|
|
1121
1175
|
versionCondition(descriptorKey, descriptorRead),
|
|
1122
|
-
|
|
1176
|
+
leaseValueCondition(leaseKey, request.target.owner),
|
|
1123
1177
|
conditionFor(capacityRowKey, capacityRead)
|
|
1124
1178
|
],
|
|
1125
1179
|
mutations: [
|
|
@@ -1300,7 +1354,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1300
1354
|
cursor: page.continuationToken === undefined
|
|
1301
1355
|
? undefined
|
|
1302
1356
|
: { value: page.continuationToken },
|
|
1303
|
-
limit: page.pageSize ??
|
|
1357
|
+
limit: page.pageSize ?? Options_1.zlinkRuntimeDefaultLocationOptions.listPageSize
|
|
1304
1358
|
}, signal);
|
|
1305
1359
|
if (result.kind === 'expired') {
|
|
1306
1360
|
throw new Error('Location Store scan snapshot expired.');
|
|
@@ -1688,20 +1742,16 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1688
1742
|
else if (intent === 2) {
|
|
1689
1743
|
return rejected(lease.value.storeNow);
|
|
1690
1744
|
}
|
|
1691
|
-
return this.writeDescriptorWithReconciliation(leaseKey, descriptor.ownerId, descriptor.leaseGeneration,
|
|
1745
|
+
return this.writeDescriptorWithReconciliation(leaseKey, descriptor.ownerId, descriptor.leaseGeneration, rowKey, current, encodeCanonicalDescriptorRecord(generation, descriptor), generation, signal);
|
|
1692
1746
|
}
|
|
1693
|
-
async writeDescriptorWithReconciliation(leaseKey, ownerId, leaseGeneration,
|
|
1694
|
-
let currentLease = liveLease;
|
|
1747
|
+
async writeDescriptorWithReconciliation(leaseKey, ownerId, leaseGeneration, rowKey, predecessor, encodedDescriptor, generation, signal) {
|
|
1695
1748
|
let currentRow = predecessor;
|
|
1696
1749
|
for (let attempt = 0; attempt <= MAX_DESCRIPTOR_WRITE_RETRIES; attempt += 1) {
|
|
1697
1750
|
const rowCondition = currentRow.kind === 'found'
|
|
1698
1751
|
? { kind: 'version', key: rowKey, expected: currentRow.value.version }
|
|
1699
1752
|
: { kind: 'missing', key: rowKey };
|
|
1700
1753
|
const result = await this.provider.write({
|
|
1701
|
-
conditions: [
|
|
1702
|
-
{ kind: 'version', key: leaseKey, expected: currentLease.value.version },
|
|
1703
|
-
rowCondition
|
|
1704
|
-
],
|
|
1754
|
+
conditions: [leaseValueCondition(leaseKey, { ownerId, leaseGeneration }), rowCondition],
|
|
1705
1755
|
mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
|
|
1706
1756
|
}, signal);
|
|
1707
1757
|
if (result.kind === 'applied') {
|
|
@@ -1718,7 +1768,6 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1718
1768
|
!sameDescriptorPredecessor(predecessor, refreshedRow)) {
|
|
1719
1769
|
return ignoredStale(result.storeNow);
|
|
1720
1770
|
}
|
|
1721
|
-
currentLease = refreshedLease;
|
|
1722
1771
|
currentRow = refreshedRow;
|
|
1723
1772
|
}
|
|
1724
1773
|
throw new Error('Descriptor write retry loop exhausted unexpectedly.');
|
|
@@ -1744,7 +1793,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1744
1793
|
cursor: page.continuationToken === undefined
|
|
1745
1794
|
? undefined
|
|
1746
1795
|
: { value: page.continuationToken },
|
|
1747
|
-
limit: page.pageSize ??
|
|
1796
|
+
limit: page.pageSize ?? Options_1.zlinkRuntimeDefaultLocationOptions.listPageSize
|
|
1748
1797
|
}, signal);
|
|
1749
1798
|
if (result.kind === 'expired') {
|
|
1750
1799
|
throw new Error('Location Store scan snapshot expired.');
|
|
@@ -1801,7 +1850,10 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1801
1850
|
}
|
|
1802
1851
|
const result = await this.provider.write({
|
|
1803
1852
|
conditions: [
|
|
1804
|
-
|
|
1853
|
+
leaseValueCondition(leaseKey, {
|
|
1854
|
+
ownerId: location.ownerId,
|
|
1855
|
+
leaseGeneration: locationOwnerGeneration(location)
|
|
1856
|
+
}),
|
|
1805
1857
|
rowCondition
|
|
1806
1858
|
],
|
|
1807
1859
|
mutations: [
|
|
@@ -1842,7 +1894,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1842
1894
|
: decodeJson(result.value.bytes).descriptor;
|
|
1843
1895
|
}
|
|
1844
1896
|
async listOwnedLocations(prefix, page, revive, matches, signal) {
|
|
1845
|
-
const requested = page.pageSize ??
|
|
1897
|
+
const requested = page.pageSize ?? Options_1.zlinkRuntimeDefaultLocationOptions.listPageSize;
|
|
1846
1898
|
let cursor = page.continuationToken === undefined
|
|
1847
1899
|
? undefined
|
|
1848
1900
|
: { value: page.continuationToken };
|
|
@@ -1913,7 +1965,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1913
1965
|
}
|
|
1914
1966
|
async normalizeCommittedAggregate(fence, aggregate, signal) {
|
|
1915
1967
|
const entries = await this.aggregateInventory.read(fence, Buffer.from(aggregate.inventoryDigest), signal);
|
|
1916
|
-
await parallelForEach(entries,
|
|
1968
|
+
await parallelForEach(entries, LOCATION_STORE_WRITE_CONCURRENCY, async (entry, index) => {
|
|
1917
1969
|
const rowKey = authorityKey(entry.authorityKey);
|
|
1918
1970
|
for (;;) {
|
|
1919
1971
|
const current = await this.provider.read(rowKey, signal);
|
|
@@ -1980,8 +2032,8 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1980
2032
|
});
|
|
1981
2033
|
}
|
|
1982
2034
|
async putImmutable(key, bytes, signal) {
|
|
1983
|
-
if (bytes.byteLength >
|
|
1984
|
-
throw new RangeError(
|
|
2035
|
+
if (bytes.byteLength > Stores_1.ZLINK_PROVIDER_MAX_VALUE_BYTES) {
|
|
2036
|
+
throw new RangeError(`Aggregate participant staging value exceeds ${Stores_1.ZLINK_PROVIDER_MAX_VALUE_BYTES / (1024 * 1024)} MiB.`);
|
|
1985
2037
|
}
|
|
1986
2038
|
const result = await this.provider.write({
|
|
1987
2039
|
conditions: [{ kind: 'missing', key }],
|
|
@@ -2024,7 +2076,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
2024
2076
|
}
|
|
2025
2077
|
}
|
|
2026
2078
|
async clearAggregateMarkers(fence, installed, signal) {
|
|
2027
|
-
await parallelForEach(installed,
|
|
2079
|
+
await parallelForEach(installed, LOCATION_STORE_WRITE_CONCURRENCY, async (value) => {
|
|
2028
2080
|
await this.clearAggregateMarker(fence, value.key, signal);
|
|
2029
2081
|
});
|
|
2030
2082
|
}
|
|
@@ -2045,7 +2097,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
2045
2097
|
return (record.aggregate?.aggregateId === fence.aggregateId.value &&
|
|
2046
2098
|
record.aggregate.aggregateGeneration === fence.aggregateGeneration);
|
|
2047
2099
|
});
|
|
2048
|
-
await parallelForEach(matching,
|
|
2100
|
+
await parallelForEach(matching, LOCATION_STORE_WRITE_CONCURRENCY, async (item) => {
|
|
2049
2101
|
await this.clearAggregateMarker(fence, item.key, signal);
|
|
2050
2102
|
});
|
|
2051
2103
|
if (result.value.nextCursor === undefined)
|
|
@@ -2083,85 +2135,13 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
2083
2135
|
}
|
|
2084
2136
|
}
|
|
2085
2137
|
exports.ZLinkLocationStoreRepository = ZLinkLocationStoreRepository;
|
|
2086
|
-
const AMBIGUOUS_WRITE_RECONCILIATION_TIMEOUT_MS = 5_000;
|
|
2087
|
-
/**
|
|
2088
|
-
* Keeps provider failures private while preserving the opaque Store contract.
|
|
2089
|
-
*
|
|
2090
|
-
* A write response can be lost after the provider applied the atomic batch.
|
|
2091
|
-
* The Framework confirms every mutation by an independent exact read. A put
|
|
2092
|
-
* must retain the requested bytes and a version different from the conditioned
|
|
2093
|
-
* version; a delete must remain absent. Any mismatch is a normal conflict, so
|
|
2094
|
-
* the domain repository can reread its authoritative record and classify the
|
|
2095
|
-
* operation without exposing a provider-specific retry API.
|
|
2096
|
-
*/
|
|
2097
|
-
class AmbiguousWriteReconcilingLocationStore {
|
|
2098
|
-
inner;
|
|
2099
|
-
constructor(inner) {
|
|
2100
|
-
this.inner = inner;
|
|
2101
|
-
}
|
|
2102
|
-
read(key, signal) {
|
|
2103
|
-
return this.inner.read(key, signal);
|
|
2104
|
-
}
|
|
2105
|
-
scan(request, signal) {
|
|
2106
|
-
return this.inner.scan(request, signal);
|
|
2107
|
-
}
|
|
2108
|
-
async write(request, signal) {
|
|
2109
|
-
try {
|
|
2110
|
-
return await this.inner.write(request, signal);
|
|
2111
|
-
}
|
|
2112
|
-
catch (failure) {
|
|
2113
|
-
try {
|
|
2114
|
-
return await this.reconcile(request);
|
|
2115
|
-
}
|
|
2116
|
-
catch {
|
|
2117
|
-
throw failure;
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
}
|
|
2121
|
-
async reconcile(request) {
|
|
2122
|
-
if (request.mutations.length === 0) {
|
|
2123
|
-
throw new Error('Cannot reconcile an opaque Store write without mutations.');
|
|
2124
|
-
}
|
|
2125
|
-
const reconciliationSignal = AbortSignal.timeout(AMBIGUOUS_WRITE_RECONCILIATION_TIMEOUT_MS);
|
|
2126
|
-
const reads = await Promise.all(request.mutations.map((mutation) => this.inner.read(mutation.key, reconciliationSignal)));
|
|
2127
|
-
const putVersions = [];
|
|
2128
|
-
let storeNow = new Date(0);
|
|
2129
|
-
for (let index = 0; index < request.mutations.length; index += 1) {
|
|
2130
|
-
const mutation = request.mutations[index];
|
|
2131
|
-
const read = reads[index];
|
|
2132
|
-
storeNow =
|
|
2133
|
-
read.kind === 'found'
|
|
2134
|
-
? latestDate(storeNow, read.value.storeNow)
|
|
2135
|
-
: latestDate(storeNow, read.storeNow);
|
|
2136
|
-
if (mutation.kind === 'delete') {
|
|
2137
|
-
if (read.kind !== 'missing')
|
|
2138
|
-
return { kind: 'conflict', storeNow };
|
|
2139
|
-
continue;
|
|
2140
|
-
}
|
|
2141
|
-
if (read.kind !== 'found' ||
|
|
2142
|
-
!Buffer.from(read.value.bytes).equals(Buffer.from(mutation.bytes)) ||
|
|
2143
|
-
!versionAdvanced(request.conditions, mutation.key, read.value.version)) {
|
|
2144
|
-
return { kind: 'conflict', storeNow };
|
|
2145
|
-
}
|
|
2146
|
-
putVersions.push({ key: mutation.key, version: read.value.version });
|
|
2147
|
-
}
|
|
2148
|
-
return { kind: 'applied', putVersions, storeNow };
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
function versionAdvanced(conditions, key, current) {
|
|
2152
|
-
const condition = conditions.find((candidate) => candidate.key.value === key.value);
|
|
2153
|
-
return condition?.kind !== 'version' || condition.expected.value !== current.value;
|
|
2154
|
-
}
|
|
2155
|
-
function latestDate(left, right) {
|
|
2156
|
-
return left.getTime() >= right.getTime() ? left : right;
|
|
2157
|
-
}
|
|
2158
2138
|
function validateProviderAggregateRequest(request) {
|
|
2159
2139
|
requireText(request.aggregateId.value, 'aggregate ID');
|
|
2160
2140
|
if (request.aggregateGeneration < 1n || request.participants.length < 1) {
|
|
2161
2141
|
throw new RangeError('Aggregate generation and participant count are invalid.');
|
|
2162
2142
|
}
|
|
2163
|
-
if (request.inventoryDigest.byteLength !==
|
|
2164
|
-
throw new TypeError(
|
|
2143
|
+
if (request.inventoryDigest.byteLength !== actor_join_recovery_codec_1.SHA256_DIGEST_BYTES) {
|
|
2144
|
+
throw new TypeError(`Aggregate inventory digest must contain ${actor_join_recovery_codec_1.SHA256_DIGEST_BYTES} bytes.`);
|
|
2165
2145
|
}
|
|
2166
2146
|
const keys = request.participants.map((value) => value.authorityKey.value);
|
|
2167
2147
|
if (new Set(keys).size !== keys.length ||
|
|
@@ -2171,9 +2151,9 @@ function validateProviderAggregateRequest(request) {
|
|
|
2171
2151
|
for (const participant of request.participants) {
|
|
2172
2152
|
requireText(participant.authorityKey.value, 'aggregate authority key');
|
|
2173
2153
|
requireText(participant.expectedStoreVersion.value, 'aggregate expected Store version');
|
|
2174
|
-
if (participant.authorityPayload.byteLength >
|
|
2175
|
-
participant.membershipMutation.byteLength >
|
|
2176
|
-
throw new RangeError(
|
|
2154
|
+
if (participant.authorityPayload.byteLength > Stores_1.ZLINK_PROVIDER_MAX_VALUE_BYTES ||
|
|
2155
|
+
participant.membershipMutation.byteLength > Stores_1.ZLINK_PROVIDER_MAX_VALUE_BYTES) {
|
|
2156
|
+
throw new RangeError(`Aggregate participant value exceeds ${Stores_1.ZLINK_PROVIDER_MAX_VALUE_BYTES / (1024 * 1024)} MiB.`);
|
|
2177
2157
|
}
|
|
2178
2158
|
}
|
|
2179
2159
|
}
|
|
@@ -2275,27 +2255,6 @@ async function parallelForEach(values, concurrency, operation) {
|
|
|
2275
2255
|
}
|
|
2276
2256
|
}));
|
|
2277
2257
|
}
|
|
2278
|
-
async function waitForAggregateCommitRetry(retryAttempt, deadlineAtMs, signal) {
|
|
2279
|
-
signal?.throwIfAborted();
|
|
2280
|
-
const remainingMs = deadlineAtMs - performance.now();
|
|
2281
|
-
if (remainingMs <= 0)
|
|
2282
|
-
return;
|
|
2283
|
-
const exponentialMs = Math.min(100, 2 << Math.min(retryAttempt, 5));
|
|
2284
|
-
const delayMs = Math.min(remainingMs, exponentialMs + Math.floor(Math.random() * (exponentialMs + 1)));
|
|
2285
|
-
await new Promise((resolve, reject) => {
|
|
2286
|
-
let timer;
|
|
2287
|
-
const aborted = () => {
|
|
2288
|
-
if (timer !== undefined)
|
|
2289
|
-
clearTimeout(timer);
|
|
2290
|
-
reject(signal?.reason ?? new Error('Aggregate commit was aborted.'));
|
|
2291
|
-
};
|
|
2292
|
-
signal?.addEventListener('abort', aborted, { once: true });
|
|
2293
|
-
timer = setTimeout(() => {
|
|
2294
|
-
signal?.removeEventListener('abort', aborted);
|
|
2295
|
-
resolve();
|
|
2296
|
-
}, delayMs);
|
|
2297
|
-
});
|
|
2298
|
-
}
|
|
2299
2258
|
function sha256Hex(bytes) {
|
|
2300
2259
|
return (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
|
|
2301
2260
|
}
|
|
@@ -2456,7 +2415,7 @@ function decodeJson(value) {
|
|
|
2456
2415
|
function requireRecordVersion(value, kind) {
|
|
2457
2416
|
if (value === null ||
|
|
2458
2417
|
typeof value !== 'object' ||
|
|
2459
|
-
value.recordVersion !==
|
|
2418
|
+
value.recordVersion !== LOCATION_RECORD_VERSION) {
|
|
2460
2419
|
throw new Error(`Location Store ${kind} record has an unrecognized recordVersion.`);
|
|
2461
2420
|
}
|
|
2462
2421
|
}
|
|
@@ -2474,21 +2433,22 @@ function canonicalize(value) {
|
|
|
2474
2433
|
}
|
|
2475
2434
|
return value;
|
|
2476
2435
|
}
|
|
2436
|
+
const GENERATION_KEYS = new Set([
|
|
2437
|
+
'generation',
|
|
2438
|
+
'leaseGeneration',
|
|
2439
|
+
'ownerLeaseGeneration',
|
|
2440
|
+
'objectGeneration',
|
|
2441
|
+
'authorityOwnerGeneration',
|
|
2442
|
+
'targetAuthorityOwnerGeneration',
|
|
2443
|
+
'aggregateGeneration',
|
|
2444
|
+
'lifecycleGeneration',
|
|
2445
|
+
'descriptorRevision',
|
|
2446
|
+
'nodeGeneration',
|
|
2447
|
+
'applicationVersion',
|
|
2448
|
+
'requestEncodedSize'
|
|
2449
|
+
]);
|
|
2477
2450
|
function reviveCanonical(value, key = '') {
|
|
2478
|
-
|
|
2479
|
-
'generation',
|
|
2480
|
-
'leaseGeneration',
|
|
2481
|
-
'ownerLeaseGeneration',
|
|
2482
|
-
'objectGeneration',
|
|
2483
|
-
'authorityOwnerGeneration',
|
|
2484
|
-
'aggregateGeneration',
|
|
2485
|
-
'lifecycleGeneration',
|
|
2486
|
-
'descriptorRevision',
|
|
2487
|
-
'nodeGeneration',
|
|
2488
|
-
'applicationVersion',
|
|
2489
|
-
'requestEncodedSize'
|
|
2490
|
-
]);
|
|
2491
|
-
if (typeof value === 'string' && generationKeys.has(key))
|
|
2451
|
+
if (typeof value === 'string' && GENERATION_KEYS.has(key))
|
|
2492
2452
|
return BigInt(value);
|
|
2493
2453
|
if (Array.isArray(value))
|
|
2494
2454
|
return value.map((item) => reviveCanonical(item));
|
|
@@ -2504,7 +2464,7 @@ function decodeOwnerRecord(bytes) {
|
|
|
2504
2464
|
}
|
|
2505
2465
|
function encodeOwnerRecord(ownerId, leaseGeneration) {
|
|
2506
2466
|
return encodeJson({
|
|
2507
|
-
recordVersion:
|
|
2467
|
+
recordVersion: LOCATION_RECORD_VERSION,
|
|
2508
2468
|
ownerId,
|
|
2509
2469
|
leaseGeneration: leaseGeneration.toString()
|
|
2510
2470
|
});
|
|
@@ -2515,7 +2475,7 @@ function encodeCanonicalDescriptorRecord(generation, descriptor) {
|
|
|
2515
2475
|
// not serialized (21-location-runtime §2.4).
|
|
2516
2476
|
void generation;
|
|
2517
2477
|
return Buffer.from(JSON.stringify({
|
|
2518
|
-
recordVersion:
|
|
2478
|
+
recordVersion: LOCATION_RECORD_VERSION,
|
|
2519
2479
|
ownerId: descriptor.ownerId,
|
|
2520
2480
|
leaseGeneration: descriptor.leaseGeneration.toString(),
|
|
2521
2481
|
descriptorRevision: descriptor.descriptorRevision.toString(),
|
|
@@ -2525,7 +2485,7 @@ function encodeCanonicalDescriptorRecord(generation, descriptor) {
|
|
|
2525
2485
|
function decodeCanonicalDescriptorRecord(bytes) {
|
|
2526
2486
|
const record = JSON.parse(decodeText(bytes));
|
|
2527
2487
|
requireRecordVersion(record, 'descriptor');
|
|
2528
|
-
return
|
|
2488
|
+
return record;
|
|
2529
2489
|
}
|
|
2530
2490
|
function descriptorStoreGeneration(record, storeVersion) {
|
|
2531
2491
|
return record.generation === undefined ? BigInt(storeVersion) : BigInt(record.generation);
|
|
@@ -2653,7 +2613,7 @@ function encodeAuthorityRecord(record) {
|
|
|
2653
2613
|
const snapshot = record.snapshot;
|
|
2654
2614
|
const allocation = snapshot.allocation;
|
|
2655
2615
|
const envelope = {
|
|
2656
|
-
recordVersion:
|
|
2616
|
+
recordVersion: LOCATION_RECORD_VERSION,
|
|
2657
2617
|
payload: Buffer.from(snapshot.payload).toString('base64'),
|
|
2658
2618
|
objectGeneration: snapshot.objectGeneration.toString(),
|
|
2659
2619
|
authorityOwnerGeneration: snapshot.authorityOwnerGeneration.toString(),
|
|
@@ -2789,8 +2749,8 @@ function runtimeSpotPlacementObjectKind(kind) {
|
|
|
2789
2749
|
function createTerminalRecord(request, now) {
|
|
2790
2750
|
const publication = request.completion.terminal;
|
|
2791
2751
|
validateCreationOperation(publication.operation);
|
|
2792
|
-
if (publication.terminalEnvelope.byteLength >
|
|
2793
|
-
throw new RangeError(
|
|
2752
|
+
if (publication.terminalEnvelope.byteLength > InternalDefaults_1.CREATION_TERMINAL_ENVELOPE_MAX_BYTES) {
|
|
2753
|
+
throw new RangeError(`Creation terminal envelope must not exceed ${InternalDefaults_1.CREATION_TERMINAL_ENVELOPE_MAX_BYTES / (1024 * 1024)} MiB.`);
|
|
2794
2754
|
}
|
|
2795
2755
|
const deadlineMs = publication.operationDeadline.getTime();
|
|
2796
2756
|
const expiresAtMs = deadlineMs + CREATION_TERMINAL_RETENTION_MS;
|
|
@@ -2831,8 +2791,10 @@ function retainedCreationTerminal(operation, terminalEnvelope, expiresAt, storeN
|
|
|
2831
2791
|
function validateCreationOperation(operation) {
|
|
2832
2792
|
const sourceRid = String(operation.sourceNodeRid);
|
|
2833
2793
|
const sourceRidBytes = Buffer.byteLength(sourceRid, 'utf8');
|
|
2834
|
-
if (sourceRidBytes < 1 ||
|
|
2835
|
-
|
|
2794
|
+
if (sourceRidBytes < 1 ||
|
|
2795
|
+
sourceRidBytes > CoreTypes_1.ZLINK_MAX_ROUTING_ID_BYTES ||
|
|
2796
|
+
sourceRid.includes('\0')) {
|
|
2797
|
+
throw new TypeError(`Creation terminal source node RID must contain 1..${CoreTypes_1.ZLINK_MAX_ROUTING_ID_BYTES} UTF-8 bytes without NUL.`);
|
|
2836
2798
|
}
|
|
2837
2799
|
if (operation.sourceNodeGeneration < 1n ||
|
|
2838
2800
|
operation.sourceNodeGeneration > MAX_U64 ||
|
|
@@ -2845,8 +2807,8 @@ function validateCreationOperation(operation) {
|
|
|
2845
2807
|
}
|
|
2846
2808
|
}
|
|
2847
2809
|
function validatePayloadSize(value, name) {
|
|
2848
|
-
if (value.byteLength >
|
|
2849
|
-
throw new RangeError(`${name} must not exceed
|
|
2810
|
+
if (value.byteLength > InternalDefaults_1.AUTHORITY_ENVELOPE_MAX_BYTES) {
|
|
2811
|
+
throw new RangeError(`${name} must not exceed ${InternalDefaults_1.AUTHORITY_ENVELOPE_MAX_BYTES / (1024 * 1024)} MiB.`);
|
|
2850
2812
|
}
|
|
2851
2813
|
}
|
|
2852
2814
|
function requireText(value, name) {
|
|
@@ -2900,6 +2862,9 @@ function versionCondition(key, read) {
|
|
|
2900
2862
|
}
|
|
2901
2863
|
return { kind: 'version', key, expected: read.value.version };
|
|
2902
2864
|
}
|
|
2865
|
+
function leaseValueCondition(key, owner) {
|
|
2866
|
+
return { kind: 'value', key, expected: encodeOwnerRecord(owner.ownerId, owner.leaseGeneration) };
|
|
2867
|
+
}
|
|
2903
2868
|
function emptyCapacityRecord() {
|
|
2904
2869
|
return {
|
|
2905
2870
|
active: { actors: 0, spots: 0, spotTypes: {} },
|
|
@@ -3215,8 +3180,8 @@ function validateClientServerDescriptor(descriptor) {
|
|
|
3215
3180
|
descriptor.ownerId
|
|
3216
3181
|
], 'ClientServer');
|
|
3217
3182
|
validateDescriptorGenerations(descriptor, 'ClientServer');
|
|
3218
|
-
if (!
|
|
3219
|
-
throw new RangeError(
|
|
3183
|
+
if (!(0, RegistrationBuilderPolicy_1.isValidPublicWeight)(descriptor.weight)) {
|
|
3184
|
+
throw new RangeError(`ClientServer descriptor weight must be an integer in 0..${RegistrationBuilderPolicy_1.ZLINK_MAX_PUBLIC_WEIGHT}.`);
|
|
3220
3185
|
}
|
|
3221
3186
|
}
|
|
3222
3187
|
function validateFanoutPublisherDescriptor(descriptor) {
|
|
@@ -3266,3 +3231,9 @@ function requireOwnerInput(ownerId, leaseTtlMs) {
|
|
|
3266
3231
|
throw new RangeError('Owner lease TTL must be a positive safe integer.');
|
|
3267
3232
|
}
|
|
3268
3233
|
}
|
|
3234
|
+
function throwIfOperationExpired(signal, deadlineUnixMs) {
|
|
3235
|
+
signal?.throwIfAborted();
|
|
3236
|
+
if (deadlineUnixMs !== undefined && Date.now() >= Number(deadlineUnixMs)) {
|
|
3237
|
+
throw new DOMException('Operation deadline exceeded.', 'TimeoutError');
|
|
3238
|
+
}
|
|
3239
|
+
}
|