@zlink-systems/framework 0.30.1 → 0.30.2
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/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +4 -0
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +0 -1
- package/dist/runtime/actors/actor-client.js +38 -45
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +7 -3
- package/dist/runtime/actors/actor-handoff.js +212 -88
- package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
- package/dist/runtime/actors/actor-local-native-join.js +4 -0
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +6 -2
- package/dist/runtime/actors/index.js +37 -21
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +55 -32
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
- package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
- package/dist/runtime/application-jobs/contracts.d.ts +2 -0
- package/dist/runtime/backend/contracts/index.d.ts +19 -3
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.js +5 -0
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
- package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +20 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
- package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatchers.js +44 -37
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +74 -31
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
- package/dist/runtime/channels/channel-runtime-manager.js +4 -4
- package/dist/runtime/channels/channel-transports.d.ts +0 -1
- package/dist/runtime/channels/channel-transports.js +35 -33
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
- package/dist/runtime/execution/serial-execution-queue.js +21 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
- package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +24 -3
- package/dist/runtime/host/application-job-queue.js +28 -41
- package/dist/runtime/host/index.d.ts +5 -1
- package/dist/runtime/host/index.js +171 -97
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +71 -190
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +5 -3
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
- package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
- package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +6 -2
- package/dist/runtime/locations/runtime.js +37 -30
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.js +29 -26
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
- package/dist/runtime/spots/index.d.ts +18 -11
- package/dist/runtime/spots/index.js +234 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +6 -3
- package/dist/runtime/spots/spot-activation.js +123 -44
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +14 -9
- package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
- package/dist/runtime/spots/spot-handler-registry.js +6 -2
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.js +3 -3
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +287 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.js +1 -4
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +8 -0
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +61 -70
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +282 -106
- package/src/runtime/actors/actor-join-relocation.ts +2 -0
- package/src/runtime/actors/actor-local-native-join.ts +4 -0
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +41 -27
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/admission.ts +69 -34
- package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
- package/src/runtime/application-jobs/contracts.ts +2 -0
- package/src/runtime/backend/contracts/index.ts +39 -4
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +4 -0
- package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
- package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
- package/src/runtime/channels/channel-clients.ts +49 -24
- package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
- package/src/runtime/channels/channel-dispatchers.ts +116 -72
- package/src/runtime/channels/channel-envelope.ts +105 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +12 -5
- package/src/runtime/channels/channel-transports.ts +49 -58
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
- package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +29 -44
- package/src/runtime/host/index.ts +286 -129
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +86 -248
- package/src/runtime/host/route-mesh-runtime.ts +11 -5
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
- package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +70 -40
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +33 -29
- package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
- package/src/runtime/spots/index.ts +375 -281
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +170 -86
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +24 -19
- package/src/runtime/spots/spot-handler-registry.ts +15 -4
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +3 -3
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-runtime-ports.ts +0 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
- package/src/runtime/spots/spot-timer.ts +413 -157
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +1 -5
- package/src/runtime/workers/index.ts +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { routingIdsEqual } from '../routing-id';
|
|
1
2
|
import type { ZLinkRuntimeEventPublisher } from '../diagnostics';
|
|
2
3
|
import { ZLinkSpotRelocationCoordinationMode, ZLinkUserSpotExecutionMode } from '../../contracts';
|
|
3
4
|
import {
|
|
@@ -137,6 +138,15 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
137
138
|
}
|
|
138
139
|
await runtime.dispatchEntryActorJoin(meshName, actor, handoffBacklog);
|
|
139
140
|
},
|
|
141
|
+
admitEntryActorPacketPrefix: (meshName, actorId, records) => {
|
|
142
|
+
const runtime = this.options.spotNodeRuntime();
|
|
143
|
+
if (runtime === undefined) {
|
|
144
|
+
throw new ZLinkConfigurationException(
|
|
145
|
+
'Entry Actor replay requires the MeshNode runtime.'
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return runtime.admitEntryActorPacketPrefix(meshName, actorId, records);
|
|
149
|
+
},
|
|
140
150
|
executeEntryActor: (meshName, actorId, operation) => {
|
|
141
151
|
const runtime = this.options.spotNodeRuntime();
|
|
142
152
|
if (runtime === undefined) {
|
|
@@ -278,8 +288,9 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
278
288
|
this.options.spotNodeRuntime()?.meshNode(meshName) as never,
|
|
279
289
|
spotRouteResolver: this.options.createLocationSpotRouteResolver(),
|
|
280
290
|
actorResolver: (actorId) => {
|
|
281
|
-
const
|
|
282
|
-
|
|
291
|
+
const manager = this.options.actorManager();
|
|
292
|
+
const state = manager?.getState(actorId);
|
|
293
|
+
return state?.isMoving === true ? undefined : manager?.resolveLocalActor(actorId);
|
|
283
294
|
},
|
|
284
295
|
canonicalActorJoinResolver: (fence) =>
|
|
285
296
|
this.options.boundSessionRelay.actorJoins.prepareCanonicalActorJoin({
|
|
@@ -297,14 +308,14 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
297
308
|
state?.nativeActorRef === undefined
|
|
298
309
|
? undefined
|
|
299
310
|
: toFrameworkActorRef(state.nativeActorRef, state.meshName ?? '');
|
|
300
|
-
const localNodeRid =
|
|
311
|
+
const localNodeRid =
|
|
312
|
+
state?.meshName === undefined ? undefined : this.meshNodeRoutingId(state.meshName);
|
|
301
313
|
if (
|
|
302
314
|
state?.actor === undefined ||
|
|
303
|
-
state.spot === undefined ||
|
|
304
315
|
state.remoteActorPacketTarget !== undefined ||
|
|
305
316
|
actorRef === undefined ||
|
|
306
317
|
localNodeRid === undefined ||
|
|
307
|
-
|
|
318
|
+
!routingIdsEqual(actorRef.nodeRid, localNodeRid)
|
|
308
319
|
) {
|
|
309
320
|
return {};
|
|
310
321
|
}
|
|
@@ -351,11 +362,11 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
351
362
|
|
|
352
363
|
private primaryNodeRoutingId(): string | undefined {
|
|
353
364
|
const node = this.primaryNode();
|
|
354
|
-
return node === undefined ? undefined :
|
|
365
|
+
return node === undefined ? undefined : node.status().routingId;
|
|
355
366
|
}
|
|
356
367
|
|
|
357
368
|
private meshNodeRoutingId(meshName: string): string | undefined {
|
|
358
369
|
const node = this.options.spotNodeRuntime()?.meshNode(meshName);
|
|
359
|
-
return node === undefined ? undefined :
|
|
370
|
+
return node === undefined ? undefined : node.status().routingId;
|
|
360
371
|
}
|
|
361
372
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import {
|
|
3
4
|
type RoutingId,
|
|
@@ -131,7 +132,6 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
131
132
|
const contentReference = encodeLocationCreationContent(request.requestPayload);
|
|
132
133
|
const excludedNodeRids = new Set<string>();
|
|
133
134
|
let target: Awaited<ReturnType<ZLinkUserSpotCreationCoordinatorOptions['target']>>;
|
|
134
|
-
let authorityTarget;
|
|
135
135
|
let reserved: ZLinkObjectReserveResult;
|
|
136
136
|
for (;;) {
|
|
137
137
|
try {
|
|
@@ -154,7 +154,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
154
154
|
true
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
|
-
if (excludedNodeRids.has(
|
|
157
|
+
if (excludedNodeRids.has(encodeRoutingIdStorageHex(target.nodeRid))) {
|
|
158
158
|
deadline.close();
|
|
159
159
|
throw createInternalFrameworkException(
|
|
160
160
|
ZLinkFrameworkInternalErrorKind.PlacementCapacityExhausted,
|
|
@@ -163,7 +163,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
163
163
|
);
|
|
164
164
|
}
|
|
165
165
|
const owner = target.owner;
|
|
166
|
-
authorityTarget = {
|
|
166
|
+
const authorityTarget = {
|
|
167
167
|
meshName: target.meshName,
|
|
168
168
|
nodeRid: target.nodeRid,
|
|
169
169
|
nodeLifecycleGeneration: target.nodeGeneration,
|
|
@@ -217,92 +217,31 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
217
217
|
error
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
reserved.current.allocation.objectKind === 'user_spot' &&
|
|
228
|
-
reserved.current.allocation.stableType === request.stableType)
|
|
229
|
-
) {
|
|
230
|
-
const current = reserved.kind === 'alreadyExists' ? reserved.current : reserved.current;
|
|
231
|
-
if (current.kind === 'snapshot' && current.allocation.state === 'active') {
|
|
220
|
+
if (
|
|
221
|
+
reserved.kind === 'alreadyExists' ||
|
|
222
|
+
(reserved.kind === 'conflict' &&
|
|
223
|
+
reserved.current.kind === 'snapshot' &&
|
|
224
|
+
reserved.current.allocation.objectKind === 'user_spot' &&
|
|
225
|
+
reserved.current.allocation.stableType === request.stableType)
|
|
226
|
+
) {
|
|
232
227
|
if (request.generatedIdentity === true) {
|
|
233
228
|
deadline.close();
|
|
234
229
|
throw spotIdConflict(request.spotId);
|
|
235
230
|
}
|
|
236
|
-
const spot = spotRef(current, request);
|
|
237
|
-
deadline.close();
|
|
238
|
-
return {
|
|
239
|
-
result: { spot, state: ZLinkSpotCreateState.Existing },
|
|
240
|
-
spot
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
if (current.kind !== 'snapshot' || !sameCreationTarget(current, authorityTarget)) {
|
|
244
|
-
deadline.close();
|
|
245
|
-
if (request.generatedIdentity === true) {
|
|
246
|
-
throw spotIdConflict(request.spotId);
|
|
247
|
-
}
|
|
248
|
-
throw createInternalFrameworkException(
|
|
249
|
-
ZLinkFrameworkInternalErrorKind.RequestFailed,
|
|
250
|
-
'User Spot creation requires a remote generation-fenced create operation.'
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
if (current.allocation.state === 'reserved' && !target.isLocal) {
|
|
254
231
|
try {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
current,
|
|
258
|
-
target.nodeRid,
|
|
259
|
-
target.nodeGeneration,
|
|
260
|
-
deadlineUnixMs,
|
|
261
|
-
deadlineMs
|
|
262
|
-
);
|
|
263
|
-
} finally {
|
|
264
|
-
deadline.close();
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (current.allocation.state === 'reserved' && target.isLocal) {
|
|
268
|
-
const pending = current.pendingCreation;
|
|
269
|
-
const admitted =
|
|
270
|
-
pending === undefined ? undefined : this.localCreations.get(pending.reservationId);
|
|
271
|
-
if (admitted === undefined) {
|
|
272
|
-
try {
|
|
273
|
-
const spot = await this.awaitReady(request, signal);
|
|
274
|
-
return {
|
|
275
|
-
result: { spot, state: ZLinkSpotCreateState.Existing },
|
|
276
|
-
spot
|
|
277
|
-
};
|
|
278
|
-
} finally {
|
|
232
|
+
const spot = await this.awaitReady(request, signal);
|
|
233
|
+
if (spot !== undefined) {
|
|
279
234
|
deadline.close();
|
|
235
|
+
return { result: { spot, state: ZLinkSpotCreateState.Existing }, spot };
|
|
280
236
|
}
|
|
281
|
-
}
|
|
282
|
-
try {
|
|
283
|
-
const result = await admitted;
|
|
284
|
-
return result.result.state === ZLinkSpotCreateState.Created
|
|
285
|
-
? {
|
|
286
|
-
result: {
|
|
287
|
-
...result.result,
|
|
288
|
-
state: ZLinkSpotCreateState.Existing
|
|
289
|
-
},
|
|
290
|
-
spot: result.spot
|
|
291
|
-
}
|
|
292
|
-
: result;
|
|
293
|
-
} finally {
|
|
237
|
+
} catch (error) {
|
|
294
238
|
deadline.close();
|
|
239
|
+
throw error;
|
|
295
240
|
}
|
|
241
|
+
continue;
|
|
296
242
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return {
|
|
300
|
-
result: { spot, state: ZLinkSpotCreateState.Existing },
|
|
301
|
-
spot
|
|
302
|
-
};
|
|
303
|
-
} finally {
|
|
304
|
-
deadline.close();
|
|
305
|
-
}
|
|
243
|
+
if (reserved.kind !== 'placementCapacityExhausted') break;
|
|
244
|
+
excludedNodeRids.add(encodeRoutingIdStorageHex(target.nodeRid));
|
|
306
245
|
}
|
|
307
246
|
if (reserved.kind === 'typeMismatch') {
|
|
308
247
|
deadline.close();
|
|
@@ -478,7 +417,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
478
417
|
current.allocation.stableType === record.stableType &&
|
|
479
418
|
current.objectGeneration === record.reservation.objectGeneration &&
|
|
480
419
|
current.authorityOwnerGeneration === record.reservation.authorityOwnerGeneration &&
|
|
481
|
-
|
|
420
|
+
routingIdsEqual(current.allocation.descriptor.rid, record.reservation.targetNodeRid) &&
|
|
482
421
|
current.allocation.descriptorLifecycleGeneration ===
|
|
483
422
|
record.reservation.targetNodeGeneration &&
|
|
484
423
|
current.ownerId === record.reservation.targetOwnerId &&
|
|
@@ -532,7 +471,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
532
471
|
try {
|
|
533
472
|
local = await materialize(requestPayload, current, signal ?? new AbortController().signal);
|
|
534
473
|
if (local.state === ZLinkSpotCreateState.Rejected) {
|
|
535
|
-
local.publication?.abort();
|
|
474
|
+
await local.publication?.abort();
|
|
536
475
|
await this.options.store.abort(
|
|
537
476
|
{
|
|
538
477
|
key: { kind: 'user_spot', globalId: record.spotId },
|
|
@@ -609,13 +548,15 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
609
548
|
committed.ready.allocation.descriptor.meshName,
|
|
610
549
|
readySpotRoute(record.spotId, committed.ready)
|
|
611
550
|
);
|
|
612
|
-
local.publication?.publish();
|
|
551
|
+
await local.publication?.publish();
|
|
613
552
|
return {
|
|
614
553
|
result: { spot: readySpot, state: local.state, reply: local.reply },
|
|
615
554
|
spot: readySpot
|
|
616
555
|
};
|
|
617
556
|
} catch (error) {
|
|
618
|
-
|
|
557
|
+
const publicationCleanup = await Promise.allSettled([
|
|
558
|
+
Promise.resolve().then(() => local?.publication?.abort())
|
|
559
|
+
]);
|
|
619
560
|
const cleanupDeadline = createDeadline(
|
|
620
561
|
this.options.cleanupTimeoutMs ?? DEFAULT_USER_SPOT_CLEANUP_TIMEOUT_MS
|
|
621
562
|
);
|
|
@@ -644,7 +585,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
644
585
|
waitForAbort(discard?.(cleanupSignal) ?? Promise.resolve(), cleanupSignal)
|
|
645
586
|
]);
|
|
646
587
|
cleanupDeadline.close();
|
|
647
|
-
const cleanupErrors = cleanup
|
|
588
|
+
const cleanupErrors = [...publicationCleanup, ...cleanup]
|
|
648
589
|
.filter((item): item is PromiseRejectedResult => item.status === 'rejected')
|
|
649
590
|
.map((item) => item.reason);
|
|
650
591
|
if (cleanupErrors.length > 0) {
|
|
@@ -774,12 +715,25 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
774
715
|
private async awaitReady(
|
|
775
716
|
request: ZLinkUserSpotCreationRequest,
|
|
776
717
|
signal: AbortSignal
|
|
777
|
-
): Promise<SpotRef> {
|
|
718
|
+
): Promise<SpotRef | undefined> {
|
|
778
719
|
const key = encodeAuthorityKey('user_spot', String(request.spotId));
|
|
779
720
|
for (;;) {
|
|
780
721
|
signal.throwIfAborted();
|
|
781
722
|
const current = await this.options.store.readAuthority(key, signal);
|
|
782
|
-
if (current.kind === '
|
|
723
|
+
if (current.kind === 'missing') return undefined;
|
|
724
|
+
if (
|
|
725
|
+
current.allocation.objectKind !== 'user_spot' ||
|
|
726
|
+
current.allocation.stableType !== request.stableType
|
|
727
|
+
) {
|
|
728
|
+
throw createInternalFrameworkException(
|
|
729
|
+
ZLinkFrameworkInternalErrorKind.SpotTypeMismatch,
|
|
730
|
+
`User Spot '${String(request.spotId)}' has another stable type.`
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
if (
|
|
734
|
+
current.allocation.state === 'active' &&
|
|
735
|
+
decodeServiceClosingSpotAuthority(current.payload) === undefined
|
|
736
|
+
) {
|
|
783
737
|
return spotRef(current, request);
|
|
784
738
|
}
|
|
785
739
|
await wait(this.options.pollIntervalMs ?? DEFAULT_USER_SPOT_POLL_INTERVAL_MS, signal);
|
|
@@ -931,7 +885,7 @@ function requireCloseTarget(
|
|
|
931
885
|
decoded.ownerLeaseGeneration !== current.ownerLeaseGeneration ||
|
|
932
886
|
allocation.objectKind !== 'user_spot' ||
|
|
933
887
|
allocation.state !== 'active' ||
|
|
934
|
-
|
|
888
|
+
!routingIdsEqual(allocation.descriptor.rid, fence.nodeRid) ||
|
|
935
889
|
(fence.meshName !== undefined && allocation.descriptor.meshName !== fence.meshName) ||
|
|
936
890
|
(fence.nodeGeneration !== undefined &&
|
|
937
891
|
allocation.descriptorLifecycleGeneration !== fence.nodeGeneration) ||
|
|
@@ -1057,19 +1011,6 @@ export function decodeLocationCreationContent(
|
|
|
1057
1011
|
return payload;
|
|
1058
1012
|
}
|
|
1059
1013
|
|
|
1060
|
-
function sameCreationTarget(
|
|
1061
|
-
snapshot: ZLinkAuthoritySnapshot,
|
|
1062
|
-
target: Parameters<ZLinkObjectCreationStore['reserve']>[0]['target']
|
|
1063
|
-
): boolean {
|
|
1064
|
-
return (
|
|
1065
|
-
snapshot.allocation.descriptor.meshName === target.meshName &&
|
|
1066
|
-
String(snapshot.allocation.descriptor.rid) === String(target.nodeRid) &&
|
|
1067
|
-
snapshot.allocation.descriptorLifecycleGeneration === target.nodeLifecycleGeneration &&
|
|
1068
|
-
snapshot.ownerId === target.owner.ownerId &&
|
|
1069
|
-
snapshot.ownerLeaseGeneration === target.owner.leaseGeneration
|
|
1070
|
-
);
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
1014
|
function remoteCreationFingerprint(record: ServiceUserSpotCreateRecord): string {
|
|
1074
1015
|
return JSON.stringify(
|
|
1075
1016
|
{
|
|
@@ -55,6 +55,15 @@ export class ZLinkAutoConnectLoop {
|
|
|
55
55
|
this.scheduleNext();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
async requestPeerReconcile(meshName: string, _peerRid: string): Promise<void> {
|
|
59
|
+
const controller = this.controller;
|
|
60
|
+
if (meshName !== this.meshName || controller === undefined) return;
|
|
61
|
+
// A fresh descriptor scan uses the same RID ordering and connection owner as a periodic tick.
|
|
62
|
+
await this.lane.run(async () => {
|
|
63
|
+
if (!controller.signal.aborted) await this.runReconcile(controller.signal);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
58
67
|
async stop(signal?: AbortSignal): Promise<void> {
|
|
59
68
|
await this.prepareTransportShutdown();
|
|
60
69
|
await this.finishTransportShutdown(signal);
|
|
@@ -78,7 +87,11 @@ export class ZLinkAutoConnectLoop {
|
|
|
78
87
|
}
|
|
79
88
|
|
|
80
89
|
async tick(signal?: AbortSignal): Promise<void> {
|
|
81
|
-
|
|
90
|
+
await this.lane.run(() => this.tickCore(signal));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private async tickCore(signal?: AbortSignal): Promise<void> {
|
|
94
|
+
const lastTickFailed = this.lastTickFailed;
|
|
82
95
|
if (this.changeStampStore?.getMeshNodeChangeStamp !== undefined && !lastTickFailed) {
|
|
83
96
|
try {
|
|
84
97
|
const stamp = await this.changeStampStore.getMeshNodeChangeStamp(this.meshName, signal);
|
|
@@ -94,11 +107,10 @@ export class ZLinkAutoConnectLoop {
|
|
|
94
107
|
return;
|
|
95
108
|
}
|
|
96
109
|
const tickFailed = await this.runReconcile(signal);
|
|
97
|
-
if (!tickFailed)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
});
|
|
110
|
+
if (!tickFailed) {
|
|
111
|
+
this.lastStamp = stamp;
|
|
112
|
+
this.lastLiveOwnerSetVersion = liveOwners;
|
|
113
|
+
}
|
|
102
114
|
return;
|
|
103
115
|
} catch {
|
|
104
116
|
// A failed stamp read degrades to a full reconcile tick.
|
|
@@ -106,18 +118,14 @@ export class ZLinkAutoConnectLoop {
|
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
await this.runReconcile(signal);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.lastLiveOwnerSetVersion = undefined;
|
|
112
|
-
});
|
|
121
|
+
this.lastStamp = undefined;
|
|
122
|
+
this.lastLiveOwnerSetVersion = undefined;
|
|
113
123
|
}
|
|
114
124
|
|
|
115
125
|
private async runReconcile(signal?: AbortSignal): Promise<boolean> {
|
|
116
126
|
await this.reconciler.tick(signal);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return this.lastTickFailed;
|
|
120
|
-
});
|
|
127
|
+
this.lastTickFailed = this.reconciler.storeFailed;
|
|
128
|
+
return this.lastTickFailed;
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
private scheduleNext(): void {
|
|
@@ -195,15 +195,11 @@ export class ZLinkAutoConnectReconciler {
|
|
|
195
195
|
}
|
|
196
196
|
const deferringMissingTargets =
|
|
197
197
|
this.monotonicNowMs() < (await this.lane.run(() => this.recoveryDeferUntilMs));
|
|
198
|
-
let staleCandidates = candidates;
|
|
199
198
|
if (deferringMissingTargets) {
|
|
200
|
-
const retainedCandidates = new Map(candidates);
|
|
201
199
|
const lastDesired = await this.lane.run(() => [...this.lastDesired]);
|
|
202
200
|
for (const [key, target] of lastDesired) {
|
|
203
201
|
if (!desired.has(key)) desired.set(key, target);
|
|
204
|
-
if (!retainedCandidates.has(key)) retainedCandidates.set(key, target);
|
|
205
202
|
}
|
|
206
|
-
staleCandidates = retainedCandidates;
|
|
207
203
|
}
|
|
208
204
|
await this.lane.run(() => {
|
|
209
205
|
this.lastDesired = new Map(desired);
|
|
@@ -270,8 +266,6 @@ export class ZLinkAutoConnectReconciler {
|
|
|
270
266
|
}
|
|
271
267
|
}
|
|
272
268
|
|
|
273
|
-
this.executor.disconnectStalePeers?.([...staleCandidates.values()]);
|
|
274
|
-
|
|
275
269
|
const activeTargets = await this.lane.run(() => [...this.active]);
|
|
276
270
|
for (const [key, target] of activeTargets) {
|
|
277
271
|
if (!desired.has(key)) {
|
|
@@ -32,7 +32,6 @@ export interface ZLinkAutoConnectTarget {
|
|
|
32
32
|
export interface IZLinkAutoConnectExecutor {
|
|
33
33
|
connect(target: ZLinkAutoConnectTarget): Promise<boolean>;
|
|
34
34
|
disconnect(target: ZLinkAutoConnectTarget): void;
|
|
35
|
-
disconnectStalePeers?(targets: readonly ZLinkAutoConnectTarget[]): void;
|
|
36
35
|
isDisconnected?(target: ZLinkAutoConnectTarget): boolean;
|
|
37
36
|
onDisconnected?(handler: (endpoint: string) => void): void;
|
|
38
37
|
replaceNotRequired?(targets: readonly ZLinkAutoConnectTarget[]): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A descriptor Store write failed without a confirmed result (Location runtime section 5). */
|
|
2
|
+
export class ZLinkDescriptorPublicationUnconfirmedError extends Error {
|
|
3
|
+
constructor(cause: unknown) {
|
|
4
|
+
super(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
5
|
+
this.name = 'ZLinkDescriptorPublicationUnconfirmedError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -49,6 +49,11 @@ import type {
|
|
|
49
49
|
* implement this interface; the framework maps it to the opaque Store SPI.
|
|
50
50
|
*/
|
|
51
51
|
export interface ZLinkDomainLocationStore {
|
|
52
|
+
confirmedCapacity?(
|
|
53
|
+
key: ZLinkMeshNodeDescriptorKey,
|
|
54
|
+
limits: ZLinkMeshNodeDescriptor['populationCapacity']
|
|
55
|
+
): ZLinkMeshNodeDescriptor['populationCapacity'] | undefined;
|
|
56
|
+
|
|
52
57
|
updateMeshNode(
|
|
53
58
|
descriptor: ZLinkMeshNodeDescriptor,
|
|
54
59
|
intent: ZLinkLocationWriteIntent,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { routingIdsEqual } from '../routing-id';
|
|
1
2
|
import {
|
|
2
3
|
AUTHORITY_ENVELOPE_MAX_BYTES,
|
|
3
4
|
CREATION_INTENT_MAX_BYTES,
|
|
@@ -5,7 +6,10 @@ import {
|
|
|
5
6
|
} from '../../contracts/Configuration/InternalDefaults';
|
|
6
7
|
import { UINT64_MAX } from '@zlink-systems/stream-wire';
|
|
7
8
|
import { ZLINK_MAX_ROUTING_ID_BYTES } from '../../contracts/Common/CoreTypes';
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
ZLINK_PROVIDER_MAX_PAGE_SIZE,
|
|
11
|
+
ZLINK_PROVIDER_MAX_WRITE_KEYS
|
|
12
|
+
} from '../../contracts/Locations/Stores';
|
|
9
13
|
import { randomUUID } from 'node:crypto';
|
|
10
14
|
import { ZLinkFrameworkException, ZLinkFrameworkErrorKind } from '../../contracts';
|
|
11
15
|
import { SHA256_DIGEST_BYTES } from '../foundation/actor-join-recovery-codec';
|
|
@@ -71,7 +75,6 @@ export interface ZLinkInMemoryAuthorityValidation {
|
|
|
71
75
|
currentActive: ZLinkCapacityVector
|
|
72
76
|
): boolean;
|
|
73
77
|
identityClaimed?(authorityKey: string): boolean;
|
|
74
|
-
hasSpotMembers?(spotId: string, objectGeneration: bigint): boolean;
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
interface AuthorityRow {
|
|
@@ -344,6 +347,7 @@ export class ZLinkInMemoryAuthorityStore {
|
|
|
344
347
|
: current.creation === undefined)
|
|
345
348
|
)
|
|
346
349
|
return false;
|
|
350
|
+
let members: string[] = [];
|
|
347
351
|
if (current.snapshot.allocation.state === 'active') {
|
|
348
352
|
let unavailable = false;
|
|
349
353
|
for (const aggregate of this.aggregates.values()) {
|
|
@@ -374,21 +378,12 @@ export class ZLinkInMemoryAuthorityStore {
|
|
|
374
378
|
spot.stableType !== request.intent.stableType ||
|
|
375
379
|
spot.spotId !== request.key.globalId ||
|
|
376
380
|
spot.activationRecovery !== undefined;
|
|
377
|
-
if (
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const actor = decodeActorAuthorityPayload(
|
|
384
|
-
serviceRelocationAuthorityApplicationPayload(row.snapshot.payload)
|
|
385
|
-
);
|
|
386
|
-
unavailable ||=
|
|
387
|
-
actor?.currentSpotKind === ZLinkSpotKind.User &&
|
|
388
|
-
actor.currentSpotId === spot.spotId &&
|
|
389
|
-
actor.currentSpotGeneration === current.snapshot.objectGeneration;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
381
|
+
if (
|
|
382
|
+
spot?.kind === 'user_spot' &&
|
|
383
|
+
!unavailable &&
|
|
384
|
+
request?.actorRelocationPolicy === 'disabled'
|
|
385
|
+
)
|
|
386
|
+
members = this.endedSpotMembers(key.value, current.snapshot, spot.spotId);
|
|
392
387
|
}
|
|
393
388
|
if (unavailable || request?.actorRelocationPolicy !== 'disabled')
|
|
394
389
|
throw new ZLinkFrameworkException(
|
|
@@ -412,12 +407,83 @@ export class ZLinkInMemoryAuthorityStore {
|
|
|
412
407
|
-1
|
|
413
408
|
);
|
|
414
409
|
this.rows.delete(key.value);
|
|
410
|
+
for (const memberKey of members) {
|
|
411
|
+
const member = this.rows.get(memberKey)!;
|
|
412
|
+
this.adjustCapacity(this.activeCapacity, member.snapshot.allocation, -1);
|
|
413
|
+
this.rows.delete(memberKey);
|
|
414
|
+
}
|
|
415
415
|
if (current.snapshot.allocation.state === 'reserved' && current.creation !== undefined)
|
|
416
416
|
this.creationTerminals.set(current.creation.reservationId, 'aborted');
|
|
417
417
|
this.scanRevision++;
|
|
418
418
|
return true;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Every Actor membership of the old User Spot incarnation must belong to an ended-owner
|
|
423
|
+
* member (location runtime §6.1): a steady Ready, activated authority outside any aggregate
|
|
424
|
+
* with an invalid owner lease. The release must fit one provider batch; its key set mirrors
|
|
425
|
+
* the provider repository batch (authorities, owner leases, descriptor and capacity records).
|
|
426
|
+
*/
|
|
427
|
+
private endedSpotMembers(spotKey: string, spot: StoredSnapshot, spotId: string): string[] {
|
|
428
|
+
const descriptorKey = (descriptor: ZLinkMeshNodeDescriptorKey) =>
|
|
429
|
+
`${descriptor.meshName}\0${String(descriptor.rid)}`;
|
|
430
|
+
const batchKeys = new Set<string>([
|
|
431
|
+
`authority:${spotKey}`,
|
|
432
|
+
`owner:${spot.ownerId}`,
|
|
433
|
+
`descriptor:${descriptorKey(spot.allocation.descriptor)}`,
|
|
434
|
+
`capacity:${descriptorKey(spot.allocation.descriptor)}`
|
|
435
|
+
]);
|
|
436
|
+
const members: string[] = [];
|
|
437
|
+
for (const [memberKey, row] of this.rows) {
|
|
438
|
+
if (row.snapshot.allocation.objectKind !== 'actor') continue;
|
|
439
|
+
const actor = decodeActorAuthorityPayload(
|
|
440
|
+
serviceRelocationAuthorityApplicationPayload(row.snapshot.payload)
|
|
441
|
+
);
|
|
442
|
+
if (
|
|
443
|
+
actor?.currentSpotKind !== ZLinkSpotKind.User ||
|
|
444
|
+
actor.currentSpotId !== spotId ||
|
|
445
|
+
actor.currentSpotGeneration !== spot.objectGeneration
|
|
446
|
+
)
|
|
447
|
+
continue;
|
|
448
|
+
if (
|
|
449
|
+
row.snapshot.allocation.state !== 'active' ||
|
|
450
|
+
[...this.aggregates.values()].some(
|
|
451
|
+
(aggregate) =>
|
|
452
|
+
aggregate.state === 'prepared' &&
|
|
453
|
+
aggregate.request.participants.some(
|
|
454
|
+
(participant) => participant.authorityKey.value === memberKey
|
|
455
|
+
)
|
|
456
|
+
) ||
|
|
457
|
+
relocationAuthorityCodec.read(row.snapshot.payload) !== undefined ||
|
|
458
|
+
decodeActorAuthorityPayload(row.snapshot.payload)?.state !== 'ready'
|
|
459
|
+
)
|
|
460
|
+
throw new ZLinkFrameworkException(
|
|
461
|
+
ZLinkFrameworkErrorKind.Unavailable,
|
|
462
|
+
'User Spot still has a relocating or unactivated member.'
|
|
463
|
+
);
|
|
464
|
+
if (
|
|
465
|
+
this.validation.isOwnerLive({
|
|
466
|
+
ownerId: row.snapshot.ownerId,
|
|
467
|
+
leaseGeneration: row.snapshot.ownerLeaseGeneration
|
|
468
|
+
})
|
|
469
|
+
)
|
|
470
|
+
throw new ZLinkFrameworkException(
|
|
471
|
+
ZLinkFrameworkErrorKind.Unavailable,
|
|
472
|
+
'User Spot still has a member with a live owner lease.'
|
|
473
|
+
);
|
|
474
|
+
members.push(memberKey);
|
|
475
|
+
batchKeys.add(`authority:${memberKey}`);
|
|
476
|
+
batchKeys.add(`owner:${row.snapshot.ownerId}`);
|
|
477
|
+
batchKeys.add(`capacity:${descriptorKey(row.snapshot.allocation.descriptor)}`);
|
|
478
|
+
}
|
|
479
|
+
if (batchKeys.size > ZLINK_PROVIDER_MAX_WRITE_KEYS)
|
|
480
|
+
throw new ZLinkFrameworkException(
|
|
481
|
+
ZLinkFrameworkErrorKind.Unavailable,
|
|
482
|
+
'User Spot member release exceeds one Location Store batch.'
|
|
483
|
+
);
|
|
484
|
+
return members;
|
|
485
|
+
}
|
|
486
|
+
|
|
421
487
|
async reserve(
|
|
422
488
|
request: ZLinkObjectReserveRequest,
|
|
423
489
|
signal?: AbortSignal
|
|
@@ -1204,7 +1270,7 @@ function sameCreationTarget(
|
|
|
1204
1270
|
): boolean {
|
|
1205
1271
|
return (
|
|
1206
1272
|
target.descriptor.meshName === actual.meshName &&
|
|
1207
|
-
|
|
1273
|
+
routingIdsEqual(target.descriptor.rid, actual.nodeRid) &&
|
|
1208
1274
|
target.lifecycleGeneration === actual.nodeLifecycleGeneration &&
|
|
1209
1275
|
sameOwner(target.owner, actual.owner)
|
|
1210
1276
|
);
|
|
@@ -1218,11 +1284,7 @@ function sameDescriptor(
|
|
|
1218
1284
|
left: ZLinkMeshNodeDescriptorKey,
|
|
1219
1285
|
right: ZLinkMeshNodeDescriptorKey
|
|
1220
1286
|
): boolean {
|
|
1221
|
-
return left.meshName === right.meshName &&
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
function sameRid(left: unknown, right: unknown): boolean {
|
|
1225
|
-
return String(left) === String(right);
|
|
1287
|
+
return left.meshName === right.meshName && routingIdsEqual(left.rid, right.rid);
|
|
1226
1288
|
}
|
|
1227
1289
|
|
|
1228
1290
|
function capacityEntries(
|
|
@@ -145,18 +145,7 @@ export class ZLinkInMemoryLocationStore
|
|
|
145
145
|
typeCapacity.limit)))
|
|
146
146
|
);
|
|
147
147
|
},
|
|
148
|
-
identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey)
|
|
149
|
-
hasSpotMembers: (spotId, objectGeneration) => {
|
|
150
|
-
for (const actor of this.actors.rows.values()) {
|
|
151
|
-
if (
|
|
152
|
-
actor.spotKind === ZLinkSpotKind.User &&
|
|
153
|
-
String(actor.spotId) === spotId &&
|
|
154
|
-
actor.spotGeneration === objectGeneration
|
|
155
|
-
)
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
148
|
+
identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey)
|
|
160
149
|
},
|
|
161
150
|
now
|
|
162
151
|
);
|
|
@@ -6,6 +6,7 @@ export * from './in-memory-provider-location-store';
|
|
|
6
6
|
export * from './location-store-repository';
|
|
7
7
|
export * from './in-memory-authority-store';
|
|
8
8
|
export * from './lease-tracker';
|
|
9
|
+
export * from './request-source-resolver';
|
|
9
10
|
export * from './lifecycle';
|
|
10
11
|
export * from './resolvers';
|
|
11
12
|
export * from './runtime';
|
|
@@ -7,10 +7,7 @@ import {
|
|
|
7
7
|
type ZLinkOwnerLeaseReadResult
|
|
8
8
|
} from './internal-location-contracts';
|
|
9
9
|
import type { ZLinkOwnerLeaseStore } from './internal-store-contracts';
|
|
10
|
-
import {
|
|
11
|
-
import { ZLinkStateLane } from '../execution/state-lane';
|
|
12
|
-
|
|
13
|
-
const detachedLeaseRefreshResource = new AsyncResource('zlink:owner-lease-tracker');
|
|
10
|
+
import { startOutsideStateLane, ZLinkStateLane } from '../execution/state-lane';
|
|
14
11
|
|
|
15
12
|
export interface ZLinkOwnerLeaseTrackerOptions {
|
|
16
13
|
readonly store: ZLinkOwnerLeaseStore;
|
|
@@ -108,7 +105,7 @@ export class ZLinkOwnerLeaseTracker {
|
|
|
108
105
|
const prepared = await this.lane.run(() => this.prepareSnapshotRefresh(ownerId));
|
|
109
106
|
if (prepared.snapshot !== undefined) return prepared.snapshot;
|
|
110
107
|
if (prepared.start) {
|
|
111
|
-
void
|
|
108
|
+
void startOutsideStateLane(() => this.refreshSnapshot(ownerId, signal, prepared.refresh));
|
|
112
109
|
}
|
|
113
110
|
return await prepared.refresh.promise;
|
|
114
111
|
}
|
|
@@ -218,7 +215,3 @@ export class ZLinkLiveRowFilter {
|
|
|
218
215
|
return (await isLive(row, signal)) ? row : undefined;
|
|
219
216
|
}
|
|
220
217
|
}
|
|
221
|
-
|
|
222
|
-
function runDetachedLeaseRefresh(work: () => Promise<void>): Promise<void> {
|
|
223
|
-
return detachedLeaseRefreshResource.runInAsyncScope(work);
|
|
224
|
-
}
|