@zlink-systems/framework 0.21.0 → 0.22.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/ZLinkMessage.js +5 -5
- package/dist/contracts/Configuration/CodecContentType.js +5 -7
- package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
- package/dist/contracts/Configuration/EndpointNotation.js +4 -8
- package/dist/contracts/Configuration/Registration.js +14 -11
- package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
- package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
- package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
- package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/location-store-integration.js +16 -16
- package/dist/nest-integration.js +17 -11
- package/dist/runtime/abort.js +9 -5
- package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
- package/dist/runtime/actors/actor-authority-publication.js +18 -17
- package/dist/runtime/actors/actor-client.js +83 -63
- package/dist/runtime/actors/actor-context.js +24 -18
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-local-native-join.js +18 -19
- package/dist/runtime/actors/actor-mailbox.js +1 -1
- package/dist/runtime/actors/actor-message-follow-context.js +24 -21
- package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
- package/dist/runtime/actors/actor-remote-joiner.js +20 -17
- package/dist/runtime/actors/actor-remote-wire.js +6 -7
- package/dist/runtime/actors/actor-runtime-state.js +87 -81
- package/dist/runtime/actors/actor-transfer-registry.js +3 -5
- package/dist/runtime/actors/bound-session-wire.js +14 -9
- package/dist/runtime/actors/deferred-join-accepted-journal.js +158 -124
- package/dist/runtime/actors/index.js +2 -5
- package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
- package/dist/runtime/actors/post-commit-actor-location.js +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
- package/dist/runtime/admission.js +2 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
- package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
- package/dist/runtime/backend/mesh-completion-table.js +1 -3
- package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
- package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +116 -113
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
- package/dist/runtime/backend/runtime-message.js +3 -3
- package/dist/runtime/backend/runtime-values.d.ts +2 -2
- package/dist/runtime/backend/runtime-values.js +4 -5
- package/dist/runtime/channels/channel-clients.js +27 -24
- package/dist/runtime/channels/channel-dispatch-pipeline.js +10 -18
- package/dist/runtime/channels/channel-dispatch-services.js +7 -4
- package/dist/runtime/channels/channel-dispatchers.js +9 -9
- package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
- package/dist/runtime/channels/channel-envelope.js +83 -47
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-receive-loops.js +20 -22
- package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
- package/dist/runtime/channels/channel-runtime-manager.js +18 -9
- package/dist/runtime/channels/channel-socket-registry.js +126 -123
- package/dist/runtime/channels/channel-transports.js +43 -33
- package/dist/runtime/channels/client-server-location-runtime.js +32 -40
- package/dist/runtime/channels/client-server-service-wire.js +29 -22
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -7
- package/dist/runtime/channels/fanout-location-runtime.js +34 -47
- package/dist/runtime/channels/fanout-service-wire.js +3 -5
- package/dist/runtime/channels/local-spot-route-transport.js +7 -1
- package/dist/runtime/channels/route-member-snapshot.js +3 -3
- package/dist/runtime/channels/source-spot-router.js +6 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
- package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +47 -39
- package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
- package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
- package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
- package/dist/runtime/execution/index.js +7 -6
- package/dist/runtime/execution/serial-execution-queue.js +12 -18
- package/dist/runtime/execution/state-lane.js +2 -2
- package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -23
- package/dist/runtime/foundation/event-loop-resources.js +4 -4
- package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +136 -136
- package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
- package/dist/runtime/foundation/runtime-state-projections.js +22 -11
- package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
- package/dist/runtime/foundation/service-discovery-registry.js +35 -33
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
- package/dist/runtime/foundation/service-liveness-registry.js +16 -12
- package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
- package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
- package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.js +416 -438
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.js +96 -95
- package/dist/runtime/foundation/service-weighted-selection.js +6 -11
- package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
- package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
- package/dist/runtime/framework-errors-internal.js +7 -10
- package/dist/runtime/handlers/handler-instance-scope.js +4 -5
- package/dist/runtime/handlers/index.js +3 -1
- package/dist/runtime/host/actor-packet-relay.js +74 -70
- package/dist/runtime/host/actor-placement-coordinator.js +29 -31
- package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
- package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
- package/dist/runtime/host/actor-transfer-runtime.js +176 -153
- package/dist/runtime/host/application-job-queue.js +18 -22
- package/dist/runtime/host/bound-session-relay.js +3 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
- package/dist/runtime/host/host-capacity-status.js +8 -4
- package/dist/runtime/host/index.js +244 -227
- package/dist/runtime/host/instance-activation-authority.js +93 -96
- package/dist/runtime/host/location-runtime-owner.js +16 -14
- package/dist/runtime/host/mesh-router-resolver.js +11 -13
- package/dist/runtime/host/relocation-direct-transfer.js +10 -9
- package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
- package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
- package/dist/runtime/host/remote-bound-session-relay.js +97 -73
- package/dist/runtime/host/route-mesh-runtime.js +64 -69
- package/dist/runtime/host/runtime-shutdown.js +1 -2
- package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
- package/dist/runtime/host/spot-address-transport.js +69 -71
- package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
- package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
- package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
- package/dist/runtime/locations/actor-location-claims.js +26 -20
- package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
- package/dist/runtime/locations/authority-key-codec.js +7 -7
- package/dist/runtime/locations/auto-connect-loop.js +3 -3
- package/dist/runtime/locations/auto-connect-planner.js +25 -19
- package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
- package/dist/runtime/locations/in-memory-authority-store.js +128 -118
- package/dist/runtime/locations/in-memory-location-store.js +195 -168
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
- package/dist/runtime/locations/key-codec.js +1 -1
- package/dist/runtime/locations/lease-tracker.js +23 -21
- package/dist/runtime/locations/lifecycle.js +4 -5
- package/dist/runtime/locations/location-store-repository.js +368 -324
- package/dist/runtime/locations/opaque-record-key.js +2 -2
- package/dist/runtime/locations/resolvers.js +73 -82
- package/dist/runtime/locations/runtime.js +68 -63
- package/dist/runtime/locations/spot-location-claims.js +39 -35
- package/dist/runtime/messaging/framework-json-v1.js +7 -7
- package/dist/runtime/messaging/packet-name.js +7 -6
- package/dist/runtime/messaging/payload-codec.js +21 -18
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
- package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
- package/dist/runtime/routing-id.js +3 -5
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
- package/dist/runtime/spots/index.js +208 -219
- package/dist/runtime/spots/spot-activation-registry.js +15 -14
- package/dist/runtime/spots/spot-activation-state.js +17 -15
- package/dist/runtime/spots/spot-activation.js +33 -16
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
- package/dist/runtime/spots/spot-actor-membership.js +1 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +23 -20
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -10
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
- package/dist/runtime/spots/spot-closing.js +3 -7
- package/dist/runtime/spots/spot-context.js +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +13 -14
- package/dist/runtime/spots/spot-handle.js +6 -3
- package/dist/runtime/spots/spot-handler-registry.js +12 -12
- package/dist/runtime/spots/spot-manager-public.js +5 -6
- package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
- package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +74 -85
- package/dist/runtime/spots/spot-outbound.js +10 -14
- package/dist/runtime/spots/spot-remote-codec.js +22 -26
- package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
- package/dist/runtime/spots/spot-route-packet-dispatch.js +16 -14
- package/dist/runtime/spots/spot-route-replies.js +4 -6
- package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
- package/dist/runtime/spots/spot-serial-executor.js +5 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
- package/dist/runtime/spots/spot-subscription-dispatch.js +5 -5
- package/dist/runtime/spots/spot-timer.js +25 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +98 -107
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +18 -16
- package/dist/runtime/streams/bound-session-service.js +8 -9
- package/dist/runtime/streams/index.js +20 -19
- package/dist/runtime/streams/managed-stream.js +32 -30
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.js +29 -18
- package/dist/runtime/streams/session-actor-coordinator.js +34 -37
- package/dist/runtime/streams/session-context.js +30 -28
- package/dist/runtime/streams/session-provider.js +2 -2
- package/dist/runtime/streams/session-serial-executor.js +1 -2
- package/dist/runtime/streams/stream-frame-factory.js +11 -5
- package/dist/runtime/streams/stream-session-runtime.js +70 -66
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +2 -2
- package/src/contracts/Channels/RouteCalls.ts +6 -1
- package/src/contracts/Common/ZLinkMessage.ts +5 -5
- package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
- package/src/contracts/Configuration/Builders.ts +14 -14
- package/src/contracts/Configuration/CodecContentType.ts +8 -10
- package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
- package/src/contracts/Configuration/EndpointNotation.ts +11 -11
- package/src/contracts/Configuration/ObjectRoles.ts +1 -3
- package/src/contracts/Configuration/Registration.ts +46 -17
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
- package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
- package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
- package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
- package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
- package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
- package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
- package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -6
- package/src/contracts/Errors/index.ts +1 -4
- package/src/contracts/Handlers/Attributes.ts +15 -9
- package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
- package/src/contracts/Handlers/JsonContract.ts +53 -19
- package/src/contracts/Locations/ActorTransfer.ts +1 -5
- package/src/contracts/Locations/Authority.ts +4 -11
- package/src/contracts/Locations/Keys.ts +6 -1
- package/src/contracts/Locations/Options.ts +3 -2
- package/src/contracts/Locations/RelocationStore.ts +1 -4
- package/src/contracts/Locations/Resolvers.ts +5 -5
- package/src/contracts/Locations/RuntimeQuery.ts +6 -2
- package/src/contracts/Locations/Stores.ts +1 -2
- package/src/contracts/Locations/index.ts +2 -8
- package/src/contracts/RouteMesh/Contracts.ts +1 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
- package/src/contracts/Spots/Contracts.ts +2 -8
- package/src/contracts/Spots/SpotKind.ts +16 -8
- package/src/contracts/Spots/ZLinkSpot.ts +8 -11
- package/src/contracts/Streams/IZLinkSession.ts +0 -1
- package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
- package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
- package/src/internal.ts +5 -4
- package/src/location-store-integration.ts +24 -16
- package/src/nest-integration.ts +40 -25
- package/src/runtime/abort.ts +10 -4
- package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
- package/src/runtime/actors/actor-authority-publication.ts +92 -77
- package/src/runtime/actors/actor-client.ts +162 -133
- package/src/runtime/actors/actor-context.ts +138 -130
- package/src/runtime/actors/actor-creation.ts +47 -44
- package/src/runtime/actors/actor-execution-context.ts +6 -4
- package/src/runtime/actors/actor-handoff.ts +269 -293
- package/src/runtime/actors/actor-join-deferred-scope.ts +5 -4
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
- package/src/runtime/actors/actor-local-native-join.ts +131 -159
- package/src/runtime/actors/actor-mailbox.ts +16 -19
- package/src/runtime/actors/actor-message-follow-context.ts +46 -36
- package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
- package/src/runtime/actors/actor-remote-joiner.ts +50 -54
- package/src/runtime/actors/actor-remote-wire.ts +9 -13
- package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
- package/src/runtime/actors/actor-runtime-state.ts +127 -124
- package/src/runtime/actors/actor-transfer-registry.ts +9 -14
- package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
- package/src/runtime/actors/bound-session-wire.ts +37 -17
- package/src/runtime/actors/deferred-join-accepted-journal.ts +351 -320
- package/src/runtime/actors/index.ts +43 -86
- package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
- package/src/runtime/actors/post-commit-actor-location.ts +30 -23
- package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
- package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
- package/src/runtime/admission.ts +9 -9
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
- package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
- package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
- package/src/runtime/backend/contracts/index.ts +73 -52
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
- package/src/runtime/backend/mesh-completion-table.ts +6 -9
- package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
- package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
- package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
- package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +335 -383
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
- package/src/runtime/backend/runtime-message.ts +5 -3
- package/src/runtime/backend/runtime-values.ts +10 -7
- package/src/runtime/channels/channel-autoconnect.ts +1 -4
- package/src/runtime/channels/channel-clients.ts +93 -73
- package/src/runtime/channels/channel-dispatch-pipeline.ts +40 -42
- package/src/runtime/channels/channel-dispatch-services.ts +51 -49
- package/src/runtime/channels/channel-dispatchers.ts +152 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
- package/src/runtime/channels/channel-envelope.ts +256 -150
- package/src/runtime/channels/channel-multipart.ts +13 -5
- package/src/runtime/channels/channel-outbound-operations.ts +37 -41
- package/src/runtime/channels/channel-receive-loops.ts +102 -98
- package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
- package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
- package/src/runtime/channels/channel-runtime-manager.ts +63 -37
- package/src/runtime/channels/channel-socket-options.ts +3 -10
- package/src/runtime/channels/channel-socket-registry.ts +331 -273
- package/src/runtime/channels/channel-transports.ts +215 -197
- package/src/runtime/channels/client-server-location-runtime.ts +116 -100
- package/src/runtime/channels/client-server-service-wire.ts +37 -36
- package/src/runtime/channels/dispatch-error-reporter.ts +11 -8
- package/src/runtime/channels/fanout-location-runtime.ts +91 -94
- package/src/runtime/channels/fanout-service-wire.ts +5 -12
- package/src/runtime/channels/handler-filter-scope.ts +1 -4
- package/src/runtime/channels/index.ts +1 -4
- package/src/runtime/channels/local-spot-route-transport.ts +20 -5
- package/src/runtime/channels/route-member-snapshot.ts +11 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
- package/src/runtime/channels/source-spot-router.ts +26 -22
- package/src/runtime/channels/spot-direct-envelope.ts +10 -8
- package/src/runtime/channels/spot-node-route-transport.ts +13 -16
- package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
- package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
- package/src/runtime/codecs/index.ts +3 -2
- package/src/runtime/diagnostics/flow-context.ts +12 -3
- package/src/runtime/diagnostics/index.ts +96 -61
- package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
- package/src/runtime/diagnostics/message-flow.ts +95 -76
- package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
- package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
- package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
- package/src/runtime/execution/index.ts +18 -26
- package/src/runtime/execution/serial-execution-queue.ts +31 -40
- package/src/runtime/execution/state-lane.ts +2 -2
- package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -51
- package/src/runtime/foundation/event-loop-resources.ts +8 -4
- package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
- package/src/runtime/foundation/operation-identity.ts +1 -2
- package/src/runtime/foundation/operation-registry.ts +8 -2
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +312 -385
- package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
- package/src/runtime/foundation/runtime-state-projections.ts +24 -23
- package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
- package/src/runtime/foundation/service-discovery-registry.ts +67 -59
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
- package/src/runtime/foundation/service-liveness-registry.ts +18 -13
- package/src/runtime/foundation/service-mailbox.ts +14 -14
- package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
- package/src/runtime/foundation/service-metadata-codec.ts +2 -9
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
- package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
- package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
- package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
- package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1174 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +157 -159
- package/src/runtime/foundation/service-weighted-selection.ts +9 -15
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
- package/src/runtime/framework-errors-internal.ts +31 -30
- package/src/runtime/handlers/handler-instance-scope.ts +18 -29
- package/src/runtime/handlers/index.ts +18 -8
- package/src/runtime/host/actor-packet-relay.ts +290 -261
- package/src/runtime/host/actor-placement-coordinator.ts +165 -150
- package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
- package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
- package/src/runtime/host/actor-transfer-runtime.ts +391 -395
- package/src/runtime/host/application-job-queue.ts +32 -48
- package/src/runtime/host/bound-session-relay.ts +7 -9
- package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
- package/src/runtime/host/host-capacity-status.ts +10 -9
- package/src/runtime/host/index.ts +861 -789
- package/src/runtime/host/instance-activation-authority.ts +125 -143
- package/src/runtime/host/location-runtime-owner.ts +38 -26
- package/src/runtime/host/mesh-router-resolver.ts +30 -23
- package/src/runtime/host/relocation-direct-transfer.ts +15 -15
- package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
- package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
- package/src/runtime/host/remote-bound-session-relay.ts +274 -247
- package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
- package/src/runtime/host/route-mesh-runtime.ts +227 -181
- package/src/runtime/host/runtime-shutdown.ts +4 -3
- package/src/runtime/host/service-relocation-control.ts +14 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
- package/src/runtime/host/spot-address-transport.ts +284 -237
- package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
- package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
- package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
- package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
- package/src/runtime/locations/actor-location-claims.ts +61 -49
- package/src/runtime/locations/actor-session-route-claims.ts +1 -4
- package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
- package/src/runtime/locations/authority-key-codec.ts +13 -10
- package/src/runtime/locations/auto-connect-loop.ts +14 -11
- package/src/runtime/locations/auto-connect-planner.ts +42 -31
- package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
- package/src/runtime/locations/canonical-codec.ts +3 -1
- package/src/runtime/locations/creation-operation-id.ts +4 -3
- package/src/runtime/locations/domain-store-contract.ts +13 -7
- package/src/runtime/locations/in-memory-authority-store.ts +232 -199
- package/src/runtime/locations/in-memory-location-store.ts +432 -250
- package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
- package/src/runtime/locations/internal-store-contracts.ts +95 -38
- package/src/runtime/locations/key-codec.ts +3 -4
- package/src/runtime/locations/lease-tracker.ts +36 -27
- package/src/runtime/locations/lifecycle-runtime.ts +15 -3
- package/src/runtime/locations/lifecycle.ts +33 -28
- package/src/runtime/locations/location-store-repository.ts +1329 -1185
- package/src/runtime/locations/opaque-record-key.ts +4 -9
- package/src/runtime/locations/resolvers.ts +201 -178
- package/src/runtime/locations/runtime.ts +251 -159
- package/src/runtime/locations/spot-location-claims.ts +110 -112
- package/src/runtime/messaging/creation-payload-codec.ts +4 -1
- package/src/runtime/messaging/framework-json-v1.ts +34 -15
- package/src/runtime/messaging/packet-name.ts +8 -6
- package/src/runtime/messaging/payload-codec.ts +70 -50
- package/src/runtime/messaging/submission-result.ts +6 -9
- package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/routing-id.ts +10 -7
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
- package/src/runtime/spots/index.ts +593 -563
- package/src/runtime/spots/spot-activation-registry.ts +38 -34
- package/src/runtime/spots/spot-activation-state.ts +43 -51
- package/src/runtime/spots/spot-activation.ts +179 -116
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
- package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
- package/src/runtime/spots/spot-actor-membership.ts +25 -27
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +184 -153
- package/src/runtime/spots/spot-actor-packet-drain.ts +54 -42
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
- package/src/runtime/spots/spot-closing.ts +11 -12
- package/src/runtime/spots/spot-context.ts +46 -26
- package/src/runtime/spots/spot-entry-activation.ts +84 -65
- package/src/runtime/spots/spot-handle.ts +17 -15
- package/src/runtime/spots/spot-handler-registry.ts +44 -31
- package/src/runtime/spots/spot-location-claim.ts +5 -4
- package/src/runtime/spots/spot-manager-public.ts +62 -82
- package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
- package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
- package/src/runtime/spots/spot-node-runtime-manager.ts +230 -221
- package/src/runtime/spots/spot-outbound.ts +47 -59
- package/src/runtime/spots/spot-publisher-transport.ts +5 -4
- package/src/runtime/spots/spot-remote-codec.ts +66 -65
- package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
- package/src/runtime/spots/spot-route-packet-dispatch.ts +128 -95
- package/src/runtime/spots/spot-route-replies.ts +23 -24
- package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
- package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +11 -17
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
- package/src/runtime/spots/spot-routing-internal.ts +1 -4
- package/src/runtime/spots/spot-runtime-ports.ts +5 -5
- package/src/runtime/spots/spot-serial-executor.ts +5 -9
- package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
- package/src/runtime/spots/spot-subscription-dispatch.ts +56 -46
- package/src/runtime/spots/spot-timer.ts +98 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +277 -235
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +7 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +53 -51
- package/src/runtime/streams/bound-session-response-target.ts +29 -8
- package/src/runtime/streams/bound-session-service.ts +39 -39
- package/src/runtime/streams/index.ts +176 -100
- package/src/runtime/streams/managed-stream.ts +98 -87
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +73 -43
- package/src/runtime/streams/session-actor-coordinator.ts +97 -89
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +66 -48
- package/src/runtime/streams/session-provider.ts +5 -7
- package/src/runtime/streams/session-serial-executor.ts +7 -6
- package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
- package/src/runtime/streams/stream-frame-factory.ts +55 -38
- package/src/runtime/streams/stream-session-runtime.ts +268 -210
- package/src/runtime/workers/index.ts +68 -29
|
@@ -73,9 +73,9 @@ import {
|
|
|
73
73
|
matchesSpotLocation
|
|
74
74
|
} from '../../location-store-integration';
|
|
75
75
|
|
|
76
|
-
export class ZLinkInMemoryLocationStore
|
|
77
|
-
ZLinkDomainLocationStore,
|
|
78
|
-
|
|
76
|
+
export class ZLinkInMemoryLocationStore
|
|
77
|
+
implements ZLinkDomainLocationStore, ZLinkFanoutLocationStore
|
|
78
|
+
{
|
|
79
79
|
private readonly leases = new Map<string, InMemoryOwnerLease>();
|
|
80
80
|
private readonly meshNodes = new RowTable<ZLinkMeshNodeDescriptor>();
|
|
81
81
|
private readonly clientServers = new RowTable<ZLinkClientServerServerDescriptor>();
|
|
@@ -91,42 +91,53 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
91
91
|
private readonly authority: ZLinkInMemoryAuthorityStore;
|
|
92
92
|
|
|
93
93
|
constructor(private readonly now: () => Date = () => new Date()) {
|
|
94
|
-
this.authority = new ZLinkInMemoryAuthorityStore(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
94
|
+
this.authority = new ZLinkInMemoryAuthorityStore(
|
|
95
|
+
{
|
|
96
|
+
isTargetLive: (key, lifecycleGeneration, owner) => {
|
|
97
|
+
const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
|
|
98
|
+
const lease = this.leases.get(owner.ownerId);
|
|
99
|
+
return (
|
|
100
|
+
descriptor !== undefined &&
|
|
101
|
+
descriptor.lifecycleGeneration === lifecycleGeneration &&
|
|
102
|
+
descriptor.ownerId === owner.ownerId &&
|
|
103
|
+
descriptor.leaseGeneration === owner.leaseGeneration &&
|
|
104
|
+
descriptor.objectRole === ZLinkObjectRole.Server &&
|
|
105
|
+
descriptor.state === ZLinkFrameworkRuntimeState.Serving &&
|
|
106
|
+
lease !== undefined &&
|
|
107
|
+
lease.token.leaseGeneration === owner.leaseGeneration &&
|
|
108
|
+
lease.leaseExpiresAt.getTime() > this.now().getTime()
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
placementCapacityAvailable: (key, requested, reserved, active) => {
|
|
112
|
+
const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
|
|
113
|
+
if (descriptor === undefined) return false;
|
|
114
|
+
const spotType = requested.spotType;
|
|
115
|
+
const typeCapacity =
|
|
116
|
+
spotType === undefined
|
|
117
|
+
? undefined
|
|
118
|
+
: descriptor.populationCapacity.spotTypes.find(
|
|
119
|
+
(candidate) =>
|
|
120
|
+
candidate.objectKind === spotType.objectKind &&
|
|
121
|
+
candidate.stableType === spotType.stableType
|
|
122
|
+
);
|
|
123
|
+
return (
|
|
124
|
+
active.actors + reserved.actors + requested.actors <=
|
|
125
|
+
descriptor.populationCapacity.actors.limit &&
|
|
126
|
+
active.spots + reserved.spots + requested.spots <=
|
|
127
|
+
descriptor.populationCapacity.spots.limit &&
|
|
128
|
+
(spotType === undefined ||
|
|
129
|
+
(typeCapacity !== undefined &&
|
|
130
|
+
(typeCapacity.limit === 0 ||
|
|
131
|
+
(active.spotType?.count ?? 0) +
|
|
132
|
+
(reserved.spotType?.count ?? 0) +
|
|
133
|
+
spotType.count <=
|
|
134
|
+
typeCapacity.limit)))
|
|
135
|
+
);
|
|
136
|
+
},
|
|
137
|
+
identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey)
|
|
127
138
|
},
|
|
128
|
-
|
|
129
|
-
|
|
139
|
+
now
|
|
140
|
+
);
|
|
130
141
|
}
|
|
131
142
|
|
|
132
143
|
async readAuthority(
|
|
@@ -219,14 +230,19 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
219
230
|
const current = this.meshNodes.rows.get(key);
|
|
220
231
|
const lease = this.leases.get(descriptor.ownerId);
|
|
221
232
|
const updatedAt = this.now();
|
|
222
|
-
if (
|
|
223
|
-
|
|
224
|
-
|
|
233
|
+
if (
|
|
234
|
+
lease === undefined ||
|
|
235
|
+
lease.token.leaseGeneration !== descriptor.leaseGeneration ||
|
|
236
|
+
lease.leaseExpiresAt.getTime() <= updatedAt.getTime()
|
|
237
|
+
) {
|
|
225
238
|
return rejectedConflict();
|
|
226
239
|
}
|
|
227
240
|
if (current === undefined) {
|
|
228
|
-
if (
|
|
229
|
-
|
|
241
|
+
if (
|
|
242
|
+
intent !== ZLinkLocationWriteIntent.NewClaim &&
|
|
243
|
+
intent !== ZLinkLocationWriteIntent.Takeover
|
|
244
|
+
)
|
|
245
|
+
return ignoredStale();
|
|
230
246
|
if (!this.claimEntrySpotIdentity(descriptor, key)) return rejectedConflict();
|
|
231
247
|
this.meshNodes.rows.set(key, { ...descriptor, updatedAt });
|
|
232
248
|
this.meshNodes.generations.set(key, 1n);
|
|
@@ -234,15 +250,17 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
234
250
|
return stored(1n, updatedAt);
|
|
235
251
|
}
|
|
236
252
|
const currentLease = this.leases.get(current.ownerId);
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
253
|
+
if (
|
|
254
|
+
canTakeOver(
|
|
255
|
+
current.ownerId,
|
|
256
|
+
current.leaseGeneration,
|
|
257
|
+
currentLease,
|
|
258
|
+
descriptor.ownerId,
|
|
259
|
+
descriptor.leaseGeneration,
|
|
260
|
+
intent,
|
|
261
|
+
updatedAt
|
|
262
|
+
)
|
|
263
|
+
) {
|
|
246
264
|
if (!this.claimEntrySpotIdentity(descriptor, key)) return rejectedConflict();
|
|
247
265
|
this.releaseEntrySpotIdentity(current);
|
|
248
266
|
const next = (this.meshNodes.generations.get(key) ?? 0n) + 1n;
|
|
@@ -251,18 +269,22 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
251
269
|
this.bump(ZLinkLocationKind.Peer, descriptor.meshName);
|
|
252
270
|
return stored(next, updatedAt);
|
|
253
271
|
}
|
|
254
|
-
if (
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
272
|
+
if (
|
|
273
|
+
current.ownerId === descriptor.ownerId &&
|
|
274
|
+
current.leaseGeneration === descriptor.leaseGeneration &&
|
|
275
|
+
current.lifecycleGeneration === descriptor.lifecycleGeneration &&
|
|
276
|
+
descriptor.descriptorRevision === current.descriptorRevision &&
|
|
277
|
+
meshNodeDescriptorFingerprint(current) === meshNodeDescriptorFingerprint(descriptor)
|
|
278
|
+
) {
|
|
259
279
|
return stored(this.meshNodes.generations.get(key) ?? 1n, current.updatedAt);
|
|
260
280
|
}
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
281
|
+
if (
|
|
282
|
+
current.ownerId !== descriptor.ownerId ||
|
|
283
|
+
current.leaseGeneration !== descriptor.leaseGeneration ||
|
|
284
|
+
current.lifecycleGeneration !== descriptor.lifecycleGeneration ||
|
|
285
|
+
descriptor.descriptorRevision <= current.descriptorRevision ||
|
|
286
|
+
meshNodeImmutableFingerprint(current) !== meshNodeImmutableFingerprint(descriptor)
|
|
287
|
+
) {
|
|
266
288
|
return ignoredStale();
|
|
267
289
|
}
|
|
268
290
|
this.meshNodes.rows.set(key, { ...descriptor, updatedAt });
|
|
@@ -277,9 +299,9 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
277
299
|
const encoded = meshNodeKey(key.meshName, key.rid);
|
|
278
300
|
const current = this.meshNodes.rows.get(encoded);
|
|
279
301
|
if (
|
|
280
|
-
current === undefined
|
|
281
|
-
|
|
282
|
-
|
|
302
|
+
current === undefined ||
|
|
303
|
+
current.ownerId !== owner.ownerId ||
|
|
304
|
+
current.leaseGeneration !== owner.leaseGeneration
|
|
283
305
|
) {
|
|
284
306
|
return ZLinkLocationWriteStatus.IgnoredStale;
|
|
285
307
|
}
|
|
@@ -302,7 +324,7 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
302
324
|
const objectCapabilities = row.objectCapabilities.map((capability) => {
|
|
303
325
|
return { ...capability };
|
|
304
326
|
});
|
|
305
|
-
const spotTypes = row.populationCapacity.spotTypes.map(capacity => {
|
|
327
|
+
const spotTypes = row.populationCapacity.spotTypes.map((capacity) => {
|
|
306
328
|
const usage = this.authority.capacityUsage(
|
|
307
329
|
descriptor,
|
|
308
330
|
row.lifecycleGeneration,
|
|
@@ -312,9 +334,12 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
312
334
|
return { ...capacity, ...usage };
|
|
313
335
|
});
|
|
314
336
|
const actors = this.authority.capacityUsage(
|
|
315
|
-
descriptor,
|
|
316
|
-
|
|
317
|
-
|
|
337
|
+
descriptor,
|
|
338
|
+
row.lifecycleGeneration,
|
|
339
|
+
'actor',
|
|
340
|
+
''
|
|
341
|
+
);
|
|
342
|
+
const spots = this.authority.capacityUsage(descriptor, row.lifecycleGeneration, 'spot', '');
|
|
318
343
|
return {
|
|
319
344
|
...row,
|
|
320
345
|
objectCapabilities,
|
|
@@ -325,7 +350,7 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
325
350
|
}
|
|
326
351
|
};
|
|
327
352
|
});
|
|
328
|
-
return pageValues(rows, page ?? {}, row => meshNodeKey(row.meshName, row.rid));
|
|
353
|
+
return pageValues(rows, page ?? {}, (row) => meshNodeKey(row.meshName, row.rid));
|
|
329
354
|
}
|
|
330
355
|
|
|
331
356
|
async updateClientServer(
|
|
@@ -339,14 +364,19 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
339
364
|
const current = this.clientServers.rows.get(key);
|
|
340
365
|
const lease = this.leases.get(descriptor.ownerId);
|
|
341
366
|
const updatedAt = this.now();
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
|
|
367
|
+
if (
|
|
368
|
+
lease === undefined ||
|
|
369
|
+
lease.token.leaseGeneration !== descriptor.leaseGeneration ||
|
|
370
|
+
lease.leaseExpiresAt.getTime() <= updatedAt.getTime()
|
|
371
|
+
) {
|
|
345
372
|
return rejectedConflict();
|
|
346
373
|
}
|
|
347
374
|
if (current === undefined) {
|
|
348
|
-
if (
|
|
349
|
-
|
|
375
|
+
if (
|
|
376
|
+
intent !== ZLinkLocationWriteIntent.NewClaim &&
|
|
377
|
+
intent !== ZLinkLocationWriteIntent.Takeover
|
|
378
|
+
)
|
|
379
|
+
return ignoredStale();
|
|
350
380
|
const generation = (this.clientServers.generations.get(key) ?? 0n) + 1n;
|
|
351
381
|
this.clientServers.rows.set(key, { ...descriptor, updatedAt });
|
|
352
382
|
this.clientServers.generations.set(key, generation);
|
|
@@ -354,29 +384,35 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
354
384
|
return stored(generation, updatedAt);
|
|
355
385
|
}
|
|
356
386
|
const currentLease = this.leases.get(current.ownerId);
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
387
|
+
if (
|
|
388
|
+
canTakeOver(
|
|
389
|
+
current.ownerId,
|
|
390
|
+
current.leaseGeneration,
|
|
391
|
+
currentLease,
|
|
392
|
+
descriptor.ownerId,
|
|
393
|
+
descriptor.leaseGeneration,
|
|
394
|
+
intent,
|
|
395
|
+
updatedAt
|
|
396
|
+
)
|
|
397
|
+
) {
|
|
366
398
|
const generation = (this.clientServers.generations.get(key) ?? 0n) + 1n;
|
|
367
399
|
this.clientServers.rows.set(key, { ...descriptor, updatedAt });
|
|
368
400
|
this.clientServers.generations.set(key, generation);
|
|
369
401
|
this.bump(ZLinkLocationKind.ClientServer, descriptor.channelName);
|
|
370
402
|
return stored(generation, updatedAt);
|
|
371
403
|
}
|
|
372
|
-
if (
|
|
404
|
+
if (
|
|
405
|
+
clientServerDescriptorFingerprint(current) === clientServerDescriptorFingerprint(descriptor)
|
|
406
|
+
) {
|
|
373
407
|
return stored(this.clientServers.generations.get(key) ?? 1n, current.updatedAt);
|
|
374
408
|
}
|
|
375
|
-
if (
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
409
|
+
if (
|
|
410
|
+
current.ownerId !== descriptor.ownerId ||
|
|
411
|
+
current.leaseGeneration !== descriptor.leaseGeneration ||
|
|
412
|
+
current.lifecycleGeneration !== descriptor.lifecycleGeneration ||
|
|
413
|
+
descriptor.descriptorRevision <= current.descriptorRevision ||
|
|
414
|
+
clientServerImmutableFingerprint(current) !== clientServerImmutableFingerprint(descriptor)
|
|
415
|
+
) {
|
|
380
416
|
return ignoredStale();
|
|
381
417
|
}
|
|
382
418
|
this.clientServers.rows.set(key, { ...descriptor, updatedAt });
|
|
@@ -392,9 +428,11 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
392
428
|
signal?.throwIfAborted();
|
|
393
429
|
const encoded = clientServerKey(key.channelName, key.serverRid);
|
|
394
430
|
const current = this.clientServers.rows.get(encoded);
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
431
|
+
if (
|
|
432
|
+
current === undefined ||
|
|
433
|
+
current.ownerId !== owner.ownerId ||
|
|
434
|
+
current.leaseGeneration !== owner.leaseGeneration
|
|
435
|
+
) {
|
|
398
436
|
return ZLinkLocationWriteStatus.IgnoredStale;
|
|
399
437
|
}
|
|
400
438
|
this.clientServers.rows.delete(encoded);
|
|
@@ -422,44 +460,55 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
422
460
|
const current = this.fanoutPublishers.rows.get(key);
|
|
423
461
|
const lease = this.leases.get(descriptor.ownerId);
|
|
424
462
|
const updatedAt = this.now();
|
|
425
|
-
if (
|
|
426
|
-
|
|
427
|
-
|
|
463
|
+
if (
|
|
464
|
+
lease === undefined ||
|
|
465
|
+
lease.token.leaseGeneration !== descriptor.leaseGeneration ||
|
|
466
|
+
lease.leaseExpiresAt.getTime() <= updatedAt.getTime()
|
|
467
|
+
) {
|
|
428
468
|
return rejectedConflict();
|
|
429
469
|
}
|
|
430
470
|
if (current === undefined) {
|
|
431
|
-
if (
|
|
432
|
-
|
|
471
|
+
if (
|
|
472
|
+
intent !== ZLinkLocationWriteIntent.NewClaim &&
|
|
473
|
+
intent !== ZLinkLocationWriteIntent.Takeover
|
|
474
|
+
)
|
|
475
|
+
return ignoredStale();
|
|
433
476
|
const generation = (this.fanoutPublishers.generations.get(key) ?? 0n) + 1n;
|
|
434
477
|
this.fanoutPublishers.rows.set(key, { ...descriptor, updatedAt });
|
|
435
478
|
this.fanoutPublishers.generations.set(key, generation);
|
|
436
479
|
return stored(generation, updatedAt);
|
|
437
480
|
}
|
|
438
481
|
const currentLease = this.leases.get(current.ownerId);
|
|
439
|
-
if (
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
482
|
+
if (
|
|
483
|
+
canTakeOver(
|
|
484
|
+
current.ownerId,
|
|
485
|
+
current.leaseGeneration,
|
|
486
|
+
currentLease,
|
|
487
|
+
descriptor.ownerId,
|
|
488
|
+
descriptor.leaseGeneration,
|
|
489
|
+
intent,
|
|
490
|
+
updatedAt
|
|
491
|
+
)
|
|
492
|
+
) {
|
|
448
493
|
const generation = (this.fanoutPublishers.generations.get(key) ?? 0n) + 1n;
|
|
449
494
|
this.fanoutPublishers.rows.set(key, { ...descriptor, updatedAt });
|
|
450
495
|
this.fanoutPublishers.generations.set(key, generation);
|
|
451
496
|
return stored(generation, updatedAt);
|
|
452
497
|
}
|
|
453
|
-
if (
|
|
454
|
-
|
|
498
|
+
if (
|
|
499
|
+
fanoutPublisherDescriptorFingerprint(current) ===
|
|
500
|
+
fanoutPublisherDescriptorFingerprint(descriptor)
|
|
501
|
+
) {
|
|
455
502
|
return stored(this.fanoutPublishers.generations.get(key) ?? 1n, current.updatedAt);
|
|
456
503
|
}
|
|
457
|
-
if (
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
504
|
+
if (
|
|
505
|
+
current.ownerId !== descriptor.ownerId ||
|
|
506
|
+
current.leaseGeneration !== descriptor.leaseGeneration ||
|
|
507
|
+
current.lifecycleGeneration !== descriptor.lifecycleGeneration ||
|
|
508
|
+
descriptor.descriptorRevision <= current.descriptorRevision ||
|
|
509
|
+
fanoutPublisherImmutableFingerprint(current) !==
|
|
510
|
+
fanoutPublisherImmutableFingerprint(descriptor)
|
|
511
|
+
) {
|
|
463
512
|
return ignoredStale();
|
|
464
513
|
}
|
|
465
514
|
this.fanoutPublishers.rows.set(key, { ...descriptor, updatedAt });
|
|
@@ -474,9 +523,11 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
474
523
|
signal?.throwIfAborted();
|
|
475
524
|
const encoded = fanoutPublisherKey(key.channelName, key.publisherRid);
|
|
476
525
|
const current = this.fanoutPublishers.rows.get(encoded);
|
|
477
|
-
if (
|
|
478
|
-
|
|
479
|
-
|
|
526
|
+
if (
|
|
527
|
+
current === undefined ||
|
|
528
|
+
current.ownerId !== owner.ownerId ||
|
|
529
|
+
current.leaseGeneration !== owner.leaseGeneration
|
|
530
|
+
) {
|
|
480
531
|
return ZLinkLocationWriteStatus.IgnoredStale;
|
|
481
532
|
}
|
|
482
533
|
this.fanoutPublishers.rows.delete(encoded);
|
|
@@ -522,7 +573,10 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
522
573
|
);
|
|
523
574
|
}
|
|
524
575
|
|
|
525
|
-
async removePeer(
|
|
576
|
+
async removePeer(
|
|
577
|
+
key: ZLinkPeerLocationKey,
|
|
578
|
+
owner: ZLinkLocationOwnerToken
|
|
579
|
+
): Promise<ZLinkLocationWriteResult> {
|
|
526
580
|
return this.remove(
|
|
527
581
|
this.peers,
|
|
528
582
|
ZLinkLocationKeyCodec.encodePeerKey(key),
|
|
@@ -542,24 +596,33 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
542
596
|
spot: ZLinkSpotLocation,
|
|
543
597
|
intent: ZLinkLocationWriteIntent
|
|
544
598
|
): Promise<ZLinkLocationWriteResult> {
|
|
545
|
-
const key = ZLinkLocationKeyCodec.encodeSpotKey({
|
|
599
|
+
const key = ZLinkLocationKeyCodec.encodeSpotKey({
|
|
600
|
+
meshName: spot.meshName,
|
|
601
|
+
spotId: spot.spotId
|
|
602
|
+
});
|
|
546
603
|
const updatedAt = this.now();
|
|
547
604
|
const current = this.spots.rows.get(key);
|
|
548
|
-
if (
|
|
549
|
-
|
|
550
|
-
|
|
605
|
+
if (
|
|
606
|
+
intent === ZLinkLocationWriteIntent.NewClaim &&
|
|
607
|
+
current !== undefined &&
|
|
608
|
+
this.isOwnerLive(current.ownerId, updatedAt)
|
|
609
|
+
) {
|
|
551
610
|
return rejectedConflict();
|
|
552
611
|
}
|
|
553
612
|
if (intent === ZLinkLocationWriteIntent.Renew) {
|
|
554
|
-
if (
|
|
555
|
-
|
|
556
|
-
|
|
613
|
+
if (
|
|
614
|
+
current === undefined ||
|
|
615
|
+
current.ownerId !== spot.ownerId ||
|
|
616
|
+
current.leaseGeneration !== spot.leaseGeneration
|
|
617
|
+
)
|
|
618
|
+
return ignoredStale();
|
|
557
619
|
this.spots.rows.set(key, { ...spot, updatedAt });
|
|
558
620
|
this.bump(ZLinkLocationKind.Spot, spot.meshName);
|
|
559
621
|
return stored(this.spots.generations.get(key) ?? 0n, updatedAt);
|
|
560
622
|
}
|
|
561
|
-
if (
|
|
562
|
-
&&
|
|
623
|
+
if (
|
|
624
|
+
current !== undefined &&
|
|
625
|
+
!canTakeOver(
|
|
563
626
|
current.ownerId,
|
|
564
627
|
current.leaseGeneration,
|
|
565
628
|
this.leases.get(current.ownerId),
|
|
@@ -567,7 +630,9 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
567
630
|
spot.leaseGeneration,
|
|
568
631
|
intent,
|
|
569
632
|
updatedAt
|
|
570
|
-
)
|
|
633
|
+
)
|
|
634
|
+
)
|
|
635
|
+
return rejectedConflict();
|
|
571
636
|
const generation = (this.spots.generations.get(key) ?? 0n) + 1n;
|
|
572
637
|
this.spots.generations.set(key, generation);
|
|
573
638
|
this.spots.rows.set(key, { ...spot, updatedAt });
|
|
@@ -575,13 +640,18 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
575
640
|
return stored(generation, updatedAt);
|
|
576
641
|
}
|
|
577
642
|
|
|
578
|
-
async removeSpot(
|
|
643
|
+
async removeSpot(
|
|
644
|
+
key: ZLinkSpotLocationKey,
|
|
645
|
+
owner: ZLinkLocationOwnerToken
|
|
646
|
+
): Promise<ZLinkLocationWriteStatus> {
|
|
579
647
|
const encoded = ZLinkLocationKeyCodec.encodeSpotKey(key);
|
|
580
648
|
const current = this.spots.rows.get(encoded);
|
|
581
649
|
const leaseGeneration = current?.leaseGeneration ?? this.spots.generations.get(encoded);
|
|
582
|
-
if (
|
|
583
|
-
|
|
584
|
-
|
|
650
|
+
if (
|
|
651
|
+
current === undefined ||
|
|
652
|
+
current.ownerId !== owner.ownerId ||
|
|
653
|
+
leaseGeneration !== owner.leaseGeneration
|
|
654
|
+
) {
|
|
585
655
|
return ZLinkLocationWriteStatus.IgnoredStale;
|
|
586
656
|
}
|
|
587
657
|
this.spots.rows.delete(encoded);
|
|
@@ -604,24 +674,33 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
604
674
|
actor: ZLinkActorLocation,
|
|
605
675
|
intent: ZLinkLocationWriteIntent
|
|
606
676
|
): Promise<ZLinkLocationWriteResult> {
|
|
607
|
-
const key = ZLinkLocationKeyCodec.encodeActorKey({
|
|
677
|
+
const key = ZLinkLocationKeyCodec.encodeActorKey({
|
|
678
|
+
meshName: actor.meshName,
|
|
679
|
+
actorId: actor.actorId
|
|
680
|
+
});
|
|
608
681
|
const updatedAt = this.now();
|
|
609
682
|
const current = this.actors.rows.get(key);
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
|
|
683
|
+
if (
|
|
684
|
+
intent === ZLinkLocationWriteIntent.NewClaim &&
|
|
685
|
+
current !== undefined &&
|
|
686
|
+
this.isOwnerLive(current.ownerId, updatedAt)
|
|
687
|
+
) {
|
|
613
688
|
return rejectedConflict();
|
|
614
689
|
}
|
|
615
690
|
if (intent === ZLinkLocationWriteIntent.Renew) {
|
|
616
|
-
if (
|
|
617
|
-
|
|
618
|
-
|
|
691
|
+
if (
|
|
692
|
+
current === undefined ||
|
|
693
|
+
current.ownerId !== actor.ownerId ||
|
|
694
|
+
current.leaseGeneration !== actor.leaseGeneration
|
|
695
|
+
)
|
|
696
|
+
return ignoredStale();
|
|
619
697
|
this.actors.rows.set(key, { ...actor, updatedAt });
|
|
620
698
|
this.bump(ZLinkLocationKind.Actor, actor.meshName);
|
|
621
699
|
return stored(this.actors.generations.get(key) ?? 0n, updatedAt);
|
|
622
700
|
}
|
|
623
|
-
if (
|
|
624
|
-
&&
|
|
701
|
+
if (
|
|
702
|
+
current !== undefined &&
|
|
703
|
+
!canTakeOver(
|
|
625
704
|
current.ownerId,
|
|
626
705
|
current.leaseGeneration,
|
|
627
706
|
this.leases.get(current.ownerId),
|
|
@@ -629,7 +708,9 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
629
708
|
actor.leaseGeneration,
|
|
630
709
|
intent,
|
|
631
710
|
updatedAt
|
|
632
|
-
)
|
|
711
|
+
)
|
|
712
|
+
)
|
|
713
|
+
return rejectedConflict();
|
|
633
714
|
const generation = (this.actors.generations.get(key) ?? 0n) + 1n;
|
|
634
715
|
this.actors.generations.set(key, generation);
|
|
635
716
|
this.actors.rows.set(key, { ...actor, updatedAt });
|
|
@@ -637,13 +718,18 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
637
718
|
return stored(generation, updatedAt);
|
|
638
719
|
}
|
|
639
720
|
|
|
640
|
-
async removeActor(
|
|
721
|
+
async removeActor(
|
|
722
|
+
key: ZLinkActorLocationKey,
|
|
723
|
+
owner: ZLinkLocationOwnerToken
|
|
724
|
+
): Promise<ZLinkLocationWriteStatus> {
|
|
641
725
|
const encoded = ZLinkLocationKeyCodec.encodeActorKey(key);
|
|
642
726
|
const current = this.actors.rows.get(encoded);
|
|
643
727
|
const leaseGeneration = current?.leaseGeneration ?? this.actors.generations.get(encoded);
|
|
644
|
-
if (
|
|
645
|
-
|
|
646
|
-
|
|
728
|
+
if (
|
|
729
|
+
current === undefined ||
|
|
730
|
+
current.ownerId !== owner.ownerId ||
|
|
731
|
+
leaseGeneration !== owner.leaseGeneration
|
|
732
|
+
) {
|
|
647
733
|
return ZLinkLocationWriteStatus.IgnoredStale;
|
|
648
734
|
}
|
|
649
735
|
this.actors.rows.delete(encoded);
|
|
@@ -668,7 +754,10 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
668
754
|
): Promise<ZLinkLocationWriteResult> {
|
|
669
755
|
return this.write(
|
|
670
756
|
this.routes,
|
|
671
|
-
ZLinkLocationKeyCodec.encodeRouteKey({
|
|
757
|
+
ZLinkLocationKeyCodec.encodeRouteKey({
|
|
758
|
+
routeKind: route.routeKind,
|
|
759
|
+
routeKey: route.routeKey
|
|
760
|
+
}),
|
|
672
761
|
route,
|
|
673
762
|
intent,
|
|
674
763
|
route.ownerId,
|
|
@@ -681,7 +770,10 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
681
770
|
);
|
|
682
771
|
}
|
|
683
772
|
|
|
684
|
-
async removeRoute(
|
|
773
|
+
async removeRoute(
|
|
774
|
+
key: ZLinkRouteLocationKey,
|
|
775
|
+
owner: ZLinkLocationOwnerToken
|
|
776
|
+
): Promise<ZLinkLocationWriteResult> {
|
|
685
777
|
return this.remove(
|
|
686
778
|
this.routes,
|
|
687
779
|
ZLinkLocationKeyCodec.encodeRouteKey(key),
|
|
@@ -752,7 +844,13 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
752
844
|
): Promise<ZLinkActorTransferWriteResult> {
|
|
753
845
|
signal?.throwIfAborted();
|
|
754
846
|
return this.transitionActorTransfer(
|
|
755
|
-
meshName,
|
|
847
|
+
meshName,
|
|
848
|
+
actorId,
|
|
849
|
+
transferId,
|
|
850
|
+
recoveryOwnerId,
|
|
851
|
+
'prepared',
|
|
852
|
+
'committed',
|
|
853
|
+
false
|
|
756
854
|
);
|
|
757
855
|
}
|
|
758
856
|
|
|
@@ -765,7 +863,13 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
765
863
|
): Promise<ZLinkActorTransferWriteResult> {
|
|
766
864
|
signal?.throwIfAborted();
|
|
767
865
|
return this.transitionActorTransfer(
|
|
768
|
-
meshName,
|
|
866
|
+
meshName,
|
|
867
|
+
actorId,
|
|
868
|
+
transferId,
|
|
869
|
+
recoveryOwnerId,
|
|
870
|
+
'committed',
|
|
871
|
+
'activated',
|
|
872
|
+
true
|
|
769
873
|
);
|
|
770
874
|
}
|
|
771
875
|
|
|
@@ -778,7 +882,13 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
778
882
|
): Promise<ZLinkActorTransferWriteResult> {
|
|
779
883
|
signal?.throwIfAborted();
|
|
780
884
|
return this.transitionActorTransfer(
|
|
781
|
-
meshName,
|
|
885
|
+
meshName,
|
|
886
|
+
actorId,
|
|
887
|
+
transferId,
|
|
888
|
+
recoveryOwnerId,
|
|
889
|
+
'prepared',
|
|
890
|
+
'aborted',
|
|
891
|
+
true
|
|
782
892
|
);
|
|
783
893
|
}
|
|
784
894
|
|
|
@@ -793,7 +903,9 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
793
903
|
signal?.throwIfAborted();
|
|
794
904
|
validateTransferIdentity(meshName, actorId, transferId);
|
|
795
905
|
validateTransferLease(successorOwnerId, recoveryLeaseTtlMs);
|
|
796
|
-
const record = this.actorTransfers
|
|
906
|
+
const record = this.actorTransfers
|
|
907
|
+
.get(actorTransferKey(meshName, actorId))
|
|
908
|
+
?.records.get(transferId);
|
|
797
909
|
if (record === undefined) return transferResult('notFound');
|
|
798
910
|
if (record.state !== 'prepared' && record.state !== 'committed') {
|
|
799
911
|
return transferResult('invalidState');
|
|
@@ -819,7 +931,9 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
819
931
|
): Promise<ZLinkActorTransferRecord | undefined> {
|
|
820
932
|
signal?.throwIfAborted();
|
|
821
933
|
const slot = this.actorTransfers.get(actorTransferKey(meshName, actorId));
|
|
822
|
-
return slot?.activeTransferId === undefined
|
|
934
|
+
return slot?.activeTransferId === undefined
|
|
935
|
+
? undefined
|
|
936
|
+
: slot.records.get(slot.activeTransferId);
|
|
823
937
|
}
|
|
824
938
|
|
|
825
939
|
async claimOwnerLease(
|
|
@@ -843,10 +957,7 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
843
957
|
return { kind: 'claimed', token, leaseExpiresAt, storeNow };
|
|
844
958
|
}
|
|
845
959
|
|
|
846
|
-
async readOwnerLease(
|
|
847
|
-
ownerId: string,
|
|
848
|
-
signal?: AbortSignal
|
|
849
|
-
): Promise<ZLinkOwnerLeaseReadResult> {
|
|
960
|
+
async readOwnerLease(ownerId: string, signal?: AbortSignal): Promise<ZLinkOwnerLeaseReadResult> {
|
|
850
961
|
signal?.throwIfAborted();
|
|
851
962
|
if (ownerId.trim().length === 0) throw new TypeError('ownerId is required.');
|
|
852
963
|
const storeNow = this.now();
|
|
@@ -873,9 +984,9 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
873
984
|
const storeNow = this.now();
|
|
874
985
|
const current = this.leases.get(token.ownerId);
|
|
875
986
|
if (
|
|
876
|
-
current === undefined
|
|
877
|
-
|
|
878
|
-
|
|
987
|
+
current === undefined ||
|
|
988
|
+
current.leaseExpiresAt.getTime() <= storeNow.getTime() ||
|
|
989
|
+
current.token.leaseGeneration !== token.leaseGeneration
|
|
879
990
|
) {
|
|
880
991
|
return { kind: 'stale' };
|
|
881
992
|
}
|
|
@@ -897,15 +1008,14 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
897
1008
|
return 'released';
|
|
898
1009
|
}
|
|
899
1010
|
|
|
900
|
-
async removeAllByOwner(
|
|
901
|
-
owner: ZLinkLocationOwnerToken,
|
|
902
|
-
signal?: AbortSignal
|
|
903
|
-
): Promise<bigint> {
|
|
1011
|
+
async removeAllByOwner(owner: ZLinkLocationOwnerToken, signal?: AbortSignal): Promise<bigint> {
|
|
904
1012
|
signal?.throwIfAborted();
|
|
905
1013
|
const lease = this.leases.get(owner.ownerId);
|
|
906
|
-
if (
|
|
907
|
-
|
|
908
|
-
|
|
1014
|
+
if (
|
|
1015
|
+
lease === undefined ||
|
|
1016
|
+
lease.token.leaseGeneration !== owner.leaseGeneration ||
|
|
1017
|
+
lease.leaseExpiresAt.getTime() <= this.now().getTime()
|
|
1018
|
+
) {
|
|
909
1019
|
return 0n;
|
|
910
1020
|
}
|
|
911
1021
|
const ownerId = owner.ownerId;
|
|
@@ -917,10 +1027,34 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
917
1027
|
this.bump(ZLinkLocationKind.Peer, row.meshName);
|
|
918
1028
|
removed++;
|
|
919
1029
|
}
|
|
920
|
-
removed += this.removeByOwner(
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
1030
|
+
removed += this.removeByOwner(
|
|
1031
|
+
this.peers,
|
|
1032
|
+
ownerId,
|
|
1033
|
+
(row) => row.ownerId,
|
|
1034
|
+
ZLinkLocationKind.Peer,
|
|
1035
|
+
(row) => row.meshName
|
|
1036
|
+
);
|
|
1037
|
+
removed += this.removeByOwner(
|
|
1038
|
+
this.spots,
|
|
1039
|
+
ownerId,
|
|
1040
|
+
(row) => row.ownerId,
|
|
1041
|
+
ZLinkLocationKind.Spot,
|
|
1042
|
+
(row) => row.meshName
|
|
1043
|
+
);
|
|
1044
|
+
removed += this.removeByOwner(
|
|
1045
|
+
this.actors,
|
|
1046
|
+
ownerId,
|
|
1047
|
+
(row) => row.ownerId,
|
|
1048
|
+
ZLinkLocationKind.Actor,
|
|
1049
|
+
() => undefined
|
|
1050
|
+
);
|
|
1051
|
+
removed += this.removeByOwner(
|
|
1052
|
+
this.routes,
|
|
1053
|
+
ownerId,
|
|
1054
|
+
(row) => row.ownerId,
|
|
1055
|
+
ZLinkLocationKind.Route,
|
|
1056
|
+
() => undefined
|
|
1057
|
+
);
|
|
924
1058
|
removed += this.removeByOwner(
|
|
925
1059
|
this.clientServers,
|
|
926
1060
|
ownerId,
|
|
@@ -940,9 +1074,11 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
940
1074
|
const authorityKey = encodeAuthorityKey('user_spot', descriptor.entrySpotId).value;
|
|
941
1075
|
const current = this.entrySpotClaims.get(authorityKey);
|
|
942
1076
|
if (current !== undefined) {
|
|
943
|
-
if (
|
|
944
|
-
|
|
945
|
-
|
|
1077
|
+
if (
|
|
1078
|
+
current.descriptorKey !== descriptorKey ||
|
|
1079
|
+
current.ownerId !== descriptor.ownerId ||
|
|
1080
|
+
current.lifecycleGeneration !== descriptor.lifecycleGeneration
|
|
1081
|
+
) {
|
|
946
1082
|
return false;
|
|
947
1083
|
}
|
|
948
1084
|
this.entrySpotClaims.set(authorityKey, {
|
|
@@ -964,9 +1100,11 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
964
1100
|
if (descriptor.entrySpotId === undefined) return;
|
|
965
1101
|
const authorityKey = encodeAuthorityKey('user_spot', descriptor.entrySpotId).value;
|
|
966
1102
|
const current = this.entrySpotClaims.get(authorityKey);
|
|
967
|
-
if (
|
|
968
|
-
|
|
969
|
-
|
|
1103
|
+
if (
|
|
1104
|
+
current?.ownerId === descriptor.ownerId &&
|
|
1105
|
+
current.leaseGeneration === descriptor.leaseGeneration &&
|
|
1106
|
+
current.lifecycleGeneration === descriptor.lifecycleGeneration
|
|
1107
|
+
) {
|
|
970
1108
|
this.entrySpotClaims.delete(authorityKey);
|
|
971
1109
|
}
|
|
972
1110
|
}
|
|
@@ -991,13 +1129,18 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
991
1129
|
const updatedAt = this.now();
|
|
992
1130
|
const current = table.rows.get(key);
|
|
993
1131
|
|
|
994
|
-
if (
|
|
995
|
-
|
|
996
|
-
|
|
1132
|
+
if (
|
|
1133
|
+
intent === ZLinkLocationWriteIntent.NewClaim &&
|
|
1134
|
+
current !== undefined &&
|
|
1135
|
+
this.isOwnerLive(ownerOf(current), updatedAt)
|
|
1136
|
+
) {
|
|
997
1137
|
return rejectedConflict();
|
|
998
1138
|
}
|
|
999
1139
|
|
|
1000
|
-
if (
|
|
1140
|
+
if (
|
|
1141
|
+
intent === ZLinkLocationWriteIntent.NewClaim ||
|
|
1142
|
+
intent === ZLinkLocationWriteIntent.Takeover
|
|
1143
|
+
) {
|
|
1001
1144
|
const next = (table.generations.get(key) ?? 0n) + 1n;
|
|
1002
1145
|
table.generations.set(key, next);
|
|
1003
1146
|
table.rows.set(key, finalize(row, next, updatedAt));
|
|
@@ -1005,9 +1148,11 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
1005
1148
|
return stored(next, updatedAt);
|
|
1006
1149
|
}
|
|
1007
1150
|
|
|
1008
|
-
if (
|
|
1009
|
-
|
|
1010
|
-
|
|
1151
|
+
if (
|
|
1152
|
+
current !== undefined &&
|
|
1153
|
+
ownerOf(current) === ownerId &&
|
|
1154
|
+
(generation === 0n || generationOf(current) === generation)
|
|
1155
|
+
) {
|
|
1011
1156
|
table.rows.set(key, finalize(row, generation, updatedAt));
|
|
1012
1157
|
this.bump(kind, meshName);
|
|
1013
1158
|
return stored(table.generations.get(key) ?? generation, updatedAt);
|
|
@@ -1053,8 +1198,11 @@ export class ZLinkInMemoryLocationStore implements
|
|
|
1053
1198
|
meshName: string | undefined
|
|
1054
1199
|
): ZLinkLocationWriteResult {
|
|
1055
1200
|
const current = table.rows.get(key);
|
|
1056
|
-
if (
|
|
1057
|
-
|
|
1201
|
+
if (
|
|
1202
|
+
current === undefined ||
|
|
1203
|
+
ownerOf(current) !== owner.ownerId ||
|
|
1204
|
+
generationOf(current) !== owner.leaseGeneration
|
|
1205
|
+
) {
|
|
1058
1206
|
return ignoredStale();
|
|
1059
1207
|
}
|
|
1060
1208
|
|
|
@@ -1133,10 +1281,16 @@ function validateMeshNodeDescriptor(descriptor: ZLinkMeshNodeDescriptor): void {
|
|
|
1133
1281
|
throw new TypeError('Only Object Server descriptors may publish an Entry Spot ID.');
|
|
1134
1282
|
}
|
|
1135
1283
|
const maxGeneration = 0x7fff_ffff_ffff_ffffn;
|
|
1136
|
-
if (
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1284
|
+
if (
|
|
1285
|
+
descriptor.lifecycleGeneration < 1n ||
|
|
1286
|
+
descriptor.lifecycleGeneration > maxGeneration ||
|
|
1287
|
+
descriptor.descriptorRevision < 1n ||
|
|
1288
|
+
descriptor.descriptorRevision > maxGeneration ||
|
|
1289
|
+
descriptor.leaseGeneration < 1n ||
|
|
1290
|
+
descriptor.leaseGeneration > maxGeneration ||
|
|
1291
|
+
descriptor.applicationVersion < 0n ||
|
|
1292
|
+
descriptor.applicationVersion > maxGeneration
|
|
1293
|
+
) {
|
|
1140
1294
|
throw new RangeError('MeshNode descriptor generations are invalid.');
|
|
1141
1295
|
}
|
|
1142
1296
|
const capacities = [
|
|
@@ -1144,22 +1298,26 @@ function validateMeshNodeDescriptor(descriptor: ZLinkMeshNodeDescriptor): void {
|
|
|
1144
1298
|
descriptor.populationCapacity.spots,
|
|
1145
1299
|
...descriptor.populationCapacity.spotTypes
|
|
1146
1300
|
];
|
|
1147
|
-
const values = capacities.flatMap(capacity =>
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
||
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1301
|
+
const values = capacities.flatMap((capacity) => [
|
|
1302
|
+
capacity.active,
|
|
1303
|
+
capacity.reserved,
|
|
1304
|
+
capacity.limit
|
|
1305
|
+
]);
|
|
1306
|
+
if (
|
|
1307
|
+
values.some((value) => !Number.isSafeInteger(value) || value < 0) ||
|
|
1308
|
+
capacities.some(
|
|
1309
|
+
(capacity) => capacity.active + capacity.reserved > capacity.limit && capacity.limit !== 0
|
|
1310
|
+
) ||
|
|
1311
|
+
!Number.isSafeInteger(descriptor.activationConcurrency.active) ||
|
|
1312
|
+
descriptor.activationConcurrency.active < 0 ||
|
|
1313
|
+
!Number.isSafeInteger(descriptor.activationConcurrency.limit) ||
|
|
1314
|
+
descriptor.activationConcurrency.limit < 1 ||
|
|
1315
|
+
descriptor.activationConcurrency.active > descriptor.activationConcurrency.limit ||
|
|
1316
|
+
descriptor.placementWeight < 0 ||
|
|
1317
|
+
descriptor.placementWeight > 10_000 ||
|
|
1318
|
+
descriptor.objectCapabilities.length > 1024 ||
|
|
1319
|
+
(descriptor.objectRole !== ZLinkObjectRole.Server && descriptor.objectCapabilities.length !== 0)
|
|
1320
|
+
) {
|
|
1163
1321
|
throw new RangeError('MeshNode object capacity is invalid.');
|
|
1164
1322
|
}
|
|
1165
1323
|
const keys = new Set<string>();
|
|
@@ -1173,8 +1331,11 @@ function validateMeshNodeDescriptor(descriptor: ZLinkMeshNodeDescriptor): void {
|
|
|
1173
1331
|
if ((capability.policy === 'snapshot') !== capability.hasSnapshotAdapter) {
|
|
1174
1332
|
throw new TypeError('Snapshot adapter presence does not match the maintenance policy.');
|
|
1175
1333
|
}
|
|
1176
|
-
if (
|
|
1177
|
-
|
|
1334
|
+
if (
|
|
1335
|
+
!Number.isSafeInteger(capability.limit) ||
|
|
1336
|
+
capability.limit < 0 ||
|
|
1337
|
+
(capability.objectKind === 'actor' && capability.limit !== 0)
|
|
1338
|
+
) {
|
|
1178
1339
|
throw new RangeError('MeshNode capability limit is invalid.');
|
|
1179
1340
|
}
|
|
1180
1341
|
}
|
|
@@ -1186,11 +1347,10 @@ function validDescriptorText(value: string): boolean {
|
|
|
1186
1347
|
}
|
|
1187
1348
|
|
|
1188
1349
|
function meshNodeImmutableFingerprint(descriptor: ZLinkMeshNodeDescriptor): string {
|
|
1189
|
-
const capabilities = [...descriptor.objectCapabilities]
|
|
1190
|
-
.
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
});
|
|
1350
|
+
const capabilities = [...descriptor.objectCapabilities].sort((left, right) => {
|
|
1351
|
+
const byKind = left.objectKind.localeCompare(right.objectKind);
|
|
1352
|
+
return byKind !== 0 ? byKind : left.stableType.localeCompare(right.stableType);
|
|
1353
|
+
});
|
|
1194
1354
|
return JSON.stringify({
|
|
1195
1355
|
meshName: descriptor.meshName,
|
|
1196
1356
|
rid: String(descriptor.rid),
|
|
@@ -1239,38 +1399,45 @@ interface InMemoryOwnerLease {
|
|
|
1239
1399
|
const TRANSFER_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
1240
1400
|
|
|
1241
1401
|
function meshNodeKey(meshName: string, rid: RoutingId): string {
|
|
1242
|
-
const value = typeof rid === 'string'
|
|
1243
|
-
? rid
|
|
1244
|
-
: (rid as unknown as { toHex(): string }).toHex();
|
|
1402
|
+
const value = typeof rid === 'string' ? rid : (rid as unknown as { toHex(): string }).toHex();
|
|
1245
1403
|
return `${meshName.length}:${meshName}:${value.length}:${value}`;
|
|
1246
1404
|
}
|
|
1247
1405
|
|
|
1248
1406
|
function clientServerKey(channelName: string, serverRid: RoutingId): string {
|
|
1249
|
-
const value =
|
|
1250
|
-
|
|
1251
|
-
|
|
1407
|
+
const value =
|
|
1408
|
+
typeof serverRid === 'string'
|
|
1409
|
+
? serverRid
|
|
1410
|
+
: (serverRid as unknown as { toHex(): string }).toHex();
|
|
1252
1411
|
return `${channelName.length}:${channelName}:${value.length}:${value}`;
|
|
1253
1412
|
}
|
|
1254
1413
|
|
|
1255
1414
|
function fanoutPublisherKey(channelName: string, publisherRid: RoutingId): string {
|
|
1256
|
-
const value =
|
|
1257
|
-
|
|
1258
|
-
|
|
1415
|
+
const value =
|
|
1416
|
+
typeof publisherRid === 'string'
|
|
1417
|
+
? publisherRid
|
|
1418
|
+
: (publisherRid as unknown as { toHex(): string }).toHex();
|
|
1259
1419
|
return `${channelName.length}:${channelName}:${value.length}:${value}`;
|
|
1260
1420
|
}
|
|
1261
1421
|
|
|
1262
1422
|
function validateClientServerDescriptor(descriptor: ZLinkClientServerServerDescriptor): void {
|
|
1263
|
-
if (
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1423
|
+
if (
|
|
1424
|
+
!validDescriptorText(descriptor.channelName) ||
|
|
1425
|
+
!validDescriptorText(String(descriptor.serverRid)) ||
|
|
1426
|
+
!validDescriptorText(descriptor.endpoint) ||
|
|
1427
|
+
!validDescriptorText(descriptor.securityIdentity) ||
|
|
1428
|
+
!validDescriptorText(descriptor.ownerId)
|
|
1429
|
+
) {
|
|
1268
1430
|
throw new TypeError('ClientServer descriptor identity and endpoint are required.');
|
|
1269
1431
|
}
|
|
1270
1432
|
const maxGeneration = 0x7fff_ffff_ffff_ffffn;
|
|
1271
|
-
if (
|
|
1272
|
-
|
|
1273
|
-
|
|
1433
|
+
if (
|
|
1434
|
+
descriptor.lifecycleGeneration < 1n ||
|
|
1435
|
+
descriptor.lifecycleGeneration > maxGeneration ||
|
|
1436
|
+
descriptor.descriptorRevision < 1n ||
|
|
1437
|
+
descriptor.descriptorRevision > maxGeneration ||
|
|
1438
|
+
descriptor.leaseGeneration < 1n ||
|
|
1439
|
+
descriptor.leaseGeneration > maxGeneration
|
|
1440
|
+
) {
|
|
1274
1441
|
throw new RangeError('ClientServer descriptor generations are invalid.');
|
|
1275
1442
|
}
|
|
1276
1443
|
if (!Number.isInteger(descriptor.weight) || descriptor.weight < 0 || descriptor.weight > 10_000) {
|
|
@@ -1300,17 +1467,24 @@ function clientServerDescriptorFingerprint(descriptor: ZLinkClientServerServerDe
|
|
|
1300
1467
|
}
|
|
1301
1468
|
|
|
1302
1469
|
function validateFanoutPublisherDescriptor(descriptor: ZLinkFanoutPublisherDescriptor): void {
|
|
1303
|
-
if (
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1470
|
+
if (
|
|
1471
|
+
!validDescriptorText(descriptor.channelName) ||
|
|
1472
|
+
!validDescriptorText(String(descriptor.publisherRid)) ||
|
|
1473
|
+
!validDescriptorText(descriptor.endpoint) ||
|
|
1474
|
+
!validDescriptorText(descriptor.securityIdentity) ||
|
|
1475
|
+
!validDescriptorText(descriptor.ownerId)
|
|
1476
|
+
) {
|
|
1308
1477
|
throw new TypeError('Fanout publisher descriptor identity and endpoint are required.');
|
|
1309
1478
|
}
|
|
1310
1479
|
const maxGeneration = 0x7fff_ffff_ffff_ffffn;
|
|
1311
|
-
if (
|
|
1312
|
-
|
|
1313
|
-
|
|
1480
|
+
if (
|
|
1481
|
+
descriptor.lifecycleGeneration < 1n ||
|
|
1482
|
+
descriptor.lifecycleGeneration > maxGeneration ||
|
|
1483
|
+
descriptor.descriptorRevision < 1n ||
|
|
1484
|
+
descriptor.descriptorRevision > maxGeneration ||
|
|
1485
|
+
descriptor.leaseGeneration < 1n ||
|
|
1486
|
+
descriptor.leaseGeneration > maxGeneration
|
|
1487
|
+
) {
|
|
1314
1488
|
throw new RangeError('Fanout publisher descriptor generations are invalid.');
|
|
1315
1489
|
}
|
|
1316
1490
|
}
|
|
@@ -1369,7 +1543,9 @@ function transferStored(record: ZLinkActorTransferRecord): ZLinkActorTransferWri
|
|
|
1369
1543
|
return { status: 'stored', record };
|
|
1370
1544
|
}
|
|
1371
1545
|
|
|
1372
|
-
function transferResult(
|
|
1546
|
+
function transferResult(
|
|
1547
|
+
status: ZLinkActorTransferWriteResult['status']
|
|
1548
|
+
): ZLinkActorTransferWriteResult {
|
|
1373
1549
|
return { status };
|
|
1374
1550
|
}
|
|
1375
1551
|
|
|
@@ -1390,7 +1566,8 @@ function pageRows<TRow>(
|
|
|
1390
1566
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
1391
1567
|
.map(([, row]) => row);
|
|
1392
1568
|
const offset = parseContinuationToken(page.continuationToken);
|
|
1393
|
-
const size =
|
|
1569
|
+
const size =
|
|
1570
|
+
page.pageSize !== undefined && page.pageSize > 0 ? page.pageSize : Number.MAX_SAFE_INTEGER;
|
|
1394
1571
|
const items = ordered.slice(offset, offset + size);
|
|
1395
1572
|
const nextOffset = offset + items.length;
|
|
1396
1573
|
return {
|
|
@@ -1406,9 +1583,8 @@ function pageValues<TRow>(
|
|
|
1406
1583
|
): ZLinkLocationPage<TRow> {
|
|
1407
1584
|
const ordered = [...rows].sort((left, right) => key(left).localeCompare(key(right)));
|
|
1408
1585
|
const offset = parseContinuationToken(page.continuationToken);
|
|
1409
|
-
const size =
|
|
1410
|
-
? page.pageSize
|
|
1411
|
-
: Number.MAX_SAFE_INTEGER;
|
|
1586
|
+
const size =
|
|
1587
|
+
page.pageSize !== undefined && page.pageSize > 0 ? page.pageSize : Number.MAX_SAFE_INTEGER;
|
|
1412
1588
|
const items = ordered.slice(offset, offset + size);
|
|
1413
1589
|
const nextOffset = offset + items.length;
|
|
1414
1590
|
return {
|
|
@@ -1438,7 +1614,11 @@ function ignoredStale(): ZLinkLocationWriteResult {
|
|
|
1438
1614
|
}
|
|
1439
1615
|
|
|
1440
1616
|
function rejectedConflict(): ZLinkLocationWriteResult {
|
|
1441
|
-
return {
|
|
1617
|
+
return {
|
|
1618
|
+
status: ZLinkLocationWriteStatus.RejectedConflict,
|
|
1619
|
+
generation: 0n,
|
|
1620
|
+
updatedAt: new Date(0)
|
|
1621
|
+
};
|
|
1442
1622
|
}
|
|
1443
1623
|
|
|
1444
1624
|
function canTakeOver(
|
|
@@ -1458,10 +1638,12 @@ function canTakeOver(
|
|
|
1458
1638
|
if (intent !== ZLinkLocationWriteIntent.NewClaim) {
|
|
1459
1639
|
return false;
|
|
1460
1640
|
}
|
|
1461
|
-
const ownerGone =
|
|
1462
|
-
|| currentLease.leaseExpiresAt.getTime() <= now.getTime();
|
|
1641
|
+
const ownerGone =
|
|
1642
|
+
currentLease === undefined || currentLease.leaseExpiresAt.getTime() <= now.getTime();
|
|
1463
1643
|
if (ownerGone) return true;
|
|
1464
|
-
return
|
|
1465
|
-
|
|
1466
|
-
|
|
1644
|
+
return (
|
|
1645
|
+
currentOwnerId === nextOwnerId &&
|
|
1646
|
+
currentLeaseGeneration !== nextLeaseGeneration &&
|
|
1647
|
+
currentLease.token.leaseGeneration === nextLeaseGeneration
|
|
1648
|
+
);
|
|
1467
1649
|
}
|