@zlink-systems/framework 0.21.0 → 0.23.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/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
- 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 +28 -22
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
- package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
- 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 +160 -130
- 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/contracts/index.d.ts +1 -0
- 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.d.ts +3 -0
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +134 -118
- 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 +12 -20
- 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 +46 -42
- 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.d.ts +1 -0
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -39
- 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/dispatch-error-details.d.ts +6 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
- package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
- package/dist/runtime/diagnostics/flow-context.js +2 -2
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +58 -42
- 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 -27
- 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.d.ts +4 -2
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +169 -144
- 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-session-binding-ingress-port.d.ts +1 -0
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -0
- package/dist/runtime/foundation/service-stateful-runtime.js +461 -439
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
- package/dist/runtime/foundation/service-topology-registry.js +105 -96
- 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 +245 -228
- 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/protocol/service_wire_pilot_codec.generated.js +20 -18
- 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 +209 -220
- 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.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +29 -21
- package/dist/runtime/spots/spot-actor-packet-drain.js +14 -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 +79 -86
- 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 +17 -15
- 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 +2 -3
- 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 +6 -6
- package/dist/runtime/spots/spot-timer.js +26 -30
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
- package/dist/runtime/streams/actor-session-binding-registry.js +168 -148
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +20 -17
- package/dist/runtime/streams/bound-session-response-target.js +8 -1
- package/dist/runtime/streams/bound-session-service.d.ts +1 -0
- package/dist/runtime/streams/bound-session-service.js +14 -12
- package/dist/runtime/streams/index.js +28 -20
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +52 -31
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.d.ts +5 -1
- package/dist/runtime/streams/protocol.js +68 -20
- package/dist/runtime/streams/session-actor-coordinator.js +37 -41
- package/dist/runtime/streams/session-context.d.ts +9 -2
- package/dist/runtime/streams/session-context.js +50 -32
- package/dist/runtime/streams/session-local-actors.d.ts +3 -1
- package/dist/runtime/streams/session-local-actors.js +17 -2
- 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.d.ts +1 -1
- package/dist/runtime/streams/stream-frame-factory.js +14 -7
- package/dist/runtime/streams/stream-session-runtime.js +112 -78
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +3 -3
- 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 +2 -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 +2 -2
- 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 +142 -134
- 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 +1 -32
- 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 +353 -326
- 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 +77 -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 +370 -390
- 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 +44 -44
- 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 +218 -206
- 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 +12 -47
- 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/dispatch-error-details.ts +62 -0
- package/src/runtime/diagnostics/flow-context.ts +18 -7
- 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 +107 -79
- 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 -55
- 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 +364 -396
- 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 +2 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1233 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +170 -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 +19 -18
- 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 +595 -564
- 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 +196 -148
- package/src/runtime/spots/spot-actor-packet-drain.ts +56 -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 +235 -222
- 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 +129 -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 +13 -18
- 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 +58 -47
- package/src/runtime/spots/spot-timer.ts +103 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +421 -292
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +8 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +60 -50
- package/src/runtime/streams/bound-session-response-target.ts +39 -9
- package/src/runtime/streams/bound-session-service.ts +52 -42
- package/src/runtime/streams/index.ts +183 -100
- package/src/runtime/streams/managed-stream.ts +123 -90
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +115 -46
- package/src/runtime/streams/session-actor-coordinator.ts +109 -93
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +96 -51
- package/src/runtime/streams/session-local-actors.ts +19 -3
- 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 +59 -40
- package/src/runtime/streams/stream-session-runtime.ts +317 -214
- package/src/runtime/workers/index.ts +68 -29
|
@@ -26,18 +26,12 @@ import {
|
|
|
26
26
|
type ServiceRelocationPublication
|
|
27
27
|
} from '../foundation/service-relocation-runtime';
|
|
28
28
|
import { putNewRelocationBlob } from '../locations/relocation-blob';
|
|
29
|
-
import {
|
|
30
|
-
decodeRoutingId,
|
|
31
|
-
encodeRoutingIdStorageHex,
|
|
32
|
-
routingIdWireHex
|
|
33
|
-
} from '../routing-id';
|
|
29
|
+
import { decodeRoutingId, encodeRoutingIdStorageHex, routingIdWireHex } from '../routing-id';
|
|
34
30
|
import {
|
|
35
31
|
decodeRelocatingActorAuthorityIdentity,
|
|
36
32
|
encodeActorAuthorityIdentity
|
|
37
33
|
} from './actor-authority-publication';
|
|
38
|
-
import {
|
|
39
|
-
replaceActorRelocationAuthorityApplicationPayload
|
|
40
|
-
} from './actor-authority-payload-codec';
|
|
34
|
+
import { replaceActorRelocationAuthorityApplicationPayload } from './actor-authority-payload-codec';
|
|
41
35
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
42
36
|
import { wrapFrameworkPayloadMessage } from '../messaging/payload-codec';
|
|
43
37
|
import {
|
|
@@ -50,16 +44,9 @@ import {
|
|
|
50
44
|
const RETENTION_MS = 24 * 60 * 60 * 1_000;
|
|
51
45
|
const ROOT_VERSION = 2;
|
|
52
46
|
const ROOT_MAGIC = Buffer.from('ZLJR');
|
|
53
|
-
const
|
|
54
|
-
const JOURNAL_INVENTORY_DOMAIN = Buffer.from(
|
|
55
|
-
'zlink-node-deferred-join-authority-v1\0',
|
|
56
|
-
'utf8'
|
|
57
|
-
);
|
|
47
|
+
const JOURNAL_INVENTORY_DOMAIN = Buffer.from('zlink-node-deferred-join-authority-v1\0', 'utf8');
|
|
58
48
|
|
|
59
|
-
export type ZLinkDeferredJoinDeliveryCursor =
|
|
60
|
-
| 'prepared'
|
|
61
|
-
| 'committed'
|
|
62
|
-
| 'delivered';
|
|
49
|
+
export type ZLinkDeferredJoinDeliveryCursor = 'prepared' | 'committed' | 'delivered';
|
|
63
50
|
|
|
64
51
|
export interface ZLinkDeferredJoinAcceptedRoot {
|
|
65
52
|
readonly authority: ZLinkAuthoritySnapshot;
|
|
@@ -94,21 +81,25 @@ export async function isDeferredJoinAcceptedRootPublication(
|
|
|
94
81
|
if (hasJournalRootMagic(read.bytes)) {
|
|
95
82
|
try {
|
|
96
83
|
const root = decodeRoot(read.bytes);
|
|
97
|
-
return
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
84
|
+
return (
|
|
85
|
+
expected.aggregateId === operationAggregateId(root.operationId) &&
|
|
86
|
+
expected.aggregateGeneration === root.actor.objectGeneration &&
|
|
87
|
+
expected.authorityKey === encodeAuthorityKey('actor', root.actor.actorId).value &&
|
|
88
|
+
expected.objectGeneration === root.actor.objectGeneration
|
|
89
|
+
);
|
|
101
90
|
} catch {
|
|
102
91
|
return false;
|
|
103
92
|
}
|
|
104
93
|
}
|
|
105
94
|
const root = await readCanonicalDeferredJoinRoot(relocation, read.bytes, signal);
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
return (
|
|
96
|
+
root !== undefined &&
|
|
97
|
+
root.identity.aggregateId === expected.aggregateId &&
|
|
98
|
+
root.identity.aggregateGeneration === expected.aggregateGeneration &&
|
|
99
|
+
root.identity.authorityKey === expected.authorityKey &&
|
|
100
|
+
root.identity.objectKind === expected.objectKind &&
|
|
101
|
+
root.identity.objectGeneration === expected.objectGeneration
|
|
102
|
+
);
|
|
112
103
|
}
|
|
113
104
|
|
|
114
105
|
interface DeferredJoinAuthorityPublication {
|
|
@@ -175,20 +166,20 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
175
166
|
} as const;
|
|
176
167
|
const initialPublication = decodeAuthorityPublication(read.payload);
|
|
177
168
|
const initialCanonicalIdentity = serviceRelocationAuthoritySlotIdentity(read.payload);
|
|
178
|
-
const canonicalPublication =
|
|
179
|
-
? initialPublication
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
169
|
+
const canonicalPublication =
|
|
170
|
+
initialPublication?.canonical === true ? initialPublication : undefined;
|
|
171
|
+
const root =
|
|
172
|
+
canonicalPublication !== undefined &&
|
|
173
|
+
(canonicalInventoryDigest !== undefined ||
|
|
174
|
+
!canonicalPublication.reference.value.startsWith('zlink-direct:'))
|
|
175
|
+
? await this.storeCanonicalRoot(
|
|
176
|
+
rootValue,
|
|
177
|
+
read,
|
|
178
|
+
canonicalPublication,
|
|
179
|
+
signal,
|
|
180
|
+
canonicalInventoryDigest
|
|
181
|
+
)
|
|
182
|
+
: await this.storeRoot(rootValue, signal);
|
|
192
183
|
if (initialCanonicalIdentity !== undefined && canonicalInventoryDigest !== undefined) {
|
|
193
184
|
return {
|
|
194
185
|
...root,
|
|
@@ -201,17 +192,19 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
201
192
|
const canonicalIdentity = serviceRelocationAuthoritySlotIdentity(expected.payload);
|
|
202
193
|
const publication: DeferredJoinAuthorityPublication = {
|
|
203
194
|
applicationPayload: Buffer.from(
|
|
204
|
-
currentPublication?.applicationPayload
|
|
205
|
-
|
|
195
|
+
currentPublication?.applicationPayload ??
|
|
196
|
+
serviceRelocationAuthorityApplicationPayload(expected.payload)
|
|
206
197
|
),
|
|
207
198
|
reference: root.reference,
|
|
208
199
|
checksumCrc32c: root.checksumCrc32c,
|
|
209
|
-
aggregateId:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
200
|
+
aggregateId:
|
|
201
|
+
canonicalIdentity !== undefined
|
|
202
|
+
? canonicalIdentity.aggregateId
|
|
203
|
+
: operationAggregateId(operationId),
|
|
204
|
+
aggregateGeneration:
|
|
205
|
+
canonicalIdentity === undefined
|
|
206
|
+
? actor.objectGeneration
|
|
207
|
+
: requireCanonicalAggregateGeneration(canonicalIdentity.aggregateGeneration),
|
|
215
208
|
targetOwnerId: expected.ownerId,
|
|
216
209
|
targetOwnerLeaseGeneration: expected.ownerLeaseGeneration,
|
|
217
210
|
...(currentPublication?.canonicalPublication === undefined
|
|
@@ -224,15 +217,16 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
224
217
|
{
|
|
225
218
|
kind: 'put',
|
|
226
219
|
generationTransition: 'preserve',
|
|
227
|
-
payload:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
220
|
+
payload:
|
|
221
|
+
currentPublication === undefined && canonicalIdentity !== undefined
|
|
222
|
+
? new ServiceRelocationAuthorityPayloadCodec().publish(
|
|
223
|
+
expected.payload,
|
|
224
|
+
toServiceRelocationPublication(publication)
|
|
225
|
+
)
|
|
226
|
+
: replaceDeferredJoinAuthorityPublication(
|
|
227
|
+
expected.payload,
|
|
228
|
+
encodeAuthorityPublication(publication)
|
|
229
|
+
)
|
|
236
230
|
},
|
|
237
231
|
signal
|
|
238
232
|
);
|
|
@@ -263,13 +257,8 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
263
257
|
actorId: string,
|
|
264
258
|
signal?: AbortSignal
|
|
265
259
|
): Promise<ZLinkDeferredJoinAcceptedRoot | undefined> {
|
|
266
|
-
const read = await this.authority.readAuthority(
|
|
267
|
-
|
|
268
|
-
signal
|
|
269
|
-
);
|
|
270
|
-
return read.kind === 'snapshot'
|
|
271
|
-
? await this.readPublished(read, signal)
|
|
272
|
-
: undefined;
|
|
260
|
+
const read = await this.authority.readAuthority(encodeAuthorityKey('actor', actorId), signal);
|
|
261
|
+
return read.kind === 'snapshot' ? await this.readPublished(read, signal) : undefined;
|
|
273
262
|
}
|
|
274
263
|
|
|
275
264
|
markCommitted(
|
|
@@ -288,10 +277,7 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
288
277
|
return this.moveCursor(root, 'delivered', undefined, signal);
|
|
289
278
|
}
|
|
290
279
|
|
|
291
|
-
async discardPrepared(
|
|
292
|
-
root: ZLinkDeferredJoinAcceptedRoot,
|
|
293
|
-
signal?: AbortSignal
|
|
294
|
-
): Promise<void> {
|
|
280
|
+
async discardPrepared(root: ZLinkDeferredJoinAcceptedRoot, signal?: AbortSignal): Promise<void> {
|
|
295
281
|
const key = encodeAuthorityKey('actor', root.actor.actorId);
|
|
296
282
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
297
283
|
const read = await this.authority.readAuthority(key, signal);
|
|
@@ -320,7 +306,9 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
320
306
|
return;
|
|
321
307
|
}
|
|
322
308
|
}
|
|
323
|
-
throw new Error(
|
|
309
|
+
throw new Error(
|
|
310
|
+
`Actor '${root.actor.actorId}' deferred Join preparation could not be discarded.`
|
|
311
|
+
);
|
|
324
312
|
}
|
|
325
313
|
|
|
326
314
|
async deliver(
|
|
@@ -349,17 +337,18 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
349
337
|
status: 'accepted',
|
|
350
338
|
operationId: current.operationId,
|
|
351
339
|
actor: current.actor,
|
|
352
|
-
reply:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
340
|
+
reply:
|
|
341
|
+
current.rawReply.byteLength === 0
|
|
342
|
+
? undefined
|
|
343
|
+
: current.replyContentType === undefined
|
|
344
|
+
? ZLinkMessage.fromEncoded(ZLinkEncodedPayload.from(current.rawReply))
|
|
345
|
+
: wrapFrameworkPayloadMessage(
|
|
346
|
+
RuntimeMessage.from(current.rawReply),
|
|
347
|
+
this.messageSerializers,
|
|
348
|
+
current.replyContentType,
|
|
349
|
+
undefined,
|
|
350
|
+
'reply'
|
|
351
|
+
)
|
|
363
352
|
};
|
|
364
353
|
await actor.onJoinCompleted?.(completion);
|
|
365
354
|
let delivered = current;
|
|
@@ -388,9 +377,7 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
388
377
|
if (current === undefined) return;
|
|
389
378
|
requireSameOperation(current, root.operationId, root.actor);
|
|
390
379
|
if (current.cursor !== 'delivered') {
|
|
391
|
-
throw new Error(
|
|
392
|
-
`Actor '${root.actor.actorId}' Join completion root is not Delivered.`
|
|
393
|
-
);
|
|
380
|
+
throw new Error(`Actor '${root.actor.actorId}' Join completion root is not Delivered.`);
|
|
394
381
|
}
|
|
395
382
|
const publication = decodeAuthorityPublication(read.payload);
|
|
396
383
|
if (publication === undefined) return;
|
|
@@ -433,27 +420,22 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
433
420
|
const key = encodeAuthorityKey('actor', root.actor.actorId);
|
|
434
421
|
const read = await this.authority.readAuthority(key, signal);
|
|
435
422
|
if (read.kind !== 'snapshot') {
|
|
436
|
-
throw new Error(
|
|
423
|
+
throw new Error(
|
|
424
|
+
`Actor '${root.actor.actorId}' authority disappeared during Join completion.`
|
|
425
|
+
);
|
|
437
426
|
}
|
|
438
427
|
let current = await this.readPublished(read, signal);
|
|
439
428
|
if (current === undefined) {
|
|
440
429
|
const retainedRoot = await this.relocation.read(root.reference, signal);
|
|
441
|
-
if (
|
|
442
|
-
retainedRoot.kind === 'found'
|
|
443
|
-
&& crc32c(retainedRoot.bytes) === root.checksumCrc32c
|
|
444
|
-
) {
|
|
430
|
+
if (retainedRoot.kind === 'found' && crc32c(retainedRoot.bytes) === root.checksumCrc32c) {
|
|
445
431
|
const retained = hasJournalRootMagic(retainedRoot.bytes)
|
|
446
432
|
? decodeRoot(retainedRoot.bytes)
|
|
447
|
-
: (await readCanonicalDeferredJoinRoot(
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
{ ...root, ...retained },
|
|
454
|
-
root.operationId,
|
|
455
|
-
root.actor
|
|
456
|
-
)) {
|
|
433
|
+
: (await readCanonicalDeferredJoinRoot(this.relocation, retainedRoot.bytes, signal))
|
|
434
|
+
?.completion;
|
|
435
|
+
if (
|
|
436
|
+
retained?.cursor === 'delivered' &&
|
|
437
|
+
isSameOperation({ ...root, ...retained }, root.operationId, root.actor)
|
|
438
|
+
) {
|
|
457
439
|
current = {
|
|
458
440
|
authority: read,
|
|
459
441
|
reference: root.reference,
|
|
@@ -462,33 +444,39 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
462
444
|
};
|
|
463
445
|
}
|
|
464
446
|
}
|
|
465
|
-
if (
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
447
|
+
if (
|
|
448
|
+
current === undefined &&
|
|
449
|
+
next === 'committed' &&
|
|
450
|
+
actor !== undefined &&
|
|
451
|
+
authorityMatchesActor(read.payload, actor)
|
|
469
452
|
) {
|
|
470
453
|
throw new ZLinkFrameworkException(
|
|
471
454
|
ZLinkFrameworkErrorKind.Unavailable,
|
|
472
|
-
`Actor '${root.actor.actorId}' Join completion delivery is indeterminate: `
|
|
473
|
-
|
|
455
|
+
`Actor '${root.actor.actorId}' Join completion delivery is indeterminate: ` +
|
|
456
|
+
'the authority no longer references the operation and no matching retained root exists.'
|
|
474
457
|
);
|
|
475
458
|
}
|
|
476
459
|
if (current === undefined) {
|
|
477
|
-
throw new Error(
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Actor '${root.actor.actorId}' no longer references its Join completion root.`
|
|
462
|
+
);
|
|
478
463
|
}
|
|
479
464
|
}
|
|
480
465
|
requireSameOperation(current, root.operationId, root.actor);
|
|
481
466
|
if (cursorIndex(current.cursor) >= nextIndex) return current;
|
|
482
467
|
|
|
483
|
-
const replacement = await this.storeRoot(
|
|
484
|
-
|
|
468
|
+
const replacement = await this.storeRoot(
|
|
469
|
+
{
|
|
470
|
+
operationId: current.operationId,
|
|
485
471
|
actor: actor ?? current.actor,
|
|
486
472
|
rawReply: current.rawReply,
|
|
487
473
|
...(current.replyContentType === undefined
|
|
488
474
|
? {}
|
|
489
475
|
: { replyContentType: current.replyContentType }),
|
|
490
476
|
cursor: next
|
|
491
|
-
|
|
477
|
+
},
|
|
478
|
+
signal
|
|
479
|
+
);
|
|
492
480
|
const publication = decodeAuthorityPublication(read.payload);
|
|
493
481
|
if (publication === undefined) {
|
|
494
482
|
await this.deleteBestEffort(replacement.reference);
|
|
@@ -512,12 +500,13 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
512
500
|
read.payload,
|
|
513
501
|
encodeAuthorityPublication({
|
|
514
502
|
...publication,
|
|
515
|
-
applicationPayload:
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
503
|
+
applicationPayload:
|
|
504
|
+
actor === undefined
|
|
505
|
+
? publication.applicationPayload
|
|
506
|
+
: replaceActorRelocationAuthorityApplicationPayload(
|
|
507
|
+
publication.applicationPayload,
|
|
508
|
+
encodeActorAuthorityIdentity({ ...identity, actor })
|
|
509
|
+
),
|
|
521
510
|
reference: replacement.reference,
|
|
522
511
|
checksumCrc32c: replacement.checksumCrc32c
|
|
523
512
|
})
|
|
@@ -553,31 +542,31 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
553
542
|
const canonicalPhase = publication.canonicalPublication?.canonicalPhase;
|
|
554
543
|
if (canonicalPhase === 1 || canonicalPhase === 2) return undefined;
|
|
555
544
|
const read = await this.relocation.read(publication.reference, signal);
|
|
556
|
-
if (read.kind !== 'found' && publication.canonical === true
|
|
557
|
-
&& publication.reference.value.startsWith('zlink-direct:')) {
|
|
558
|
-
return undefined;
|
|
559
|
-
}
|
|
560
545
|
if (
|
|
561
|
-
read.kind !== 'found'
|
|
562
|
-
|
|
546
|
+
read.kind !== 'found' &&
|
|
547
|
+
publication.canonical === true &&
|
|
548
|
+
publication.reference.value.startsWith('zlink-direct:')
|
|
563
549
|
) {
|
|
550
|
+
return undefined;
|
|
551
|
+
}
|
|
552
|
+
if (read.kind !== 'found' || crc32c(read.bytes) !== publication.checksumCrc32c) {
|
|
564
553
|
throw new Error('Published deferred Join completion root is missing or corrupt.');
|
|
565
554
|
}
|
|
566
555
|
if (publication.canonical === true && !hasJournalRootMagic(read.bytes)) {
|
|
567
|
-
const root = await readCanonicalDeferredJoinRoot(
|
|
568
|
-
this.relocation,
|
|
569
|
-
read.bytes,
|
|
570
|
-
signal
|
|
571
|
-
);
|
|
556
|
+
const root = await readCanonicalDeferredJoinRoot(this.relocation, read.bytes, signal);
|
|
572
557
|
if (root === undefined) {
|
|
573
558
|
// A canonical relocation root and the post-commit Join journal share
|
|
574
559
|
// the embedded slot. A root without a completion remains Host-owned.
|
|
575
560
|
return undefined;
|
|
576
561
|
}
|
|
577
|
-
if (
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
562
|
+
if (
|
|
563
|
+
root.identity.aggregateId !== publication.aggregateId ||
|
|
564
|
+
root.identity.aggregateGeneration !== publication.aggregateGeneration ||
|
|
565
|
+
root.identity.objectGeneration !== authority.objectGeneration
|
|
566
|
+
) {
|
|
567
|
+
throw new Error(
|
|
568
|
+
'Published deferred Join completion root identity does not match its authority slot.'
|
|
569
|
+
);
|
|
581
570
|
}
|
|
582
571
|
return {
|
|
583
572
|
authority,
|
|
@@ -595,31 +584,18 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
595
584
|
}
|
|
596
585
|
|
|
597
586
|
private async storeRoot(
|
|
598
|
-
value: Omit<
|
|
599
|
-
ZLinkDeferredJoinAcceptedRoot,
|
|
600
|
-
'authority' | 'reference' | 'checksumCrc32c'
|
|
601
|
-
>,
|
|
587
|
+
value: Omit<ZLinkDeferredJoinAcceptedRoot, 'authority' | 'reference' | 'checksumCrc32c'>,
|
|
602
588
|
signal?: AbortSignal
|
|
603
589
|
): Promise<Omit<ZLinkDeferredJoinAcceptedRoot, 'authority'>> {
|
|
604
590
|
const payload = encodeRoot(value);
|
|
605
591
|
const checksumCrc32c = crc32c(payload);
|
|
606
|
-
const stored = await putNewRelocationBlob(
|
|
607
|
-
|
|
608
|
-
payload,
|
|
609
|
-
RETENTION_MS,
|
|
610
|
-
signal
|
|
611
|
-
);
|
|
612
|
-
if (
|
|
613
|
-
stored.expiresAt.getTime() <= stored.storeNow.getTime()
|
|
614
|
-
) {
|
|
592
|
+
const stored = await putNewRelocationBlob(this.relocation, payload, RETENTION_MS, signal);
|
|
593
|
+
if (stored.expiresAt.getTime() <= stored.storeNow.getTime()) {
|
|
615
594
|
await this.deleteBestEffort(stored.reference);
|
|
616
595
|
throw new Error('Relocation Store returned an invalid deferred Join root receipt.');
|
|
617
596
|
}
|
|
618
597
|
const read = await this.relocation.read(stored.reference, signal);
|
|
619
|
-
if (
|
|
620
|
-
read.kind !== 'found'
|
|
621
|
-
|| !Buffer.from(read.bytes).equals(payload)
|
|
622
|
-
) {
|
|
598
|
+
if (read.kind !== 'found' || !Buffer.from(read.bytes).equals(payload)) {
|
|
623
599
|
await this.deleteBestEffort(stored.reference);
|
|
624
600
|
throw new Error('Relocation Store failed deferred Join root verification.');
|
|
625
601
|
}
|
|
@@ -632,10 +608,7 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
632
608
|
}
|
|
633
609
|
|
|
634
610
|
private async storeCanonicalRoot(
|
|
635
|
-
value: Omit<
|
|
636
|
-
ZLinkDeferredJoinAcceptedRoot,
|
|
637
|
-
'authority' | 'reference' | 'checksumCrc32c'
|
|
638
|
-
>,
|
|
611
|
+
value: Omit<ZLinkDeferredJoinAcceptedRoot, 'authority' | 'reference' | 'checksumCrc32c'>,
|
|
639
612
|
authority: ZLinkAuthoritySnapshot,
|
|
640
613
|
publication: DeferredJoinAuthorityPublication,
|
|
641
614
|
signal?: AbortSignal,
|
|
@@ -649,24 +622,13 @@ export class ZLinkDeferredJoinAcceptedJournal {
|
|
|
649
622
|
inventory = Buffer.from(canonicalInventoryDigest, 'hex');
|
|
650
623
|
} else {
|
|
651
624
|
const current = await this.relocation.read(publication.reference, signal);
|
|
652
|
-
if (current.kind !== 'found'
|
|
653
|
-
|| crc32c(current.bytes) !== publication.checksumCrc32c) {
|
|
625
|
+
if (current.kind !== 'found' || crc32c(current.bytes) !== publication.checksumCrc32c) {
|
|
654
626
|
throw new Error('Canonical relocation manifest is missing or corrupt.');
|
|
655
627
|
}
|
|
656
628
|
inventory = decodeCanonicalTreeManifest(current.bytes).inventoryDigest;
|
|
657
629
|
}
|
|
658
|
-
const logicalRoot = encodeCanonicalDeferredJoinRoot(
|
|
659
|
-
|
|
660
|
-
authority,
|
|
661
|
-
publication,
|
|
662
|
-
inventory
|
|
663
|
-
);
|
|
664
|
-
const stored = await storeCanonicalTree(
|
|
665
|
-
this.relocation,
|
|
666
|
-
logicalRoot,
|
|
667
|
-
inventory,
|
|
668
|
-
signal
|
|
669
|
-
);
|
|
630
|
+
const logicalRoot = encodeCanonicalDeferredJoinRoot(value, authority, publication, inventory);
|
|
631
|
+
const stored = await storeCanonicalTree(this.relocation, logicalRoot, inventory, signal);
|
|
670
632
|
return {
|
|
671
633
|
...value,
|
|
672
634
|
rawReply: Buffer.from(value.rawReply),
|
|
@@ -692,75 +654,70 @@ function requireAuthorityActor(payload: Uint8Array, actor: ActorRef): void {
|
|
|
692
654
|
|
|
693
655
|
function authorityMatchesActor(payload: Uint8Array, actor: ActorRef): boolean {
|
|
694
656
|
const publication = decodeAuthorityPublication(payload);
|
|
695
|
-
const applications =
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
actor.objectGeneration
|
|
657
|
+
const applications =
|
|
658
|
+
publication === undefined
|
|
659
|
+
? [serviceRelocationAuthorityApplicationPayload(payload)]
|
|
660
|
+
: [publication.applicationPayload, serviceRelocationAuthorityApplicationPayload(payload)];
|
|
661
|
+
return applications.some((application) => {
|
|
662
|
+
const identity = decodeRelocatingActorAuthorityIdentity(application, actor.objectGeneration);
|
|
663
|
+
return (
|
|
664
|
+
identity !== undefined &&
|
|
665
|
+
identity.actor.actorId === actor.actorId &&
|
|
666
|
+
identity.actor.objectGeneration === actor.objectGeneration &&
|
|
667
|
+
routingIdWireHex(identity.actor.nodeRid) === routingIdWireHex(actor.nodeRid)
|
|
705
668
|
);
|
|
706
|
-
return identity !== undefined
|
|
707
|
-
&& identity.actor.actorId === actor.actorId
|
|
708
|
-
&& identity.actor.objectGeneration === actor.objectGeneration
|
|
709
|
-
&& routingIdWireHex(identity.actor.nodeRid) === routingIdWireHex(actor.nodeRid);
|
|
710
669
|
});
|
|
711
670
|
}
|
|
712
671
|
|
|
713
672
|
function encodeRoot(
|
|
714
|
-
value: Omit<
|
|
715
|
-
ZLinkDeferredJoinAcceptedRoot,
|
|
716
|
-
'authority' | 'reference' | 'checksumCrc32c'
|
|
717
|
-
>
|
|
673
|
+
value: Omit<ZLinkDeferredJoinAcceptedRoot, 'authority' | 'reference' | 'checksumCrc32c'>
|
|
718
674
|
): Buffer {
|
|
719
675
|
const nodeRidHex = routingIdWireHex(value.actor.nodeRid);
|
|
720
|
-
const encoded = Buffer.concat([
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
676
|
+
const encoded = Buffer.concat([
|
|
677
|
+
ROOT_MAGIC,
|
|
678
|
+
Buffer.from(
|
|
679
|
+
JSON.stringify({
|
|
680
|
+
version: ROOT_VERSION,
|
|
681
|
+
operationHigh: value.operationId.high.toString(),
|
|
682
|
+
operationLow: value.operationId.low.toString(),
|
|
683
|
+
actorId: value.actor.actorId,
|
|
684
|
+
actorGeneration: value.actor.objectGeneration.toString(),
|
|
685
|
+
actorMeshName: value.actor.meshName,
|
|
686
|
+
actorNodeRid: String(value.actor.nodeRid),
|
|
687
|
+
actorNodeRidHex: nodeRidHex,
|
|
688
|
+
rawReply: Buffer.from(value.rawReply).toString('base64'),
|
|
689
|
+
...(value.replyContentType === undefined
|
|
690
|
+
? {}
|
|
691
|
+
: { replyContentType: value.replyContentType }),
|
|
692
|
+
cursor: value.cursor
|
|
693
|
+
}),
|
|
694
|
+
'utf8'
|
|
695
|
+
)
|
|
696
|
+
]);
|
|
738
697
|
return encoded;
|
|
739
698
|
}
|
|
740
699
|
|
|
741
700
|
function decodeRoot(
|
|
742
701
|
payload: Uint8Array
|
|
743
702
|
): Omit<ZLinkDeferredJoinAcceptedRoot, 'authority' | 'reference' | 'checksumCrc32c'> {
|
|
744
|
-
if (payload.byteLength === 0
|
|
745
|
-
throw new Error('Deferred Join completion root
|
|
703
|
+
if (payload.byteLength === 0) {
|
|
704
|
+
throw new Error('Deferred Join completion root is empty.');
|
|
746
705
|
}
|
|
747
706
|
const bytes = Buffer.from(payload);
|
|
748
|
-
const encoded = hasJournalRootMagic(bytes)
|
|
749
|
-
? bytes.subarray(ROOT_MAGIC.byteLength)
|
|
750
|
-
: bytes;
|
|
707
|
+
const encoded = hasJournalRootMagic(bytes) ? bytes.subarray(ROOT_MAGIC.byteLength) : bytes;
|
|
751
708
|
const value = JSON.parse(encoded.toString('utf8')) as Record<string, unknown>;
|
|
752
709
|
if (
|
|
753
|
-
value.version !== ROOT_VERSION
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
710
|
+
value.version !== ROOT_VERSION ||
|
|
711
|
+
typeof value.operationHigh !== 'string' ||
|
|
712
|
+
typeof value.operationLow !== 'string' ||
|
|
713
|
+
typeof value.actorId !== 'string' ||
|
|
714
|
+
typeof value.actorGeneration !== 'string' ||
|
|
715
|
+
typeof value.actorMeshName !== 'string' ||
|
|
716
|
+
typeof value.actorNodeRid !== 'string' ||
|
|
717
|
+
typeof value.rawReply !== 'string' ||
|
|
718
|
+
(value.replyContentType !== undefined &&
|
|
719
|
+
(typeof value.replyContentType !== 'string' || value.replyContentType.length === 0)) ||
|
|
720
|
+
!isCursor(value.cursor)
|
|
764
721
|
) {
|
|
765
722
|
throw new Error('Deferred Join completion root is invalid.');
|
|
766
723
|
}
|
|
@@ -795,10 +752,12 @@ function decodeRoot(
|
|
|
795
752
|
}
|
|
796
753
|
|
|
797
754
|
function encodeAuthorityPublication(value: DeferredJoinAuthorityPublication): Buffer {
|
|
798
|
-
return Buffer.from(
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
755
|
+
return Buffer.from(
|
|
756
|
+
new ServiceRelocationAuthorityPayloadCodec().publish(
|
|
757
|
+
value.applicationPayload,
|
|
758
|
+
toServiceRelocationPublication(value)
|
|
759
|
+
)
|
|
760
|
+
);
|
|
802
761
|
}
|
|
803
762
|
|
|
804
763
|
function toServiceRelocationPublication(
|
|
@@ -837,10 +796,7 @@ function replaceDeferredJoinAuthorityPublication(
|
|
|
837
796
|
const codec = new ServiceRelocationAuthorityPayloadCodec();
|
|
838
797
|
const currentPublication = codec.read(payload);
|
|
839
798
|
const replacementPublication = codec.read(replacement);
|
|
840
|
-
if (
|
|
841
|
-
currentPublication?.canonical === true
|
|
842
|
-
|| replacementPublication?.canonical === true
|
|
843
|
-
) {
|
|
799
|
+
if (currentPublication?.canonical === true || replacementPublication?.canonical === true) {
|
|
844
800
|
// Canonical authority has exactly one embedded relocation slot. A journal
|
|
845
801
|
// cursor replaces that slot atomically; it must never be wrapped or nested
|
|
846
802
|
// under an older ZLAR/application layer.
|
|
@@ -848,8 +804,8 @@ function replaceDeferredJoinAuthorityPublication(
|
|
|
848
804
|
}
|
|
849
805
|
const outerApplication = serviceRelocationAuthorityApplicationPayload(payload);
|
|
850
806
|
if (
|
|
851
|
-
!Buffer.from(outerApplication).equals(Buffer.from(payload))
|
|
852
|
-
|
|
807
|
+
!Buffer.from(outerApplication).equals(Buffer.from(payload)) &&
|
|
808
|
+
decodeDirectAuthorityPublication(outerApplication) !== undefined
|
|
853
809
|
) {
|
|
854
810
|
return replaceServiceRelocationAuthorityApplicationPayload(payload, replacement);
|
|
855
811
|
}
|
|
@@ -864,8 +820,8 @@ function decodeDirectAuthorityPublication(
|
|
|
864
820
|
const publication = new ServiceRelocationAuthorityPayloadCodec().read(payload);
|
|
865
821
|
if (publication === undefined) return undefined;
|
|
866
822
|
const applicationPayload = serviceRelocationAuthorityApplicationPayload(payload);
|
|
867
|
-
return publication.canonical === true
|
|
868
|
-
|
|
823
|
+
return publication.canonical === true ||
|
|
824
|
+
publication.inventoryDigest === journalInventoryDigest(applicationPayload)
|
|
869
825
|
? deferredJoinPublication(applicationPayload, publication)
|
|
870
826
|
: undefined;
|
|
871
827
|
}
|
|
@@ -889,8 +845,10 @@ function deferredJoinPublication(
|
|
|
889
845
|
|
|
890
846
|
function hasJournalRootMagic(payload: Uint8Array): boolean {
|
|
891
847
|
const bytes = Buffer.from(payload);
|
|
892
|
-
return
|
|
893
|
-
|
|
848
|
+
return (
|
|
849
|
+
bytes.byteLength >= ROOT_MAGIC.byteLength &&
|
|
850
|
+
bytes.subarray(0, ROOT_MAGIC.byteLength).equals(ROOT_MAGIC)
|
|
851
|
+
);
|
|
894
852
|
}
|
|
895
853
|
|
|
896
854
|
function journalInventoryDigest(applicationPayload: Uint8Array): string {
|
|
@@ -902,10 +860,12 @@ function journalInventoryDigest(applicationPayload: Uint8Array): string {
|
|
|
902
860
|
|
|
903
861
|
function operationAggregateId(operationId: ZLinkActorJoinOperationId): string {
|
|
904
862
|
const encoded = [operationId.high, operationId.low]
|
|
905
|
-
.map(value => BigInt.asUintN(64, value).toString(16).padStart(16, '0'))
|
|
863
|
+
.map((value) => BigInt.asUintN(64, value).toString(16).padStart(16, '0'))
|
|
906
864
|
.join('');
|
|
907
|
-
return
|
|
908
|
-
|
|
865
|
+
return (
|
|
866
|
+
`${encoded.slice(0, 8)}-${encoded.slice(8, 12)}-${encoded.slice(12, 16)}` +
|
|
867
|
+
`-${encoded.slice(16, 20)}-${encoded.slice(20)}`
|
|
868
|
+
);
|
|
909
869
|
}
|
|
910
870
|
|
|
911
871
|
function requireCanonicalAggregateGeneration(value: bigint): bigint {
|
|
@@ -946,8 +906,7 @@ function decodeCanonicalTreeManifest(payload: Uint8Array): CanonicalTreeManifest
|
|
|
946
906
|
if (chunks.length === 0) {
|
|
947
907
|
throw new Error('Canonical relocation chunk count is invalid.');
|
|
948
908
|
}
|
|
949
|
-
if (chunks.reduce((total, value) => total + value.length, 0n)
|
|
950
|
-
!== generated.totalLength) {
|
|
909
|
+
if (chunks.reduce((total, value) => total + value.length, 0n) !== generated.totalLength) {
|
|
951
910
|
throw new Error('Canonical relocation manifest length is invalid.');
|
|
952
911
|
}
|
|
953
912
|
return {
|
|
@@ -966,23 +925,29 @@ async function storeCanonicalTree(
|
|
|
966
925
|
): Promise<{ readonly reference: ZLinkBlobReference; readonly checksumCrc32c: number }> {
|
|
967
926
|
const logical = Buffer.from(logicalRoot);
|
|
968
927
|
const logicalChecksumCrc32c = crc32c(logical);
|
|
969
|
-
const chunk = Buffer.from(
|
|
970
|
-
|
|
971
|
-
data: logical
|
|
972
|
-
}));
|
|
973
|
-
const storedChunk = await putAndVerifyCanonicalBlob(store, chunk, signal);
|
|
974
|
-
const manifest = Buffer.from(encodeRelocationManifestV1({
|
|
975
|
-
logicalFormatVersion: 1,
|
|
976
|
-
totalLength: BigInt(logical.byteLength),
|
|
977
|
-
totalChecksumCrc32c: logicalChecksumCrc32c,
|
|
978
|
-
inventoryDigestSha256: Buffer.from(inventoryDigest),
|
|
979
|
-
chunks: [{
|
|
928
|
+
const chunk = Buffer.from(
|
|
929
|
+
encodeRelocationDataChunkV1({
|
|
980
930
|
order: 0,
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
931
|
+
data: logical
|
|
932
|
+
})
|
|
933
|
+
);
|
|
934
|
+
const storedChunk = await putAndVerifyCanonicalBlob(store, chunk, signal);
|
|
935
|
+
const manifest = Buffer.from(
|
|
936
|
+
encodeRelocationManifestV1({
|
|
937
|
+
logicalFormatVersion: 1,
|
|
938
|
+
totalLength: BigInt(logical.byteLength),
|
|
939
|
+
totalChecksumCrc32c: logicalChecksumCrc32c,
|
|
940
|
+
inventoryDigestSha256: Buffer.from(inventoryDigest),
|
|
941
|
+
chunks: [
|
|
942
|
+
{
|
|
943
|
+
order: 0,
|
|
944
|
+
reference: storedChunk.reference.value,
|
|
945
|
+
length: BigInt(logical.byteLength),
|
|
946
|
+
checksumCrc32c: logicalChecksumCrc32c
|
|
947
|
+
}
|
|
948
|
+
]
|
|
949
|
+
})
|
|
950
|
+
);
|
|
986
951
|
const storedManifest = await putAndVerifyCanonicalBlob(store, manifest, signal);
|
|
987
952
|
return {
|
|
988
953
|
reference: storedManifest.reference,
|
|
@@ -1008,13 +973,16 @@ async function readCanonicalDeferredJoinRoot(
|
|
|
1008
973
|
store: ZLinkRelocationStore,
|
|
1009
974
|
manifestPayload: Uint8Array,
|
|
1010
975
|
signal?: AbortSignal
|
|
1011
|
-
): Promise<
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
976
|
+
): Promise<
|
|
977
|
+
| {
|
|
978
|
+
readonly identity: ZLinkDeferredJoinRootIdentity;
|
|
979
|
+
readonly completion: Omit<
|
|
980
|
+
ZLinkDeferredJoinAcceptedRoot,
|
|
981
|
+
'authority' | 'reference' | 'checksumCrc32c'
|
|
982
|
+
>;
|
|
983
|
+
}
|
|
984
|
+
| undefined
|
|
985
|
+
> {
|
|
1018
986
|
let manifest: CanonicalTreeManifest;
|
|
1019
987
|
try {
|
|
1020
988
|
manifest = decodeCanonicalTreeManifest(manifestPayload);
|
|
@@ -1026,8 +994,7 @@ async function readCanonicalDeferredJoinRoot(
|
|
|
1026
994
|
const read = await store.read(expected.reference, signal);
|
|
1027
995
|
if (read.kind !== 'found') throw new Error('Canonical relocation chunk is missing.');
|
|
1028
996
|
const chunk = decodeRelocationDataChunkV1(read.bytes);
|
|
1029
|
-
if (chunk.order !== expected.order
|
|
1030
|
-
|| BigInt(chunk.data.byteLength) !== expected.length) {
|
|
997
|
+
if (chunk.order !== expected.order || BigInt(chunk.data.byteLength) !== expected.length) {
|
|
1031
998
|
throw new Error('Canonical relocation chunk identity is invalid.');
|
|
1032
999
|
}
|
|
1033
1000
|
const data = Buffer.from(chunk.data);
|
|
@@ -1037,8 +1004,10 @@ async function readCanonicalDeferredJoinRoot(
|
|
|
1037
1004
|
parts.push(data);
|
|
1038
1005
|
}
|
|
1039
1006
|
const logical = Buffer.concat(parts);
|
|
1040
|
-
if (
|
|
1041
|
-
|
|
1007
|
+
if (
|
|
1008
|
+
BigInt(logical.byteLength) !== manifest.logicalLength ||
|
|
1009
|
+
crc32c(logical) !== manifest.logicalChecksumCrc32c
|
|
1010
|
+
) {
|
|
1042
1011
|
throw new Error('Canonical relocation logical root checksum is invalid.');
|
|
1043
1012
|
}
|
|
1044
1013
|
return decodeCanonicalDeferredJoinRoot(logical);
|
|
@@ -1053,23 +1022,33 @@ function encodeCanonicalDeferredJoinRoot(
|
|
|
1053
1022
|
const key = encodeAuthorityKey('actor', value.actor.actorId).value;
|
|
1054
1023
|
const completion = encodeDotNetDeferredJoinCompletion(value);
|
|
1055
1024
|
return Buffer.concat([
|
|
1056
|
-
u32le(0x5a4c5231),
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
u64le(
|
|
1060
|
-
|
|
1025
|
+
u32le(0x5a4c5231),
|
|
1026
|
+
u16le(2),
|
|
1027
|
+
dotNetGuidBytes(publication.aggregateId),
|
|
1028
|
+
u64le(publication.aggregateGeneration),
|
|
1029
|
+
bytes32le(inventoryDigest),
|
|
1030
|
+
u32le(1),
|
|
1031
|
+
text16le(key),
|
|
1032
|
+
Buffer.of(1),
|
|
1033
|
+
u64le(authority.objectGeneration),
|
|
1034
|
+
u64le(authority.authorityOwnerGeneration),
|
|
1035
|
+
bytes32le(Buffer.alloc(0)),
|
|
1036
|
+
u32le(0),
|
|
1037
|
+
u32le(0),
|
|
1038
|
+
bytes32le(Buffer.alloc(0)),
|
|
1039
|
+
bytes32le(completion)
|
|
1061
1040
|
]);
|
|
1062
1041
|
}
|
|
1063
1042
|
|
|
1064
|
-
function decodeCanonicalDeferredJoinRoot(
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1043
|
+
function decodeCanonicalDeferredJoinRoot(payload: Uint8Array):
|
|
1044
|
+
| {
|
|
1045
|
+
readonly identity: ZLinkDeferredJoinRootIdentity;
|
|
1046
|
+
readonly completion: Omit<
|
|
1047
|
+
ZLinkDeferredJoinAcceptedRoot,
|
|
1048
|
+
'authority' | 'reference' | 'checksumCrc32c'
|
|
1049
|
+
>;
|
|
1050
|
+
}
|
|
1051
|
+
| undefined {
|
|
1073
1052
|
const reader = new LittleEndianReader(payload);
|
|
1074
1053
|
if (reader.u32() !== 0x5a4c5231 || reader.u16() !== 2) return undefined;
|
|
1075
1054
|
const aggregateId = canonicalUuidFromDotNetBytes(reader.take(16));
|
|
@@ -1077,25 +1056,32 @@ function decodeCanonicalDeferredJoinRoot(
|
|
|
1077
1056
|
reader.bytes32();
|
|
1078
1057
|
const count = reader.u32();
|
|
1079
1058
|
let completion: ReturnType<typeof decodeDotNetDeferredJoinCompletion> | undefined;
|
|
1080
|
-
let completionIdentity:
|
|
1081
|
-
ZLinkDeferredJoinRootIdentity,
|
|
1082
|
-
|
|
1083
|
-
> | undefined;
|
|
1059
|
+
let completionIdentity:
|
|
1060
|
+
| Pick<ZLinkDeferredJoinRootIdentity, 'authorityKey' | 'objectKind' | 'objectGeneration'>
|
|
1061
|
+
| undefined;
|
|
1084
1062
|
for (let index = 0; index < count; index++) {
|
|
1085
1063
|
const authorityKey = reader.text16();
|
|
1086
1064
|
const objectKind = reader.u8();
|
|
1087
1065
|
const objectGeneration = reader.u64();
|
|
1088
|
-
reader.u64();
|
|
1066
|
+
reader.u64();
|
|
1067
|
+
reader.bytes32();
|
|
1089
1068
|
const jobs = reader.u32();
|
|
1090
|
-
for (let job = 0; job < jobs; job++) {
|
|
1069
|
+
for (let job = 0; job < jobs; job++) {
|
|
1070
|
+
reader.u64();
|
|
1071
|
+
reader.bytes32();
|
|
1072
|
+
}
|
|
1091
1073
|
const timers = reader.u32();
|
|
1092
1074
|
for (let timer = 0; timer < timers; timer++) {
|
|
1093
|
-
reader.text16();
|
|
1075
|
+
reader.text16();
|
|
1076
|
+
reader.i64();
|
|
1077
|
+
reader.i64();
|
|
1078
|
+
reader.bytes32();
|
|
1094
1079
|
}
|
|
1095
1080
|
reader.bytes32();
|
|
1096
1081
|
const encodedCompletion = reader.bytes32();
|
|
1097
1082
|
if (encodedCompletion.byteLength !== 0) {
|
|
1098
|
-
if (completion !== undefined)
|
|
1083
|
+
if (completion !== undefined)
|
|
1084
|
+
throw new Error('Canonical relocation root has duplicate completions.');
|
|
1099
1085
|
completion = decodeDotNetDeferredJoinCompletion(encodedCompletion);
|
|
1100
1086
|
if (objectKind !== 1) return undefined;
|
|
1101
1087
|
completionIdentity = {
|
|
@@ -1107,9 +1093,10 @@ function decodeCanonicalDeferredJoinRoot(
|
|
|
1107
1093
|
}
|
|
1108
1094
|
if (!reader.done) throw new Error('Canonical relocation root has trailing bytes.');
|
|
1109
1095
|
if (completion === undefined || completionIdentity === undefined) return undefined;
|
|
1110
|
-
if (
|
|
1111
|
-
|
|
1112
|
-
|
|
1096
|
+
if (
|
|
1097
|
+
completion.actor.objectGeneration !== completionIdentity.objectGeneration ||
|
|
1098
|
+
encodeAuthorityKey('actor', completion.actor.actorId).value !== completionIdentity.authorityKey
|
|
1099
|
+
) {
|
|
1113
1100
|
return undefined;
|
|
1114
1101
|
}
|
|
1115
1102
|
return {
|
|
@@ -1127,9 +1114,15 @@ function encodeDotNetDeferredJoinCompletion(
|
|
|
1127
1114
|
): Buffer {
|
|
1128
1115
|
const routingId = Buffer.from(encodeRoutingIdStorageHex(value.actor.nodeRid), 'hex');
|
|
1129
1116
|
return Buffer.concat([
|
|
1130
|
-
u32le(0x5a4c4a43),
|
|
1131
|
-
|
|
1132
|
-
text16le(value.actor.
|
|
1117
|
+
u32le(0x5a4c4a43),
|
|
1118
|
+
Buffer.of(2),
|
|
1119
|
+
text16le(value.actor.actorId),
|
|
1120
|
+
u64le(value.actor.objectGeneration),
|
|
1121
|
+
u64le(value.operationId.high),
|
|
1122
|
+
u64le(value.operationId.low),
|
|
1123
|
+
text16le(value.actor.meshName),
|
|
1124
|
+
Buffer.of(routingId.byteLength),
|
|
1125
|
+
routingId,
|
|
1133
1126
|
u64le(value.actor.objectGeneration),
|
|
1134
1127
|
Buffer.of(value.replyContentType === undefined ? 0 : 1),
|
|
1135
1128
|
...(value.replyContentType === undefined ? [] : [text16le(value.replyContentType)]),
|
|
@@ -1180,8 +1173,12 @@ function decodeDotNetDeferredJoinCompletion(
|
|
|
1180
1173
|
class LittleEndianReader {
|
|
1181
1174
|
private offset = 0;
|
|
1182
1175
|
private readonly bytes: Buffer;
|
|
1183
|
-
constructor(payload: Uint8Array) {
|
|
1184
|
-
|
|
1176
|
+
constructor(payload: Uint8Array) {
|
|
1177
|
+
this.bytes = Buffer.from(payload);
|
|
1178
|
+
}
|
|
1179
|
+
get done(): boolean {
|
|
1180
|
+
return this.offset === this.bytes.byteLength;
|
|
1181
|
+
}
|
|
1185
1182
|
take(length: number): Buffer {
|
|
1186
1183
|
if (length < 0 || this.offset + length > this.bytes.byteLength) {
|
|
1187
1184
|
throw new Error('Canonical relocation root is truncated.');
|
|
@@ -1190,23 +1187,41 @@ class LittleEndianReader {
|
|
|
1190
1187
|
this.offset += length;
|
|
1191
1188
|
return result;
|
|
1192
1189
|
}
|
|
1193
|
-
u8(): number {
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1190
|
+
u8(): number {
|
|
1191
|
+
return this.take(1)[0]!;
|
|
1192
|
+
}
|
|
1193
|
+
u16(): number {
|
|
1194
|
+
return this.take(2).readUInt16LE();
|
|
1195
|
+
}
|
|
1196
|
+
u32(): number {
|
|
1197
|
+
return this.take(4).readUInt32LE();
|
|
1198
|
+
}
|
|
1199
|
+
u64(): bigint {
|
|
1200
|
+
return this.take(8).readBigUInt64LE();
|
|
1201
|
+
}
|
|
1202
|
+
i64(): bigint {
|
|
1203
|
+
return this.take(8).readBigInt64LE();
|
|
1204
|
+
}
|
|
1198
1205
|
text16(): string {
|
|
1199
1206
|
const bytes = this.take(this.u16());
|
|
1200
1207
|
return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
1201
1208
|
}
|
|
1202
|
-
bytes32(): Buffer {
|
|
1209
|
+
bytes32(): Buffer {
|
|
1210
|
+
return this.take(this.u32());
|
|
1211
|
+
}
|
|
1203
1212
|
}
|
|
1204
1213
|
|
|
1205
1214
|
function dotNetGuidBytes(value: string): Buffer {
|
|
1206
1215
|
const bytes = Buffer.from(value.replaceAll('-', ''), 'hex');
|
|
1207
1216
|
return Buffer.from([
|
|
1208
|
-
bytes[3]!,
|
|
1209
|
-
bytes[
|
|
1217
|
+
bytes[3]!,
|
|
1218
|
+
bytes[2]!,
|
|
1219
|
+
bytes[1]!,
|
|
1220
|
+
bytes[0]!,
|
|
1221
|
+
bytes[5]!,
|
|
1222
|
+
bytes[4]!,
|
|
1223
|
+
bytes[7]!,
|
|
1224
|
+
bytes[6]!,
|
|
1210
1225
|
...bytes.subarray(8)
|
|
1211
1226
|
]);
|
|
1212
1227
|
}
|
|
@@ -1217,13 +1232,20 @@ function canonicalUuidFromDotNetBytes(value: Uint8Array): string {
|
|
|
1217
1232
|
throw new TypeError('Canonical relocation aggregate id is invalid.');
|
|
1218
1233
|
}
|
|
1219
1234
|
const canonical = Buffer.from([
|
|
1220
|
-
bytes[3]!,
|
|
1221
|
-
bytes[
|
|
1222
|
-
bytes[
|
|
1235
|
+
bytes[3]!,
|
|
1236
|
+
bytes[2]!,
|
|
1237
|
+
bytes[1]!,
|
|
1238
|
+
bytes[0]!,
|
|
1239
|
+
bytes[5]!,
|
|
1240
|
+
bytes[4]!,
|
|
1241
|
+
bytes[7]!,
|
|
1242
|
+
bytes[6]!,
|
|
1223
1243
|
...bytes.subarray(8)
|
|
1224
1244
|
]).toString('hex');
|
|
1225
|
-
return
|
|
1226
|
-
|
|
1245
|
+
return (
|
|
1246
|
+
`${canonical.slice(0, 8)}-${canonical.slice(8, 12)}-${canonical.slice(12, 16)}` +
|
|
1247
|
+
`-${canonical.slice(16, 20)}-${canonical.slice(20)}`
|
|
1248
|
+
);
|
|
1227
1249
|
}
|
|
1228
1250
|
|
|
1229
1251
|
function text16le(value: string): Buffer {
|
|
@@ -1237,15 +1259,21 @@ function bytes32le(value: Uint8Array): Buffer {
|
|
|
1237
1259
|
}
|
|
1238
1260
|
|
|
1239
1261
|
function u16le(value: number): Buffer {
|
|
1240
|
-
const result = Buffer.alloc(2);
|
|
1262
|
+
const result = Buffer.alloc(2);
|
|
1263
|
+
result.writeUInt16LE(value);
|
|
1264
|
+
return result;
|
|
1241
1265
|
}
|
|
1242
1266
|
|
|
1243
1267
|
function u32le(value: number): Buffer {
|
|
1244
|
-
const result = Buffer.alloc(4);
|
|
1268
|
+
const result = Buffer.alloc(4);
|
|
1269
|
+
result.writeUInt32LE(value);
|
|
1270
|
+
return result;
|
|
1245
1271
|
}
|
|
1246
1272
|
|
|
1247
1273
|
function u64le(value: bigint): Buffer {
|
|
1248
|
-
const result = Buffer.alloc(8);
|
|
1274
|
+
const result = Buffer.alloc(8);
|
|
1275
|
+
result.writeBigUInt64LE(value);
|
|
1276
|
+
return result;
|
|
1249
1277
|
}
|
|
1250
1278
|
|
|
1251
1279
|
function validateIdentity(
|
|
@@ -1254,10 +1282,10 @@ function validateIdentity(
|
|
|
1254
1282
|
actor: ActorRef
|
|
1255
1283
|
): void {
|
|
1256
1284
|
if (
|
|
1257
|
-
actorId.length === 0
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1285
|
+
actorId.length === 0 ||
|
|
1286
|
+
actor.actorId !== actorId ||
|
|
1287
|
+
actor.objectGeneration <= 0n ||
|
|
1288
|
+
(operationId.high === 0n && operationId.low === 0n)
|
|
1261
1289
|
) {
|
|
1262
1290
|
throw new Error('Deferred Join completion identity is invalid.');
|
|
1263
1291
|
}
|
|
@@ -1278,24 +1306,23 @@ function isSameOperation(
|
|
|
1278
1306
|
operationId: ZLinkActorJoinOperationId,
|
|
1279
1307
|
actor: ActorRef
|
|
1280
1308
|
): boolean {
|
|
1281
|
-
return
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1309
|
+
return (
|
|
1310
|
+
root.operationId.high === operationId.high &&
|
|
1311
|
+
root.operationId.low === operationId.low &&
|
|
1312
|
+
root.actor.actorId === actor.actorId &&
|
|
1313
|
+
root.actor.objectGeneration === actor.objectGeneration
|
|
1314
|
+
);
|
|
1285
1315
|
}
|
|
1286
1316
|
|
|
1287
|
-
function requireSameActor(
|
|
1288
|
-
root: ZLinkDeferredJoinAcceptedRoot,
|
|
1289
|
-
actor: ActorRef
|
|
1290
|
-
): void {
|
|
1317
|
+
function requireSameActor(root: ZLinkDeferredJoinAcceptedRoot, actor: ActorRef): void {
|
|
1291
1318
|
if (
|
|
1292
|
-
root.actor.actorId !== actor.actorId
|
|
1293
|
-
|
|
1319
|
+
root.actor.actorId !== actor.actorId ||
|
|
1320
|
+
root.actor.objectGeneration !== actor.objectGeneration
|
|
1294
1321
|
) {
|
|
1295
1322
|
throw new Error(
|
|
1296
|
-
'Deferred Join completion generation fence is stale '
|
|
1297
|
-
|
|
1298
|
-
|
|
1323
|
+
'Deferred Join completion generation fence is stale ' +
|
|
1324
|
+
`(root ${root.actor.actorId}/${root.actor.objectGeneration}, ` +
|
|
1325
|
+
`actor ${actor.actorId}/${actor.objectGeneration}).`
|
|
1299
1326
|
);
|
|
1300
1327
|
}
|
|
1301
1328
|
}
|