@zlink-systems/framework 0.25.0 → 0.26.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/Channels/IZLinkFanoutClient.d.ts +0 -6
- package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +1 -0
- package/dist/runtime/activation-admission.d.ts +29 -0
- package/dist/runtime/activation-admission.js +61 -0
- package/dist/runtime/actors/actor-context.js +6 -6
- package/dist/runtime/actors/actor-handoff.d.ts +9 -3
- package/dist/runtime/actors/actor-handoff.js +28 -17
- package/dist/runtime/actors/actor-local-native-join.js +2 -18
- package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
- package/dist/runtime/actors/actor-remote-joiner.js +6 -8
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
- package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
- package/dist/runtime/actors/deferred-join-completion.d.ts +14 -0
- package/dist/runtime/actors/deferred-join-completion.js +20 -0
- package/dist/runtime/actors/index.d.ts +1 -1
- package/dist/runtime/actors/index.js +15 -5
- package/dist/runtime/admission.d.ts +5 -1
- package/dist/runtime/admission.js +4 -0
- package/dist/runtime/backend/contracts/index.d.ts +2 -10
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -9
- package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +6 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +12 -28
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +1 -1
- package/dist/runtime/backend/node/node-event-loop-poller.js +8 -2
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +11 -3
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +12 -9
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +61 -29
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
- package/dist/runtime/backend/raw-binding-port.d.ts +12 -0
- package/dist/runtime/channels/channel-clients.d.ts +0 -1
- package/dist/runtime/channels/channel-clients.js +0 -8
- package/dist/runtime/channels/channel-outbound-operations.js +2 -10
- package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
- package/dist/runtime/channels/channel-runtime-manager.js +1 -12
- package/dist/runtime/channels/channel-socket-registry.d.ts +17 -4
- package/dist/runtime/channels/channel-socket-registry.js +49 -62
- package/dist/runtime/channels/channel-transports.d.ts +0 -3
- package/dist/runtime/channels/fanout-location-runtime.js +3 -9
- package/dist/runtime/execution/index.d.ts +18 -8
- package/dist/runtime/execution/index.js +55 -29
- package/dist/runtime/execution/serial-execution-queue.d.ts +5 -6
- package/dist/runtime/execution/serial-execution-queue.js +49 -15
- package/dist/runtime/foundation/listener-records.d.ts +11 -0
- package/dist/runtime/foundation/listener-records.js +20 -0
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +10 -21
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +66 -392
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +8 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +23 -2
- package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
- package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +16 -4
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +6 -13
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -7
- package/dist/runtime/foundation/service-stateful-runtime.js +100 -60
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +9 -4
- package/dist/runtime/foundation/service-stateful-wire-codec.js +153 -90
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -2
- package/dist/runtime/foundation/service-topology-registry.js +6 -30
- package/dist/runtime/host/actor-transfer-runtime.d.ts +17 -15
- package/dist/runtime/host/actor-transfer-runtime.js +73 -86
- package/dist/runtime/host/index.d.ts +6 -2
- package/dist/runtime/host/index.js +63 -37
- package/dist/runtime/host/remote-bound-session-relay.js +4 -3
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -0
- package/dist/runtime/host/route-mesh-runtime.js +7 -5
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +50 -8
- package/dist/runtime/host/service-relocation-host-runtime.js +343 -270
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +7 -4
- package/dist/runtime/host/spot-runtime-options-factory.js +4 -8
- package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +11 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +85 -87
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -6
- package/dist/runtime/locations/lifecycle.d.ts +1 -1
- package/dist/runtime/locations/lifecycle.js +2 -2
- package/dist/runtime/locations/resolvers.js +7 -2
- package/dist/runtime/locations/spot-location-claims.d.ts +2 -2
- package/dist/runtime/locations/spot-location-claims.js +3 -27
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +5 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +3 -3
- package/dist/runtime/spots/index.d.ts +25 -19
- package/dist/runtime/spots/index.js +207 -205
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +34 -31
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
- package/dist/runtime/spots/spot-activation-state.js +4 -17
- package/dist/runtime/spots/spot-activation.d.ts +8 -6
- package/dist/runtime/spots/spot-activation.js +54 -49
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +1 -1
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-join-dispatch.js +3 -5
- package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -0
- package/dist/runtime/spots/spot-actor-membership.js +26 -12
- package/dist/runtime/spots/spot-entry-activation.d.ts +1 -2
- package/dist/runtime/spots/spot-entry-activation.js +0 -1
- package/dist/runtime/spots/spot-manager-public.js +1 -1
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +1 -1
- package/dist/runtime/spots/spot-native-actor-join-admission.js +2 -2
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +5 -5
- package/dist/runtime/spots/spot-node-runtime-manager.js +7 -11
- package/dist/runtime/spots/spot-outbound.js +1 -29
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-actor-admission.js +10 -0
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -6
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +2 -70
- package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -5
- package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
- package/dist/runtime/spots/spot-serial-executor.js +8 -1
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
- package/dist/runtime/spots/spot-serial-turn-executor.js +8 -4
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +13 -15
- package/dist/runtime/streams/actor-session-binding-registry.js +19 -171
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +3 -4
- package/dist/runtime/streams/bound-session-service.js +1 -18
- package/dist/runtime/streams/index.d.ts +2 -0
- package/dist/runtime/streams/index.js +19 -19
- package/dist/runtime/streams/session-serial-executor.js +2 -2
- package/package.json +3 -3
- package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
- package/src/internal.ts +1 -0
- package/src/runtime/activation-admission.ts +78 -0
- package/src/runtime/actors/actor-context.ts +6 -6
- package/src/runtime/actors/actor-handoff.ts +31 -23
- package/src/runtime/actors/actor-local-native-join.ts +3 -42
- package/src/runtime/actors/actor-remote-joiner.ts +6 -25
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
- package/src/runtime/actors/actor-source-transfer.ts +5 -18
- package/src/runtime/actors/deferred-join-completion.ts +40 -0
- package/src/runtime/actors/index.ts +22 -9
- package/src/runtime/admission.ts +5 -1
- package/src/runtime/backend/contracts/index.ts +2 -13
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -10
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
- package/src/runtime/backend/node/node-backend-adapter-support.ts +9 -29
- package/src/runtime/backend/node/node-event-loop-poller.ts +14 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +17 -3
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +65 -32
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +2 -2
- package/src/runtime/backend/raw-binding-port.ts +13 -0
- package/src/runtime/channels/channel-clients.ts +0 -11
- package/src/runtime/channels/channel-outbound-operations.ts +3 -11
- package/src/runtime/channels/channel-runtime-manager.ts +4 -15
- package/src/runtime/channels/channel-socket-registry.ts +69 -71
- package/src/runtime/channels/channel-transports.ts +0 -3
- package/src/runtime/channels/fanout-location-runtime.ts +4 -16
- package/src/runtime/execution/index.ts +68 -30
- package/src/runtime/execution/serial-execution-queue.ts +52 -20
- package/src/runtime/foundation/listener-records.ts +21 -0
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +66 -466
- package/src/runtime/foundation/service-authority-payload-codec.ts +10 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +30 -9
- package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
- package/src/runtime/foundation/service-relocation-object-owner.ts +18 -5
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +6 -14
- package/src/runtime/foundation/service-stateful-runtime.ts +151 -89
- package/src/runtime/foundation/service-stateful-wire-codec.ts +203 -121
- package/src/runtime/foundation/service-topology-registry.ts +8 -48
- package/src/runtime/host/actor-transfer-runtime.ts +94 -166
- package/src/runtime/host/index.ts +119 -54
- package/src/runtime/host/remote-bound-session-relay.ts +4 -3
- package/src/runtime/host/route-mesh-runtime.ts +9 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +495 -376
- package/src/runtime/host/spot-runtime-options-factory.ts +24 -13
- package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
- package/src/runtime/host/user-spot-creation-coordinator.ts +147 -142
- package/src/runtime/locations/in-memory-provider-location-store.ts +11 -7
- package/src/runtime/locations/lifecycle.ts +3 -2
- package/src/runtime/locations/resolvers.ts +19 -13
- package/src/runtime/locations/spot-location-claims.ts +5 -34
- package/src/runtime/protocol/service_wire_codec.generated.ts +9 -2
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +3 -3
- package/src/runtime/spots/index.ts +341 -295
- package/src/runtime/spots/spot-activation-registry.ts +41 -31
- package/src/runtime/spots/spot-activation-state.ts +4 -16
- package/src/runtime/spots/spot-activation.ts +102 -80
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +2 -2
- package/src/runtime/spots/spot-actor-join-dispatch.ts +6 -7
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
- package/src/runtime/spots/spot-actor-membership.ts +81 -17
- package/src/runtime/spots/spot-entry-activation.ts +0 -3
- package/src/runtime/spots/spot-manager-public.ts +8 -4
- package/src/runtime/spots/spot-native-actor-join-admission.ts +2 -2
- package/src/runtime/spots/spot-node-runtime-manager.ts +12 -18
- package/src/runtime/spots/spot-outbound.ts +4 -47
- package/src/runtime/spots/spot-routed-actor-admission.ts +20 -0
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -76
- package/src/runtime/spots/spot-runtime-ports.ts +6 -17
- package/src/runtime/spots/spot-serial-executor.ts +9 -1
- package/src/runtime/spots/spot-serial-turn-executor.ts +10 -4
- package/src/runtime/streams/actor-session-binding-registry.ts +20 -308
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +2 -12
- package/src/runtime/streams/bound-session-service.ts +2 -36
- package/src/runtime/streams/index.ts +29 -27
- package/src/runtime/streams/session-serial-executor.ts +2 -2
- package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
- package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
- package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
|
@@ -49,12 +49,20 @@ export interface ZLinkSpotRuntimeOptionsFactoryOptions {
|
|
|
49
49
|
) => Promise<void>;
|
|
50
50
|
readonly beginInstanceIdleClosingAuthority: (
|
|
51
51
|
meshName: string,
|
|
52
|
-
spotId: string
|
|
53
|
-
|
|
52
|
+
spotId: string,
|
|
53
|
+
onCommitted: () => void
|
|
54
|
+
) => Promise<{ release(): Promise<void> } | undefined>;
|
|
54
55
|
readonly beginInstanceClosingAuthority: (
|
|
55
56
|
meshName: string,
|
|
56
|
-
spotId: string
|
|
57
|
-
|
|
57
|
+
spotId: string,
|
|
58
|
+
onCommitted: () => void
|
|
59
|
+
) => Promise<{ release(): Promise<void> } | undefined>;
|
|
60
|
+
readonly beginUserClosingAuthority: (
|
|
61
|
+
meshName: string,
|
|
62
|
+
spotId: string,
|
|
63
|
+
objectGeneration: bigint,
|
|
64
|
+
onCommitted: () => void
|
|
65
|
+
) => Promise<{ release(): Promise<void> } | undefined>;
|
|
58
66
|
readonly createLocationSpotRouteResolver: () => ZLinkSpotRouteResolver | undefined;
|
|
59
67
|
readonly boundSessionRelay: ZLinkBoundSessionRelay;
|
|
60
68
|
readonly actorHandoff: ZLinkActorHandoffCoordinator;
|
|
@@ -149,10 +157,17 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
149
157
|
locationLifecycle: this.options.locationLifecycle(),
|
|
150
158
|
releaseInstanceAuthority: (meshName, spotId, objectGeneration) =>
|
|
151
159
|
this.options.releaseInstanceAuthority(meshName, String(spotId), objectGeneration),
|
|
152
|
-
beginInstanceIdleClosingAuthority: (meshName, spotId) =>
|
|
153
|
-
this.options.beginInstanceIdleClosingAuthority(meshName, String(spotId)),
|
|
154
|
-
beginInstanceClosingAuthority: (meshName, spotId) =>
|
|
155
|
-
this.options.beginInstanceClosingAuthority(meshName, String(spotId)),
|
|
160
|
+
beginInstanceIdleClosingAuthority: (meshName, spotId, onCommitted) =>
|
|
161
|
+
this.options.beginInstanceIdleClosingAuthority(meshName, String(spotId), onCommitted),
|
|
162
|
+
beginInstanceClosingAuthority: (meshName, spotId, onCommitted) =>
|
|
163
|
+
this.options.beginInstanceClosingAuthority(meshName, String(spotId), onCommitted),
|
|
164
|
+
beginUserClosingAuthority: (meshName, spotId, objectGeneration, onCommitted) =>
|
|
165
|
+
this.options.beginUserClosingAuthority(
|
|
166
|
+
meshName,
|
|
167
|
+
String(spotId),
|
|
168
|
+
objectGeneration,
|
|
169
|
+
onCommitted
|
|
170
|
+
),
|
|
156
171
|
instanceSpotApplicationTargetProvider: (meshName, spotId) =>
|
|
157
172
|
this.options
|
|
158
173
|
.spotNodeRuntime()
|
|
@@ -196,11 +211,6 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
196
211
|
}
|
|
197
212
|
} as never;
|
|
198
213
|
},
|
|
199
|
-
createReceived: () => {
|
|
200
|
-
const runtime = this.options.spotNodeRuntime();
|
|
201
|
-
if (runtime === undefined) throw new Error('Spot backend runtime is not initialized.');
|
|
202
|
-
return runtime.createReceived();
|
|
203
|
-
},
|
|
204
214
|
createTopicMessage: () => {
|
|
205
215
|
const runtime = this.options.spotNodeRuntime();
|
|
206
216
|
if (runtime === undefined) throw new Error('Spot backend runtime is not initialized.');
|
|
@@ -275,6 +285,7 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
275
285
|
metrics: this.options.metrics,
|
|
276
286
|
admission: this.options.admission,
|
|
277
287
|
statefulExecutionAllowed: this.options.statefulExecutionAllowed,
|
|
288
|
+
closeErrorSink: this.options.runtimeOrPreStartErrorSink,
|
|
278
289
|
dispatchErrors: this.options.dispatchErrorReporter(this.options.runtimeOrPreStartErrorSink)
|
|
279
290
|
};
|
|
280
291
|
}
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
} from '../foundation/service-stateful-wire-codec';
|
|
20
20
|
import { routingIdsEqual } from '../routing-id';
|
|
21
21
|
import {
|
|
22
|
+
decodeServiceClosingSpotAuthority,
|
|
22
23
|
decodeServiceInstanceAuthorityPayload,
|
|
23
24
|
decodeServiceReadySpotAuthority,
|
|
24
25
|
type ServiceActivationRecoveryState
|
|
@@ -74,6 +75,7 @@ interface StatefulAuthorityRouteSink {
|
|
|
74
75
|
|
|
75
76
|
interface AppliedAuthorityRoute {
|
|
76
77
|
readonly kind: 'user_spot' | 'instance_spot';
|
|
78
|
+
readonly closing: boolean;
|
|
77
79
|
readonly stableType: string;
|
|
78
80
|
readonly meshName: string;
|
|
79
81
|
readonly spotRoute: ServiceDirectSpotRouteFence;
|
|
@@ -189,7 +191,7 @@ export class ZLinkStatefulAuthorityRouteRuntime {
|
|
|
189
191
|
const expectedInstanceRoute =
|
|
190
192
|
previousRoute?.kind === 'instance_spot' ? previousRoute.instanceRoute : null;
|
|
191
193
|
sink.rememberSpotRoute(route.spotRoute, expectedSpotRoute);
|
|
192
|
-
if (route.kind === 'instance_spot') {
|
|
194
|
+
if (route.kind === 'instance_spot' && !route.closing) {
|
|
193
195
|
const status = sink.status();
|
|
194
196
|
if (
|
|
195
197
|
routingIdsEqual(status.routingId, route.instanceRoute.targetNodeRid) &&
|
|
@@ -555,9 +557,9 @@ function pendingInstanceActivation(
|
|
|
555
557
|
|
|
556
558
|
function authorityRoute(snapshot: ZLinkAuthoritySnapshot): AppliedAuthorityRoute | undefined {
|
|
557
559
|
const allocation = snapshot.allocation;
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
);
|
|
560
|
+
const payload = serviceRelocationAuthorityApplicationPayload(snapshot.payload);
|
|
561
|
+
const ready = decodeServiceReadySpotAuthority(payload);
|
|
562
|
+
const decoded = ready ?? decodeServiceClosingSpotAuthority(payload);
|
|
561
563
|
if (
|
|
562
564
|
allocation.state !== 'active' ||
|
|
563
565
|
allocation.objectKind === 'actor' ||
|
|
@@ -585,6 +587,7 @@ function authorityRoute(snapshot: ZLinkAuthoritySnapshot): AppliedAuthorityRoute
|
|
|
585
587
|
};
|
|
586
588
|
return {
|
|
587
589
|
kind: allocation.objectKind,
|
|
590
|
+
closing: ready === undefined,
|
|
588
591
|
stableType: allocation.stableType,
|
|
589
592
|
meshName: allocation.descriptor.meshName,
|
|
590
593
|
spotRoute,
|
|
@@ -617,6 +620,7 @@ function sameAppliedRoute(
|
|
|
617
620
|
if (right === undefined) return false;
|
|
618
621
|
return (
|
|
619
622
|
left.kind === right.kind &&
|
|
623
|
+
left.closing === right.closing &&
|
|
620
624
|
left.stableType === right.stableType &&
|
|
621
625
|
left.meshName === right.meshName &&
|
|
622
626
|
left.instanceRoute.targetNodeRid === right.instanceRoute.targetNodeRid &&
|
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
import { ZLinkFrameworkException, ZLinkSpotCreateState } from '../../contracts';
|
|
18
18
|
import {
|
|
19
19
|
decodeServiceReadySpotAuthority,
|
|
20
|
+
decodeServiceClosingSpotAuthority,
|
|
20
21
|
encodeServiceUserSpotAuthorityPayload
|
|
21
22
|
} from '../foundation/service-authority-payload-codec';
|
|
22
23
|
import { encodeAuthorityKey } from '../locations/authority-key-codec';
|
|
@@ -332,55 +333,34 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
332
333
|
|
|
333
334
|
async close(
|
|
334
335
|
spot: SpotRef,
|
|
335
|
-
closeOwner: (
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
336
|
+
closeOwner: (
|
|
337
|
+
current: SpotRef,
|
|
338
|
+
beginAuthority: (onCommitted: () => void) => Promise<{ release(): Promise<void> }>
|
|
339
|
+
) => Promise<boolean>,
|
|
340
|
+
signal?: AbortSignal
|
|
339
341
|
): Promise<boolean> {
|
|
340
342
|
const resolved = await this.resolveCloseTarget(spot, signal);
|
|
341
343
|
if (resolved === undefined) return false;
|
|
342
344
|
const { spot: currentRef, snapshot: current } = resolved;
|
|
343
345
|
const key = encodeAuthorityKey('user_spot', String(spot.spotId));
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
347
|
-
`User Spot '${String(spot.spotId)}' is missing from its authority owner.`,
|
|
348
|
-
true
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
if (ownerCanClose?.(currentRef) === false) return false;
|
|
352
|
-
const closing = await this.beginClosing(key, current, String(spot.spotId), signal);
|
|
353
|
-
let closed: boolean;
|
|
354
|
-
try {
|
|
355
|
-
closed = await closeOwner(currentRef, closing);
|
|
356
|
-
} catch (error) {
|
|
357
|
-
await this.restoreReady(key, closing, String(spot.spotId), signal);
|
|
358
|
-
throw error;
|
|
359
|
-
}
|
|
360
|
-
if (!closed) {
|
|
361
|
-
await this.restoreReady(key, closing, String(spot.spotId), signal);
|
|
362
|
-
return false;
|
|
363
|
-
}
|
|
364
|
-
const deleted = await this.options.store.compareExchangeAuthority(
|
|
365
|
-
key,
|
|
366
|
-
closing.storeVersion,
|
|
367
|
-
{ kind: 'delete' },
|
|
368
|
-
signal
|
|
346
|
+
return await closeOwner(currentRef, async (onCommitted) =>
|
|
347
|
+
this.commitCloseAuthority(key, current, String(spot.spotId), onCommitted)
|
|
369
348
|
);
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** Commits Closing for the owner's own incarnation when its context requests Close. */
|
|
352
|
+
async beginOwnerClose(
|
|
353
|
+
spot: SpotRef,
|
|
354
|
+
onCommitted: () => void
|
|
355
|
+
): Promise<{ release(): Promise<void> } | undefined> {
|
|
356
|
+
const resolved = await this.resolveCloseTarget(spot);
|
|
357
|
+
if (resolved === undefined) return undefined;
|
|
358
|
+
const spotId = String(spot.spotId);
|
|
359
|
+
return await this.commitCloseAuthority(
|
|
360
|
+
encodeAuthorityKey('user_spot', spotId),
|
|
361
|
+
resolved.snapshot,
|
|
362
|
+
spotId,
|
|
363
|
+
onCommitted
|
|
384
364
|
);
|
|
385
365
|
}
|
|
386
366
|
|
|
@@ -391,29 +371,14 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
391
371
|
const key = encodeAuthorityKey('user_spot', String(spot.spotId));
|
|
392
372
|
const current = await this.options.store.readAuthority(key, signal);
|
|
393
373
|
if (current.kind === 'missing') return undefined;
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
spotId: spot.spotId,
|
|
403
|
-
stableType: current.allocation.stableType,
|
|
404
|
-
requestPayload: Buffer.alloc(0),
|
|
405
|
-
timeoutMs: 1
|
|
406
|
-
});
|
|
407
|
-
if (
|
|
408
|
-
String(current.allocation.descriptor.rid) !== String(spot.nodeRid) ||
|
|
409
|
-
current.allocation.descriptor.meshName !== spot.meshName
|
|
410
|
-
) {
|
|
411
|
-
throw createInternalFrameworkException(
|
|
412
|
-
ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
|
|
413
|
-
`User Spot '${String(spot.spotId)}' owner route is stale.`
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
return { spot: currentRef, snapshot: current };
|
|
374
|
+
return {
|
|
375
|
+
spot: requireCloseTarget(current, String(spot.spotId), {
|
|
376
|
+
objectGeneration: spot.objectGeneration,
|
|
377
|
+
nodeRid: String(spot.nodeRid),
|
|
378
|
+
meshName: spot.meshName
|
|
379
|
+
}),
|
|
380
|
+
snapshot: current
|
|
381
|
+
};
|
|
417
382
|
}
|
|
418
383
|
|
|
419
384
|
async handleRemoteCreate(
|
|
@@ -672,65 +637,71 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
672
637
|
|
|
673
638
|
async handleRemoteClose(
|
|
674
639
|
record: ServiceUserSpotCloseRecord,
|
|
675
|
-
closeOwner: (
|
|
676
|
-
|
|
640
|
+
closeOwner: (
|
|
641
|
+
spot: SpotRef,
|
|
642
|
+
beginAuthority: (onCommitted: () => void) => Promise<{ release(): Promise<void> }>,
|
|
643
|
+
signal?: AbortSignal
|
|
644
|
+
) => Promise<boolean>,
|
|
645
|
+
signal?: AbortSignal,
|
|
646
|
+
canResume?: (spot: SpotRef) => boolean
|
|
677
647
|
): Promise<boolean> {
|
|
678
648
|
const key = encodeAuthorityKey('user_spot', record.target.spotId);
|
|
679
649
|
const current = await this.options.store.readAuthority(key, signal);
|
|
680
650
|
if (current.kind === 'missing') return false;
|
|
681
|
-
|
|
682
|
-
throw createInternalFrameworkException(
|
|
683
|
-
ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
|
|
684
|
-
`User Spot '${record.target.spotId}' generation is stale.`
|
|
685
|
-
);
|
|
686
|
-
}
|
|
687
|
-
if (
|
|
688
|
-
current.authorityOwnerGeneration !== record.target.authorityOwnerGeneration ||
|
|
689
|
-
current.storeVersion.value !== record.target.expectedStoreVersion ||
|
|
690
|
-
String(current.allocation.descriptor.rid) !== record.target.targetNodeRid ||
|
|
691
|
-
current.allocation.descriptorLifecycleGeneration !== record.target.targetNodeGeneration ||
|
|
692
|
-
current.allocation.objectKind !== 'user_spot' ||
|
|
693
|
-
current.allocation.state !== 'active'
|
|
694
|
-
) {
|
|
695
|
-
throw createInternalFrameworkException(
|
|
696
|
-
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
697
|
-
`User Spot '${record.target.spotId}' close authority is moving.`,
|
|
698
|
-
true
|
|
699
|
-
);
|
|
700
|
-
}
|
|
701
|
-
const spot: SpotRef = {
|
|
651
|
+
const candidate: SpotRef = {
|
|
702
652
|
spotId: record.target.spotId as RoutingId,
|
|
703
653
|
objectGeneration: current.objectGeneration,
|
|
704
654
|
meshName: current.allocation.descriptor.meshName,
|
|
705
655
|
nodeRid: current.allocation.descriptor.rid
|
|
706
656
|
};
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
657
|
+
// A Closing committed by this owner is resumed, so its store version has
|
|
658
|
+
// advanced past the one the source observed.
|
|
659
|
+
const resuming =
|
|
660
|
+
canResume?.(candidate) === true &&
|
|
661
|
+
decodeServiceClosingSpotAuthority(current.payload)?.kind === 'user_spot';
|
|
662
|
+
const spot = requireCloseTarget(current, record.target.spotId, {
|
|
663
|
+
objectGeneration: record.target.objectGeneration,
|
|
664
|
+
nodeRid: record.target.targetNodeRid,
|
|
665
|
+
nodeGeneration: record.target.targetNodeGeneration,
|
|
666
|
+
authorityOwnerGeneration: record.target.authorityOwnerGeneration,
|
|
667
|
+
storeVersion: resuming ? undefined : record.target.expectedStoreVersion
|
|
668
|
+
});
|
|
669
|
+
return await closeOwner(
|
|
670
|
+
spot,
|
|
671
|
+
async (onCommitted) =>
|
|
672
|
+
this.commitCloseAuthority(key, current, record.target.spotId, onCommitted),
|
|
723
673
|
signal
|
|
724
674
|
);
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
private async commitCloseAuthority(
|
|
678
|
+
key: ReturnType<typeof encodeAuthorityKey>,
|
|
679
|
+
current: ZLinkAuthoritySnapshot,
|
|
680
|
+
spotId: string,
|
|
681
|
+
onCommitted: () => void
|
|
682
|
+
): Promise<{ release(): Promise<void> }> {
|
|
683
|
+
const closing = await this.beginClosing(key, current, spotId);
|
|
684
|
+
const authority = {
|
|
685
|
+
release: async () => {
|
|
686
|
+
this.forgetReadyRoute(spotId as RoutingId, current);
|
|
687
|
+
const deleted = await this.options.store.compareExchangeAuthority(
|
|
688
|
+
key,
|
|
689
|
+
closing.storeVersion,
|
|
690
|
+
{
|
|
691
|
+
kind: 'delete'
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
if (deleted.kind !== 'deleted') {
|
|
695
|
+
throw createInternalFrameworkException(
|
|
696
|
+
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
697
|
+
`User Spot '${spotId}' authority changed while closing.`,
|
|
698
|
+
true
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
onCommitted();
|
|
704
|
+
return authority;
|
|
734
705
|
}
|
|
735
706
|
|
|
736
707
|
forgetReadyRoute(spotId: RoutingId, snapshot: ZLinkAuthoritySnapshot): void {
|
|
@@ -743,8 +714,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
743
714
|
private async beginClosing(
|
|
744
715
|
key: ReturnType<typeof encodeAuthorityKey>,
|
|
745
716
|
current: ZLinkAuthoritySnapshot,
|
|
746
|
-
spotId: string
|
|
747
|
-
signal?: AbortSignal
|
|
717
|
+
spotId: string
|
|
748
718
|
): Promise<ZLinkAuthoritySnapshot> {
|
|
749
719
|
const ready = decodeServiceReadySpotAuthority(current.payload);
|
|
750
720
|
if (
|
|
@@ -766,7 +736,7 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
766
736
|
payload: userSpotAuthorityPayload(current, spotId, 'closing'),
|
|
767
737
|
generationTransition: 'preserve'
|
|
768
738
|
},
|
|
769
|
-
|
|
739
|
+
undefined
|
|
770
740
|
);
|
|
771
741
|
if (closing.kind === 'stored') {
|
|
772
742
|
const { kind: _kind, ...snapshot } = closing;
|
|
@@ -779,31 +749,6 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
779
749
|
);
|
|
780
750
|
}
|
|
781
751
|
|
|
782
|
-
private async restoreReady(
|
|
783
|
-
key: ReturnType<typeof encodeAuthorityKey>,
|
|
784
|
-
closing: ZLinkAuthoritySnapshot,
|
|
785
|
-
spotId: string,
|
|
786
|
-
signal?: AbortSignal
|
|
787
|
-
): Promise<void> {
|
|
788
|
-
const restored = await this.options.store.compareExchangeAuthority(
|
|
789
|
-
key,
|
|
790
|
-
closing.storeVersion,
|
|
791
|
-
{
|
|
792
|
-
kind: 'put',
|
|
793
|
-
payload: userSpotAuthorityPayload(closing, spotId, 'ready'),
|
|
794
|
-
generationTransition: 'preserve'
|
|
795
|
-
},
|
|
796
|
-
signal
|
|
797
|
-
);
|
|
798
|
-
if (restored.kind !== 'stored') {
|
|
799
|
-
throw createInternalFrameworkException(
|
|
800
|
-
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
801
|
-
'User Spot Ready authority could not be restored after close was declined.',
|
|
802
|
-
true
|
|
803
|
-
);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
|
|
807
752
|
private async awaitReady(
|
|
808
753
|
request: ZLinkUserSpotCreationRequest,
|
|
809
754
|
signal: AbortSignal
|
|
@@ -926,6 +871,66 @@ function readySpotRoute(
|
|
|
926
871
|
};
|
|
927
872
|
}
|
|
928
873
|
|
|
874
|
+
/** The Close fence a caller observed; omitted parts are not part of that caller's fence. */
|
|
875
|
+
interface ZLinkUserSpotCloseFence {
|
|
876
|
+
readonly objectGeneration: bigint;
|
|
877
|
+
readonly nodeRid: string;
|
|
878
|
+
readonly meshName?: string;
|
|
879
|
+
readonly nodeGeneration?: bigint;
|
|
880
|
+
readonly authorityOwnerGeneration?: bigint;
|
|
881
|
+
readonly storeVersion?: string;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* The single classifier of a Close target (§7, §9): another ObjectGeneration is
|
|
886
|
+
* SpotGenerationStale; any owner fence difference or an authority that is not
|
|
887
|
+
* in a Framework-owned Ready or Closing state is SpotMoving.
|
|
888
|
+
*/
|
|
889
|
+
function requireCloseTarget(
|
|
890
|
+
current: ZLinkAuthoritySnapshot,
|
|
891
|
+
spotId: string,
|
|
892
|
+
fence: ZLinkUserSpotCloseFence
|
|
893
|
+
): SpotRef {
|
|
894
|
+
if (current.objectGeneration !== fence.objectGeneration) {
|
|
895
|
+
throw createInternalFrameworkException(
|
|
896
|
+
ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
|
|
897
|
+
`User Spot '${spotId}' generation is stale.`
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
// A committed Closing stays the close target: its owner resumes that Close.
|
|
901
|
+
const decoded =
|
|
902
|
+
decodeServiceReadySpotAuthority(current.payload) ??
|
|
903
|
+
decodeServiceClosingSpotAuthority(current.payload);
|
|
904
|
+
const allocation = current.allocation;
|
|
905
|
+
if (
|
|
906
|
+
decoded?.kind !== 'user_spot' ||
|
|
907
|
+
decoded.spotId !== spotId ||
|
|
908
|
+
decoded.ownerId !== current.ownerId ||
|
|
909
|
+
decoded.ownerLeaseGeneration !== current.ownerLeaseGeneration ||
|
|
910
|
+
allocation.objectKind !== 'user_spot' ||
|
|
911
|
+
allocation.state !== 'active' ||
|
|
912
|
+
String(allocation.descriptor.rid) !== fence.nodeRid ||
|
|
913
|
+
(fence.meshName !== undefined && allocation.descriptor.meshName !== fence.meshName) ||
|
|
914
|
+
(fence.nodeGeneration !== undefined &&
|
|
915
|
+
allocation.descriptorLifecycleGeneration !== fence.nodeGeneration) ||
|
|
916
|
+
(fence.authorityOwnerGeneration !== undefined &&
|
|
917
|
+
current.authorityOwnerGeneration !== fence.authorityOwnerGeneration) ||
|
|
918
|
+
(fence.storeVersion !== undefined && current.storeVersion.value !== fence.storeVersion)
|
|
919
|
+
) {
|
|
920
|
+
throw createInternalFrameworkException(
|
|
921
|
+
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
922
|
+
`User Spot '${spotId}' owner fence changed or the Spot is moving.`,
|
|
923
|
+
true
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
return {
|
|
927
|
+
spotId: spotId as RoutingId,
|
|
928
|
+
objectGeneration: current.objectGeneration,
|
|
929
|
+
meshName: allocation.descriptor.meshName,
|
|
930
|
+
nodeRid: allocation.descriptor.rid
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
|
|
929
934
|
function spotRef(
|
|
930
935
|
snapshot: ZLinkAuthoritySnapshot,
|
|
931
936
|
request: ZLinkUserSpotCreationRequest,
|
|
@@ -70,12 +70,10 @@ export class ZLinkInMemoryProviderLocationStore implements ZLinkLocationStore {
|
|
|
70
70
|
this.values.delete(mutation.key.value);
|
|
71
71
|
continue;
|
|
72
72
|
}
|
|
73
|
-
requireValue(mutation.bytes, mutation.retentionMs);
|
|
73
|
+
const retentionMs = requireValue(mutation.bytes, mutation.retentionMs);
|
|
74
74
|
const version = storeVersion((++this.nextVersion).toString());
|
|
75
75
|
const expiresAt =
|
|
76
|
-
|
|
77
|
-
? undefined
|
|
78
|
-
: new Date(storeNow.getTime() + mutation.retentionMs);
|
|
76
|
+
retentionMs === undefined ? undefined : new Date(storeNow.getTime() + retentionMs);
|
|
79
77
|
this.values.set(mutation.key.value, {
|
|
80
78
|
bytes: mutation.bytes.slice(),
|
|
81
79
|
version,
|
|
@@ -195,13 +193,19 @@ function requireScanRequest(request: ZLinkStoreScanRequest): void {
|
|
|
195
193
|
}
|
|
196
194
|
}
|
|
197
195
|
|
|
198
|
-
function requireValue(bytes: Uint8Array, retentionMs: number | undefined):
|
|
196
|
+
function requireValue(bytes: Uint8Array, retentionMs: number | undefined): number | undefined {
|
|
199
197
|
if (bytes.byteLength > 1024 * 1024) {
|
|
200
198
|
throw new RangeError('Location Store value exceeds 1 MiB.');
|
|
201
199
|
}
|
|
202
|
-
if (
|
|
203
|
-
|
|
200
|
+
if (
|
|
201
|
+
retentionMs !== undefined &&
|
|
202
|
+
(!Number.isFinite(retentionMs) ||
|
|
203
|
+
retentionMs <= 0 ||
|
|
204
|
+
!Number.isSafeInteger(Math.ceil(retentionMs)))
|
|
205
|
+
) {
|
|
206
|
+
throw new RangeError('Location Store retention must round to a positive safe integer.');
|
|
204
207
|
}
|
|
208
|
+
return retentionMs === undefined ? undefined : Math.ceil(retentionMs);
|
|
205
209
|
}
|
|
206
210
|
|
|
207
211
|
function requireKey(value: string): void {
|
|
@@ -226,9 +226,10 @@ export class ZLinkLocationLifecycle {
|
|
|
226
226
|
|
|
227
227
|
async beginInstanceSpotClosing(
|
|
228
228
|
meshName: string,
|
|
229
|
-
spotId: RoutingId
|
|
229
|
+
spotId: RoutingId,
|
|
230
|
+
onCommitted: () => void
|
|
230
231
|
): Promise<ZLinkInstanceClosingAuthority | undefined> {
|
|
231
|
-
return await this.spotClaims.beginInstanceClosing(meshName, spotId);
|
|
232
|
+
return await this.spotClaims.beginInstanceClosing(meshName, spotId, onCommitted);
|
|
232
233
|
}
|
|
233
234
|
|
|
234
235
|
trackInstanceSpot(input: ZLinkTrackedInstanceAuthority): void {
|
|
@@ -29,7 +29,10 @@ import type {
|
|
|
29
29
|
ZLinkRouteLocationStore,
|
|
30
30
|
ZLinkSpotLocationStore
|
|
31
31
|
} from './internal-store-contracts';
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
decodeServiceClosingSpotAuthority,
|
|
34
|
+
decodeServiceReadySpotAuthority
|
|
35
|
+
} from '../foundation/service-authority-payload-codec';
|
|
33
36
|
import { serviceRelocationAuthorityApplicationPayload } from '../foundation/service-relocation-runtime';
|
|
34
37
|
import { decodeActorAuthorityIdentity } from '../actors/actor-authority-publication';
|
|
35
38
|
import { encodeAuthorityKey } from './authority-key-codec';
|
|
@@ -930,9 +933,10 @@ export class ZLinkAuthoritySpotRouteResolver implements ZLinkSpotRouteResolver {
|
|
|
930
933
|
|
|
931
934
|
const current = await this.store.readAuthority(encodeAuthorityKey('user_spot', key), signal);
|
|
932
935
|
if (current.kind === 'snapshot' && current.allocation.state === 'active') {
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
);
|
|
936
|
+
const authorityPayload = serviceRelocationAuthorityApplicationPayload(current.payload);
|
|
937
|
+
const ready = decodeServiceReadySpotAuthority(authorityPayload);
|
|
938
|
+
const closing = decodeServiceClosingSpotAuthority(authorityPayload);
|
|
939
|
+
const decoded = ready ?? closing;
|
|
936
940
|
if (
|
|
937
941
|
decoded !== undefined &&
|
|
938
942
|
decoded.spotId === String(spotId) &&
|
|
@@ -975,15 +979,17 @@ export class ZLinkAuthoritySpotRouteResolver implements ZLinkSpotRouteResolver {
|
|
|
975
979
|
signal
|
|
976
980
|
)
|
|
977
981
|
};
|
|
978
|
-
|
|
979
|
-
this.
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
982
|
+
if (ready !== undefined) {
|
|
983
|
+
await this.lane.run(() =>
|
|
984
|
+
this.cacheResolutionCore(
|
|
985
|
+
key,
|
|
986
|
+
prepared.epoch,
|
|
987
|
+
target,
|
|
988
|
+
remainingLeaseMs,
|
|
989
|
+
current.storeVersion.value
|
|
990
|
+
)
|
|
991
|
+
);
|
|
992
|
+
}
|
|
987
993
|
return target;
|
|
988
994
|
}
|
|
989
995
|
}
|
|
@@ -126,7 +126,8 @@ export class ZLinkSpotLocationClaims {
|
|
|
126
126
|
|
|
127
127
|
async beginInstanceClosing(
|
|
128
128
|
meshName: string,
|
|
129
|
-
spotId: RoutingId
|
|
129
|
+
spotId: RoutingId,
|
|
130
|
+
onCommitted: () => void
|
|
130
131
|
): Promise<ZLinkInstanceClosingAuthority | undefined> {
|
|
131
132
|
const canonical = ZLinkLocationKeyCodec.encodeSpotKey({ meshName, spotId });
|
|
132
133
|
const tracked = this.spots.get(canonical);
|
|
@@ -166,39 +167,9 @@ export class ZLinkSpotLocationClaims {
|
|
|
166
167
|
return undefined;
|
|
167
168
|
}
|
|
168
169
|
tracked.storeVersion = result.storeVersion.value;
|
|
169
|
-
|
|
170
|
-
let restored = false;
|
|
170
|
+
onCommitted();
|
|
171
171
|
return {
|
|
172
|
-
|
|
173
|
-
if (restored) return;
|
|
174
|
-
const restore = await store.compareExchangeAuthority(key, result.storeVersion, {
|
|
175
|
-
kind: 'put',
|
|
176
|
-
generationTransition: 'preserve',
|
|
177
|
-
payload: replaceServiceRelocationAuthorityApplicationPayload(
|
|
178
|
-
current.payload,
|
|
179
|
-
encodeServiceInstanceAuthorityPayload({
|
|
180
|
-
state: 'ready',
|
|
181
|
-
stableType: decoded.stableType,
|
|
182
|
-
spotId: decoded.spotId,
|
|
183
|
-
ownerId: decoded.ownerId,
|
|
184
|
-
ownerLeaseGeneration: decoded.ownerLeaseGeneration,
|
|
185
|
-
ownerMeshName: decoded.ownerMeshName,
|
|
186
|
-
ownerNodeRid: decoded.ownerNodeRid,
|
|
187
|
-
ownerNodeGeneration: decoded.ownerNodeGeneration
|
|
188
|
-
})
|
|
189
|
-
)
|
|
190
|
-
});
|
|
191
|
-
if (restore.kind !== 'stored') {
|
|
192
|
-
throw createInternalFrameworkException(
|
|
193
|
-
ZLinkFrameworkInternalErrorKind.SpotMoving,
|
|
194
|
-
`Instance Spot '${String(spotId)}' Ready authority could not be restored after idle eviction was declined.`,
|
|
195
|
-
true
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
restored = true;
|
|
199
|
-
tracked.storeVersion = restore.storeVersion.value;
|
|
200
|
-
this.invalidateSpotRoute?.(tracked.spotId);
|
|
201
|
-
}
|
|
172
|
+
release: async () => undefined
|
|
202
173
|
};
|
|
203
174
|
}
|
|
204
175
|
|
|
@@ -382,7 +353,7 @@ export interface ZLinkTrackedInstanceAuthority {
|
|
|
382
353
|
}
|
|
383
354
|
|
|
384
355
|
export interface ZLinkInstanceClosingAuthority {
|
|
385
|
-
|
|
356
|
+
release(): Promise<void>;
|
|
386
357
|
}
|
|
387
358
|
|
|
388
359
|
interface TrackedLegacySpot {
|