@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
|
@@ -12,10 +12,7 @@ import { ZLinkSpotKind } from '../../contracts/Spots';
|
|
|
12
12
|
import { ZLinkLocationKeyCodec } from './key-codec';
|
|
13
13
|
import { encodeAuthorityKey } from './authority-key-codec';
|
|
14
14
|
import { routingIdsEqual } from '../routing-id';
|
|
15
|
-
import type {
|
|
16
|
-
IZLinkLocationLifecycleRuntime,
|
|
17
|
-
ZLinkOwnershipLostEvent
|
|
18
|
-
} from './lifecycle-runtime';
|
|
15
|
+
import type { IZLinkLocationLifecycleRuntime, ZLinkOwnershipLostEvent } from './lifecycle-runtime';
|
|
19
16
|
|
|
20
17
|
export enum ZLinkActorClaimStatus {
|
|
21
18
|
Claimed = 'claimed',
|
|
@@ -145,7 +142,8 @@ export class ZLinkActorLocationClaims {
|
|
|
145
142
|
ownerNodeRid: actorRef.nodeRid,
|
|
146
143
|
ownerNodeGeneration,
|
|
147
144
|
spotId: row.spotKind === ZLinkSpotKind.Entry ? actorRef.nodeRid : row.spotId,
|
|
148
|
-
spotGeneration:
|
|
145
|
+
spotGeneration:
|
|
146
|
+
row.spotKind === ZLinkSpotKind.Entry ? ownerNodeGeneration : row.spotGeneration
|
|
149
147
|
}));
|
|
150
148
|
}
|
|
151
149
|
|
|
@@ -264,17 +262,21 @@ export class ZLinkActorLocationClaims {
|
|
|
264
262
|
}
|
|
265
263
|
|
|
266
264
|
owns(_actorType: string, actorId: string): boolean {
|
|
267
|
-
return this.actors.has(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
265
|
+
return this.actors.has(
|
|
266
|
+
ZLinkLocationKeyCodec.encodeActorKey({
|
|
267
|
+
meshName: this.entryMeshName,
|
|
268
|
+
actorId
|
|
269
|
+
})
|
|
270
|
+
);
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
snapshot(actorId: string): ZLinkActorLocation | undefined {
|
|
274
|
-
const tracked = this.actors.get(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
274
|
+
const tracked = this.actors.get(
|
|
275
|
+
ZLinkLocationKeyCodec.encodeActorKey({
|
|
276
|
+
meshName: this.entryMeshName,
|
|
277
|
+
actorId
|
|
278
|
+
})
|
|
279
|
+
);
|
|
278
280
|
return tracked === undefined ? undefined : { ...tracked.row };
|
|
279
281
|
}
|
|
280
282
|
|
|
@@ -289,10 +291,12 @@ export class ZLinkActorLocationClaims {
|
|
|
289
291
|
try {
|
|
290
292
|
const current = await this.actorStore.resolveActor(key);
|
|
291
293
|
if (this.actors.get(canonical) !== tracked) continue;
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
if (
|
|
295
|
+
current === undefined ||
|
|
296
|
+
current.ownerId !== owner.ownerId ||
|
|
297
|
+
(current.leaseGeneration !== tracked.row.leaseGeneration &&
|
|
298
|
+
current.leaseGeneration !== owner.leaseGeneration)
|
|
299
|
+
) {
|
|
296
300
|
if (this.actors.get(canonical) !== tracked) continue;
|
|
297
301
|
this.actors.delete(canonical);
|
|
298
302
|
await tracked.deactivate?.();
|
|
@@ -304,14 +308,13 @@ export class ZLinkActorLocationClaims {
|
|
|
304
308
|
continue;
|
|
305
309
|
}
|
|
306
310
|
if (this.actors.get(canonical) !== tracked) continue;
|
|
307
|
-
const result = await this.runtime.writeActor(
|
|
308
|
-
current,
|
|
309
|
-
ZLinkLocationWriteIntent.Takeover
|
|
310
|
-
);
|
|
311
|
+
const result = await this.runtime.writeActor(current, ZLinkLocationWriteIntent.Takeover);
|
|
311
312
|
if (result.status !== ZLinkLocationWriteStatus.Stored) {
|
|
312
|
-
failures.push(
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
failures.push(
|
|
314
|
+
new Error(
|
|
315
|
+
`Actor location recovery for '${tracked.row.actorId}' was rejected with status ${result.status}.`
|
|
316
|
+
)
|
|
317
|
+
);
|
|
315
318
|
continue;
|
|
316
319
|
}
|
|
317
320
|
if (this.actors.get(canonical) !== tracked) continue;
|
|
@@ -360,14 +363,16 @@ export class ZLinkActorLocationClaims {
|
|
|
360
363
|
if (result.status === ZLinkLocationWriteStatus.Stored) {
|
|
361
364
|
tracked.row = {
|
|
362
365
|
...candidate,
|
|
363
|
-
leaseGeneration:
|
|
364
|
-
?? candidate.leaseGeneration,
|
|
366
|
+
leaseGeneration:
|
|
367
|
+
this.runtime.currentOwnerToken?.leaseGeneration ?? candidate.leaseGeneration,
|
|
365
368
|
updatedAt: result.updatedAt
|
|
366
369
|
};
|
|
367
370
|
tracked.generation = result.generation;
|
|
368
371
|
return;
|
|
369
372
|
}
|
|
370
|
-
throw new Error(
|
|
373
|
+
throw new Error(
|
|
374
|
+
`Actor location renewal for '${actorId}' was rejected with status ${result.status}.`
|
|
375
|
+
);
|
|
371
376
|
}
|
|
372
377
|
|
|
373
378
|
private async releaseAuthority(
|
|
@@ -382,22 +387,27 @@ export class ZLinkActorLocationClaims {
|
|
|
382
387
|
const current = await store.readAuthority(key);
|
|
383
388
|
if (!matchesActorAuthority(current, actorRef, ownerToken)) return;
|
|
384
389
|
|
|
385
|
-
const result = await store.compareExchangeAuthority(
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
390
|
+
const result = await store.compareExchangeAuthority(key, current.storeVersion, {
|
|
391
|
+
kind: 'delete'
|
|
392
|
+
});
|
|
393
|
+
if (
|
|
394
|
+
result.kind === 'deleted' ||
|
|
395
|
+
(result.kind === 'conflict' && result.current.kind === 'missing')
|
|
396
|
+
) {
|
|
391
397
|
return;
|
|
392
398
|
}
|
|
393
|
-
if (
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
399
|
+
if (
|
|
400
|
+
result.kind === 'conflict' &&
|
|
401
|
+
result.current.kind === 'snapshot' &&
|
|
402
|
+
matchesActorAuthority(result.current, actorRef, ownerToken)
|
|
403
|
+
) {
|
|
404
|
+
const retry = await store.compareExchangeAuthority(key, result.current.storeVersion, {
|
|
405
|
+
kind: 'delete'
|
|
406
|
+
});
|
|
407
|
+
if (
|
|
408
|
+
retry.kind === 'deleted' ||
|
|
409
|
+
(retry.kind === 'conflict' && retry.current.kind === 'missing')
|
|
410
|
+
) {
|
|
401
411
|
return;
|
|
402
412
|
}
|
|
403
413
|
}
|
|
@@ -415,12 +425,14 @@ function matchesActorAuthority(
|
|
|
415
425
|
actorRef: ActorRef,
|
|
416
426
|
ownerToken: ZLinkLocationOwnerToken
|
|
417
427
|
): current is ZLinkAuthoritySnapshot {
|
|
418
|
-
return
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
428
|
+
return (
|
|
429
|
+
current.kind === 'snapshot' &&
|
|
430
|
+
current.ownerId === ownerToken.ownerId &&
|
|
431
|
+
current.ownerLeaseGeneration === ownerToken.leaseGeneration &&
|
|
432
|
+
current.allocation.state === 'active' &&
|
|
433
|
+
current.allocation.objectKind === 'actor' &&
|
|
434
|
+
current.objectGeneration === actorRef.objectGeneration &&
|
|
435
|
+
current.allocation.descriptor.meshName === actorRef.meshName &&
|
|
436
|
+
routingIdsEqual(current.allocation.descriptor.rid, actorRef.nodeRid)
|
|
437
|
+
);
|
|
426
438
|
}
|
|
@@ -7,10 +7,7 @@ import {
|
|
|
7
7
|
type ZLinkRouteLocation
|
|
8
8
|
} from './internal-location-contracts';
|
|
9
9
|
import { ZLinkLocationKeyCodec } from './key-codec';
|
|
10
|
-
import type {
|
|
11
|
-
IZLinkLocationLifecycleRuntime,
|
|
12
|
-
ZLinkOwnershipLostEvent
|
|
13
|
-
} from './lifecycle-runtime';
|
|
10
|
+
import type { IZLinkLocationLifecycleRuntime, ZLinkOwnershipLostEvent } from './lifecycle-runtime';
|
|
14
11
|
|
|
15
12
|
const encodeRoutingIdHex = ZLinkLocationKeyCodec.encodeRoutingIdHex;
|
|
16
13
|
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { createHash, timingSafeEqual } from 'node:crypto';
|
|
2
|
-
import type {
|
|
3
|
-
ZLinkLocationStore,
|
|
4
|
-
ZLinkStoreKey,
|
|
5
|
-
ZLinkStoreReadResult
|
|
6
|
-
} from '../../contracts';
|
|
2
|
+
import type { ZLinkLocationStore, ZLinkStoreKey, ZLinkStoreReadResult } from '../../contracts';
|
|
7
3
|
import type {
|
|
8
4
|
ZLinkAggregateFence,
|
|
9
5
|
ZLinkAggregatePrepareRequest
|
|
@@ -65,25 +61,19 @@ interface InventoryTree {
|
|
|
65
61
|
export class ZLinkAggregateInventoryStore {
|
|
66
62
|
constructor(private readonly provider: ZLinkLocationStore) {}
|
|
67
63
|
|
|
68
|
-
async store(
|
|
69
|
-
request: ZLinkAggregatePrepareRequest,
|
|
70
|
-
signal?: AbortSignal
|
|
71
|
-
): Promise<void> {
|
|
64
|
+
async store(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<void> {
|
|
72
65
|
const fence = aggregateFence(request);
|
|
73
66
|
const tree = buildTree(request);
|
|
74
|
-
await parallelForEach(tree.pages, WRITE_CONCURRENCY, async page => {
|
|
67
|
+
await parallelForEach(tree.pages, WRITE_CONCURRENCY, async (page) => {
|
|
75
68
|
const bytes = encode(page);
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
if (
|
|
70
|
+
page.entries.length > MAX_PAGE_ENTRIES ||
|
|
71
|
+
page.children.length > MAX_PAGE_ENTRIES ||
|
|
72
|
+
bytes.byteLength > MAX_PAGE_BYTES
|
|
73
|
+
) {
|
|
79
74
|
throw new Error('Aggregate inventory page exceeds its encoded bounds.');
|
|
80
75
|
}
|
|
81
|
-
await putImmutable(
|
|
82
|
-
this.provider,
|
|
83
|
-
pageKey(fence, page.level, page.index),
|
|
84
|
-
bytes,
|
|
85
|
-
signal
|
|
86
|
-
);
|
|
76
|
+
await putImmutable(this.provider, pageKey(fence, page.level, page.index), bytes, signal);
|
|
87
77
|
});
|
|
88
78
|
await putImmutable(this.provider, rootKey(fence), encode(tree.root), signal);
|
|
89
79
|
await this.read(fence, request.inventoryDigest, signal);
|
|
@@ -93,13 +83,15 @@ export class ZLinkAggregateInventoryStore {
|
|
|
93
83
|
fence: ZLinkAggregateFence,
|
|
94
84
|
expectedDeclaredDigest?: Uint8Array,
|
|
95
85
|
signal?: AbortSignal
|
|
96
|
-
): Promise<
|
|
97
|
-
readonly
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
86
|
+
): Promise<
|
|
87
|
+
readonly {
|
|
88
|
+
readonly authorityKey: string;
|
|
89
|
+
readonly expectedStoreVersion: string;
|
|
90
|
+
readonly ownerTransition: 'preserve' | 'newOwner';
|
|
91
|
+
readonly authorityPayloadSha256: string;
|
|
92
|
+
readonly membershipMutationSha256: string;
|
|
93
|
+
}[]
|
|
94
|
+
> {
|
|
103
95
|
const rootBytes = await requireFound(this.provider, rootKey(fence), signal);
|
|
104
96
|
if (rootBytes.byteLength > MAX_PAGE_BYTES) {
|
|
105
97
|
throw dataLost(fence, 'root exceeds 1 MiB');
|
|
@@ -107,17 +99,14 @@ export class ZLinkAggregateInventoryStore {
|
|
|
107
99
|
const root = decodeRoot(rootBytes);
|
|
108
100
|
validateRoot(root, fence);
|
|
109
101
|
if (
|
|
110
|
-
expectedDeclaredDigest !== undefined
|
|
111
|
-
|
|
102
|
+
expectedDeclaredDigest !== undefined &&
|
|
103
|
+
!sameHash(root.declaredDigest, expectedDeclaredDigest)
|
|
112
104
|
) {
|
|
113
105
|
throw dataLost(fence, 'declared digest does not match');
|
|
114
106
|
}
|
|
115
107
|
|
|
116
108
|
const entries: InventoryEntry[] = [];
|
|
117
|
-
const observedPageCounts = Array.from(
|
|
118
|
-
{ length: root.topLevel + 1 },
|
|
119
|
-
() => 0
|
|
120
|
-
);
|
|
109
|
+
const observedPageCounts = Array.from({ length: root.topLevel + 1 }, () => 0);
|
|
121
110
|
const visited = new Set<string>();
|
|
122
111
|
const readPage = async (reference: InventoryReference): Promise<void> => {
|
|
123
112
|
validateReference(reference, root, fence);
|
|
@@ -130,32 +119,29 @@ export class ZLinkAggregateInventoryStore {
|
|
|
130
119
|
signal
|
|
131
120
|
);
|
|
132
121
|
if (
|
|
133
|
-
bytes.byteLength > MAX_PAGE_BYTES
|
|
134
|
-
|
|
122
|
+
bytes.byteLength > MAX_PAGE_BYTES ||
|
|
123
|
+
!sameHash(reference.sha256, createHash('sha256').update(bytes).digest())
|
|
135
124
|
) {
|
|
136
125
|
throw dataLost(fence, 'page checksum is invalid');
|
|
137
126
|
}
|
|
138
127
|
const page = decodePage(bytes);
|
|
139
128
|
if (
|
|
140
|
-
page.level !== reference.level
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
129
|
+
page.level !== reference.level ||
|
|
130
|
+
page.index !== reference.index ||
|
|
131
|
+
page.startIndex !== reference.startIndex ||
|
|
132
|
+
page.entryCount !== reference.entryCount
|
|
144
133
|
) {
|
|
145
134
|
throw dataLost(fence, 'page metadata changed');
|
|
146
135
|
}
|
|
147
|
-
if (
|
|
148
|
-
page.entries.length > MAX_PAGE_ENTRIES
|
|
149
|
-
|| page.children.length > MAX_PAGE_ENTRIES
|
|
150
|
-
) {
|
|
136
|
+
if (page.entries.length > MAX_PAGE_ENTRIES || page.children.length > MAX_PAGE_ENTRIES) {
|
|
151
137
|
throw dataLost(fence, 'page entry bound is invalid');
|
|
152
138
|
}
|
|
153
139
|
observedPageCounts[page.level]!++;
|
|
154
140
|
if (page.level === 0) {
|
|
155
141
|
if (
|
|
156
|
-
page.entries.length < 1
|
|
157
|
-
|
|
158
|
-
|
|
142
|
+
page.entries.length < 1 ||
|
|
143
|
+
page.children.length !== 0 ||
|
|
144
|
+
page.entries.length !== page.entryCount
|
|
159
145
|
) {
|
|
160
146
|
throw dataLost(fence, 'leaf page bounds are invalid');
|
|
161
147
|
}
|
|
@@ -185,21 +171,16 @@ export class ZLinkAggregateInventoryStore {
|
|
|
185
171
|
};
|
|
186
172
|
let expectedStart = 0;
|
|
187
173
|
for (const reference of root.topPages) {
|
|
188
|
-
if (
|
|
189
|
-
reference.level !== root.topLevel
|
|
190
|
-
|| reference.startIndex !== expectedStart
|
|
191
|
-
) {
|
|
174
|
+
if (reference.level !== root.topLevel || reference.startIndex !== expectedStart) {
|
|
192
175
|
throw dataLost(fence, 'top page references are reordered');
|
|
193
176
|
}
|
|
194
177
|
await readPage(reference);
|
|
195
178
|
expectedStart += reference.entryCount;
|
|
196
179
|
}
|
|
197
180
|
if (
|
|
198
|
-
expectedStart !== root.totalCount
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
(count, level) => count !== root.pageCountsByLevel[level]
|
|
202
|
-
)
|
|
181
|
+
expectedStart !== root.totalCount ||
|
|
182
|
+
entries.length !== root.totalCount ||
|
|
183
|
+
observedPageCounts.some((count, level) => count !== root.pageCountsByLevel[level])
|
|
203
184
|
) {
|
|
204
185
|
throw dataLost(fence, 'page counts do not match the root');
|
|
205
186
|
}
|
|
@@ -220,7 +201,7 @@ export class ZLinkAggregateInventoryStore {
|
|
|
220
201
|
if (!sameHash(root.digest, digest.digest())) {
|
|
221
202
|
throw dataLost(fence, 'inventory digest does not match');
|
|
222
203
|
}
|
|
223
|
-
return entries.map(entry => ({ ...entry }));
|
|
204
|
+
return entries.map((entry) => ({ ...entry }));
|
|
224
205
|
}
|
|
225
206
|
}
|
|
226
207
|
|
|
@@ -239,10 +220,10 @@ function buildTree(request: ZLinkAggregatePrepareRequest): InventoryTree {
|
|
|
239
220
|
authorityPayloadSha256: sha256(participant.authorityPayload),
|
|
240
221
|
membershipMutationSha256: sha256(participant.membershipMutation)
|
|
241
222
|
}));
|
|
242
|
-
const keys = entries.map(entry => entry.authorityKey);
|
|
223
|
+
const keys = entries.map((entry) => entry.authorityKey);
|
|
243
224
|
if (
|
|
244
|
-
new Set(keys).size !== keys.length
|
|
245
|
-
|
|
225
|
+
new Set(keys).size !== keys.length ||
|
|
226
|
+
keys.some((key, index) => index > 0 && keys[index - 1]!.localeCompare(key) >= 0)
|
|
246
227
|
) {
|
|
247
228
|
throw new TypeError('Aggregate participants must be unique and canonically sorted.');
|
|
248
229
|
}
|
|
@@ -253,9 +234,9 @@ function buildTree(request: ZLinkAggregatePrepareRequest): InventoryTree {
|
|
|
253
234
|
let references = packLeafPages(entries, pages);
|
|
254
235
|
let level = 0;
|
|
255
236
|
while (
|
|
256
|
-
references.length > MAX_PAGE_ENTRIES
|
|
257
|
-
|
|
258
|
-
|
|
237
|
+
references.length > MAX_PAGE_ENTRIES ||
|
|
238
|
+
encode(rootCandidate(entries.length, level, references, pages, '', '')).byteLength >
|
|
239
|
+
MAX_PAGE_BYTES
|
|
259
240
|
) {
|
|
260
241
|
level++;
|
|
261
242
|
if (level >= MAX_TREE_LEVELS) {
|
|
@@ -370,27 +351,27 @@ function rootCandidate(
|
|
|
370
351
|
|
|
371
352
|
function validateRoot(root: InventoryRoot, fence: ZLinkAggregateFence): void {
|
|
372
353
|
if (
|
|
373
|
-
!Number.isSafeInteger(root.totalCount)
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
count => !Number.isSafeInteger(count) || count < 1 || count > root.totalCount
|
|
354
|
+
!Number.isSafeInteger(root.totalCount) ||
|
|
355
|
+
root.totalCount < 1 ||
|
|
356
|
+
!isSha256(root.digest) ||
|
|
357
|
+
!isSha256(root.declaredDigest) ||
|
|
358
|
+
!Number.isSafeInteger(root.topLevel) ||
|
|
359
|
+
root.topLevel < 0 ||
|
|
360
|
+
root.topLevel >= MAX_TREE_LEVELS ||
|
|
361
|
+
root.topPages.length < 1 ||
|
|
362
|
+
root.topPages.length > MAX_PAGE_ENTRIES ||
|
|
363
|
+
root.pageCountsByLevel.length !== root.topLevel + 1 ||
|
|
364
|
+
root.pageCountsByLevel.some(
|
|
365
|
+
(count) => !Number.isSafeInteger(count) || count < 1 || count > root.totalCount
|
|
385
366
|
)
|
|
386
367
|
) {
|
|
387
368
|
throw dataLost(fence, 'root metadata is invalid');
|
|
388
369
|
}
|
|
389
370
|
const leafPages = root.pageCountsByLevel[0]!;
|
|
390
371
|
if (
|
|
391
|
-
leafPages > root.totalCount
|
|
392
|
-
|
|
393
|
-
|
|
372
|
+
leafPages > root.totalCount ||
|
|
373
|
+
root.totalCount > leafPages * MAX_PAGE_ENTRIES ||
|
|
374
|
+
root.topPages.length !== root.pageCountsByLevel[root.topLevel]
|
|
394
375
|
) {
|
|
395
376
|
throw dataLost(fence, 'root page counts are invalid');
|
|
396
377
|
}
|
|
@@ -409,33 +390,29 @@ function validateReference(
|
|
|
409
390
|
fence: ZLinkAggregateFence
|
|
410
391
|
): void {
|
|
411
392
|
if (
|
|
412
|
-
!Number.isSafeInteger(reference.level)
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
393
|
+
!Number.isSafeInteger(reference.level) ||
|
|
394
|
+
reference.level < 0 ||
|
|
395
|
+
reference.level > root.topLevel ||
|
|
396
|
+
!Number.isSafeInteger(reference.index) ||
|
|
397
|
+
reference.index < 0 ||
|
|
398
|
+
!Number.isSafeInteger(reference.startIndex) ||
|
|
399
|
+
reference.startIndex < 0 ||
|
|
400
|
+
!Number.isSafeInteger(reference.entryCount) ||
|
|
401
|
+
reference.entryCount < 1 ||
|
|
402
|
+
!isSha256(reference.sha256)
|
|
422
403
|
) {
|
|
423
404
|
throw dataLost(fence, 'page reference is invalid');
|
|
424
405
|
}
|
|
425
406
|
}
|
|
426
407
|
|
|
427
|
-
function validateEntry(
|
|
428
|
-
entry: InventoryEntry,
|
|
429
|
-
index: number,
|
|
430
|
-
fence: ZLinkAggregateFence
|
|
431
|
-
): void {
|
|
408
|
+
function validateEntry(entry: InventoryEntry, index: number, fence: ZLinkAggregateFence): void {
|
|
432
409
|
if (
|
|
433
|
-
entry.index !== index
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
410
|
+
entry.index !== index ||
|
|
411
|
+
entry.authorityKey.length < 1 ||
|
|
412
|
+
entry.expectedStoreVersion.length < 1 ||
|
|
413
|
+
!['preserve', 'newOwner'].includes(entry.ownerTransition) ||
|
|
414
|
+
!isSha256(entry.authorityPayloadSha256) ||
|
|
415
|
+
!isSha256(entry.membershipMutationSha256)
|
|
439
416
|
) {
|
|
440
417
|
throw dataLost(fence, 'inventory entry is invalid or reordered');
|
|
441
418
|
}
|
|
@@ -447,16 +424,16 @@ async function putImmutable(
|
|
|
447
424
|
bytes: Uint8Array,
|
|
448
425
|
signal?: AbortSignal
|
|
449
426
|
): Promise<void> {
|
|
450
|
-
const result = await provider.write(
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
427
|
+
const result = await provider.write(
|
|
428
|
+
{
|
|
429
|
+
conditions: [{ kind: 'missing', key }],
|
|
430
|
+
mutations: [{ kind: 'put', key, bytes }]
|
|
431
|
+
},
|
|
432
|
+
signal
|
|
433
|
+
);
|
|
454
434
|
if (result.kind === 'applied') return;
|
|
455
435
|
const current = await provider.read(key, signal);
|
|
456
|
-
if (
|
|
457
|
-
current.kind !== 'found'
|
|
458
|
-
|| !Buffer.from(current.value.bytes).equals(Buffer.from(bytes))
|
|
459
|
-
) {
|
|
436
|
+
if (current.kind !== 'found' || !Buffer.from(current.value.bytes).equals(Buffer.from(bytes))) {
|
|
460
437
|
throw new Error(`Immutable aggregate inventory value changed: ${key.value}.`);
|
|
461
438
|
}
|
|
462
439
|
}
|
|
@@ -476,10 +453,10 @@ async function requireFound(
|
|
|
476
453
|
function decodeRoot(bytes: Uint8Array): InventoryRoot {
|
|
477
454
|
const value: unknown = JSON.parse(Buffer.from(bytes).toString('utf8'));
|
|
478
455
|
if (
|
|
479
|
-
value === null
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
456
|
+
value === null ||
|
|
457
|
+
typeof value !== 'object' ||
|
|
458
|
+
!('kind' in value) ||
|
|
459
|
+
value.kind !== 'aggregate-inventory-root-v1'
|
|
483
460
|
) {
|
|
484
461
|
throw new Error('Invalid inventory root.');
|
|
485
462
|
}
|
|
@@ -489,14 +466,14 @@ function decodeRoot(bytes: Uint8Array): InventoryRoot {
|
|
|
489
466
|
function decodePage(bytes: Uint8Array): InventoryPage {
|
|
490
467
|
const value: unknown = JSON.parse(Buffer.from(bytes).toString('utf8'));
|
|
491
468
|
if (
|
|
492
|
-
value === null
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
469
|
+
value === null ||
|
|
470
|
+
typeof value !== 'object' ||
|
|
471
|
+
!('kind' in value) ||
|
|
472
|
+
value.kind !== 'aggregate-inventory-page-v1' ||
|
|
473
|
+
!('entries' in value) ||
|
|
474
|
+
!Array.isArray(value.entries) ||
|
|
475
|
+
!('children' in value) ||
|
|
476
|
+
!Array.isArray(value.children)
|
|
500
477
|
) {
|
|
501
478
|
throw new Error('Invalid inventory page.');
|
|
502
479
|
}
|
|
@@ -507,10 +484,7 @@ function encode(value: unknown): Uint8Array {
|
|
|
507
484
|
return Buffer.from(JSON.stringify(value), 'utf8');
|
|
508
485
|
}
|
|
509
486
|
|
|
510
|
-
function referenceFor(
|
|
511
|
-
page: InventoryPage,
|
|
512
|
-
encoded: Uint8Array
|
|
513
|
-
): InventoryReference {
|
|
487
|
+
function referenceFor(page: InventoryPage, encoded: Uint8Array): InventoryReference {
|
|
514
488
|
return {
|
|
515
489
|
level: page.level,
|
|
516
490
|
index: page.index,
|
|
@@ -531,11 +505,7 @@ function rootKey(fence: ZLinkAggregateFence): ZLinkStoreKey {
|
|
|
531
505
|
return storeKey(`${aggregatePrefix(fence)}root`);
|
|
532
506
|
}
|
|
533
507
|
|
|
534
|
-
function pageKey(
|
|
535
|
-
fence: ZLinkAggregateFence,
|
|
536
|
-
level: number,
|
|
537
|
-
index: number
|
|
538
|
-
): ZLinkStoreKey {
|
|
508
|
+
function pageKey(fence: ZLinkAggregateFence, level: number, index: number): ZLinkStoreKey {
|
|
539
509
|
return storeKey(`${aggregatePrefix(fence)}page:${level}:${index}`);
|
|
540
510
|
}
|
|
541
511
|
|
|
@@ -552,9 +522,11 @@ function isSha256(value: unknown): value is string {
|
|
|
552
522
|
}
|
|
553
523
|
|
|
554
524
|
function sameHash(expected: string, actual: Uint8Array): boolean {
|
|
555
|
-
return
|
|
556
|
-
&&
|
|
557
|
-
|
|
525
|
+
return (
|
|
526
|
+
isSha256(expected) &&
|
|
527
|
+
actual.byteLength === 32 &&
|
|
528
|
+
timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(actual))
|
|
529
|
+
);
|
|
558
530
|
}
|
|
559
531
|
|
|
560
532
|
function dataLost(fence: ZLinkAggregateFence, reason: string): Error {
|
|
@@ -569,13 +541,12 @@ async function parallelForEach<T>(
|
|
|
569
541
|
operation: (value: T) => Promise<void>
|
|
570
542
|
): Promise<void> {
|
|
571
543
|
let next = 0;
|
|
572
|
-
await Promise.all(
|
|
573
|
-
{ length: Math.min(concurrency, values.length) },
|
|
574
|
-
async () => {
|
|
544
|
+
await Promise.all(
|
|
545
|
+
Array.from({ length: Math.min(concurrency, values.length) }, async () => {
|
|
575
546
|
while (next < values.length) {
|
|
576
547
|
const index = next++;
|
|
577
548
|
await operation(values[index]!);
|
|
578
549
|
}
|
|
579
|
-
}
|
|
580
|
-
)
|
|
550
|
+
})
|
|
551
|
+
);
|
|
581
552
|
}
|
|
@@ -17,9 +17,10 @@ export function encodeAuthorityKey(
|
|
|
17
17
|
} as ZLinkAuthorityKey;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export function decodeAuthorityKey(
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
export function decodeAuthorityKey(key: ZLinkAuthorityKey): {
|
|
21
|
+
readonly kind: ZLinkPlacementObjectKind;
|
|
22
|
+
readonly globalId: string;
|
|
23
|
+
} {
|
|
23
24
|
if (Buffer.byteLength(key.value, 'utf8') > 776) {
|
|
24
25
|
throw new TypeError('Authority key exceeds the encoded byte limit.');
|
|
25
26
|
}
|
|
@@ -70,11 +71,13 @@ function percentEncode(bytes: Uint8Array): string {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
function isUnreserved(byte: number): boolean {
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
return (
|
|
75
|
+
(byte >= 0x41 && byte <= 0x5a) ||
|
|
76
|
+
(byte >= 0x61 && byte <= 0x7a) ||
|
|
77
|
+
(byte >= 0x30 && byte <= 0x39) ||
|
|
78
|
+
byte === 0x2d ||
|
|
79
|
+
byte === 0x2e ||
|
|
80
|
+
byte === 0x5f ||
|
|
81
|
+
byte === 0x7e
|
|
82
|
+
);
|
|
80
83
|
}
|
|
@@ -82,19 +82,23 @@ export class ZLinkAutoConnectLoop {
|
|
|
82
82
|
if (this.changeStampStore?.getMeshNodeChangeStamp !== undefined && !lastTickFailed) {
|
|
83
83
|
try {
|
|
84
84
|
const stamp = await this.changeStampStore.getMeshNodeChangeStamp(this.meshName, signal);
|
|
85
|
-
const liveOwners =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
const liveOwners =
|
|
86
|
+
this.leaseTracker === undefined
|
|
87
|
+
? 0
|
|
88
|
+
: await this.leaseTracker.getLiveOwnerSetVersion(signal);
|
|
89
|
+
if (
|
|
90
|
+
this.lastStamp === stamp &&
|
|
91
|
+
this.lastLiveOwnerSetVersion === liveOwners &&
|
|
92
|
+
this.reconciler.localPublicationReady
|
|
93
|
+
) {
|
|
91
94
|
return;
|
|
92
95
|
}
|
|
93
96
|
const tickFailed = await this.runReconcile(signal);
|
|
94
|
-
if (!tickFailed)
|
|
95
|
-
this.
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
if (!tickFailed)
|
|
98
|
+
await this.lane.run(() => {
|
|
99
|
+
this.lastStamp = stamp;
|
|
100
|
+
this.lastLiveOwnerSetVersion = liveOwners;
|
|
101
|
+
});
|
|
98
102
|
return;
|
|
99
103
|
} catch {
|
|
100
104
|
// A failed stamp read degrades to a full reconcile tick.
|
|
@@ -127,5 +131,4 @@ export class ZLinkAutoConnectLoop {
|
|
|
127
131
|
.finally(() => this.scheduleNext());
|
|
128
132
|
}, this.options.pollingIntervalMs);
|
|
129
133
|
}
|
|
130
|
-
|
|
131
134
|
}
|