@zlink-systems/framework 0.31.0 → 0.32.1
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/Actors/ZLinkActor.d.ts +2 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.d.ts +6 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.js +2 -0
- package/dist/contracts/Actors/index.d.ts +1 -0
- package/dist/contracts/Actors/index.js +1 -0
- package/dist/contracts/Common/payload-slab.d.ts +4 -0
- package/dist/contracts/Common/payload-slab.js +30 -0
- package/dist/contracts/Handlers/Contexts.d.ts +1 -0
- package/dist/internal.d.ts +9 -0
- package/dist/internal.js +23 -1
- package/dist/runtime/actors/actor-client.d.ts +1 -1
- package/dist/runtime/actors/actor-client.js +32 -23
- package/dist/runtime/actors/actor-context.js +1 -1
- package/dist/runtime/actors/actor-creation.js +1 -1
- package/dist/runtime/actors/actor-mailbox.d.ts +1 -1
- package/dist/runtime/actors/actor-runtime-state.d.ts +3 -2
- package/dist/runtime/actors/actor-runtime-state.js +24 -8
- package/dist/runtime/actors/index.d.ts +3 -3
- package/dist/runtime/actors/index.js +19 -32
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +4 -2
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -1
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +1 -0
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +3 -0
- package/dist/runtime/backend/contracts/index.d.ts +2 -0
- package/dist/runtime/backend/mesh-completion-table.d.ts +1 -0
- package/dist/runtime/backend/mesh-completion-table.js +1 -0
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +5 -1
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +7 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +17 -11
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +2 -2
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +15 -8
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +7 -6
- package/dist/runtime/channels/channel-dispatch-pipeline.js +1 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +7 -3
- package/dist/runtime/channels/channel-dispatchers.js +27 -19
- package/dist/runtime/channels/channel-envelope.js +543 -23
- package/dist/runtime/channels/channel-receive-loops.d.ts +9 -6
- package/dist/runtime/channels/channel-receive-loops.js +59 -18
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +22 -3
- package/dist/runtime/channels/channel-socket-registry.d.ts +22 -4
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +1 -1
- package/dist/runtime/diagnostics/runtime-metrics.js +2 -1
- package/dist/runtime/execution/serial-execution-queue.d.ts +26 -13
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +27 -11
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +29 -25
- package/dist/runtime/foundation/service-liveness-registry.d.ts +1 -1
- package/dist/runtime/foundation/service-mailbox.d.ts +3 -1
- package/dist/runtime/foundation/service-mailbox.js +4 -1
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +3 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +28 -12
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +51 -19
- package/dist/runtime/foundation/service-stateful-runtime.js +54 -5
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -0
- package/dist/runtime/foundation/service-stateful-wire-codec.js +15 -0
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +12 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +17 -7
- package/dist/runtime/host/actor-placement-coordinator.d.ts +1 -1
- package/dist/runtime/host/actor-transfer-runtime.d.ts +3 -3
- package/dist/runtime/host/application-job-queue.d.ts +1 -1
- package/dist/runtime/host/index.d.ts +89 -36
- package/dist/runtime/host/index.js +101 -7
- package/dist/runtime/host/location-runtime-owner.d.ts +2 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +181 -44
- package/dist/runtime/host/service-relocation-host-runtime.js +47 -13
- package/dist/runtime/host/spot-address-transport.js +50 -42
- package/dist/runtime/locations/actor-location-claims.js +9 -10
- package/dist/runtime/locations/auto-connect-loop.d.ts +0 -1
- package/dist/runtime/locations/auto-connect-loop.js +25 -19
- package/dist/runtime/locations/auto-connect-planner.js +2 -5
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +1 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +35 -23
- package/dist/runtime/locations/in-memory-location-store.d.ts +0 -2
- package/dist/runtime/locations/in-memory-location-store.js +1 -38
- package/dist/runtime/locations/location-store-repository.d.ts +0 -1
- package/dist/runtime/locations/location-store-repository.js +13 -115
- package/dist/runtime/locations/runtime.d.ts +3 -3
- package/dist/runtime/locations/runtime.js +12 -16
- package/dist/runtime/messaging/creation-payload-codec.js +2 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +4 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +17 -7
- package/dist/runtime/spots/index.d.ts +20 -5
- package/dist/runtime/spots/index.js +14 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +3 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +13 -7
- package/dist/runtime/spots/spot-actor-packet-drain.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -5
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -1
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +8 -6
- package/dist/runtime/spots/spot-node-runtime-manager.js +2 -0
- package/dist/runtime/spots/spot-route-packet-dispatch.js +7 -4
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +3 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +2 -1
- package/dist/runtime/spots/spot-subscription-dispatch.js +3 -1
- package/dist/runtime/spots/spot-timer.d.ts +1 -1
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +9 -3
- package/dist/runtime/streams/actor-session-binding-registry.js +17 -0
- package/dist/runtime/streams/index.d.ts +3 -3
- package/dist/runtime/streams/index.js +22 -2
- package/dist/runtime/streams/managed-stream.js +2 -1
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +3 -9
- package/dist/runtime/streams/session-context.d.ts +2 -2
- package/dist/runtime/streams/session-context.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -0
- package/dist/runtime/streams/stream-session-runtime.js +37 -12
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActor.ts +6 -0
- package/src/contracts/Actors/ZLinkSessionBindingIdentity.ts +7 -0
- package/src/contracts/Actors/index.ts +1 -0
- package/src/contracts/Common/payload-slab.ts +29 -0
- package/src/contracts/Handlers/Contexts.ts +1 -0
- package/src/internal.ts +17 -0
- package/src/runtime/actors/actor-client.ts +48 -23
- package/src/runtime/actors/actor-context.ts +1 -1
- package/src/runtime/actors/actor-creation.ts +1 -1
- package/src/runtime/actors/actor-mailbox.ts +1 -1
- package/src/runtime/actors/actor-runtime-state.ts +28 -10
- package/src/runtime/actors/index.ts +30 -35
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -3
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +4 -0
- package/src/runtime/backend/contracts/index.ts +2 -0
- package/src/runtime/backend/mesh-completion-table.ts +2 -0
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +5 -1
- package/src/runtime/backend/node/node-raw-binding-port.ts +20 -7
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +18 -10
- package/src/runtime/channels/channel-dispatch-pipeline.ts +6 -5
- package/src/runtime/channels/channel-dispatchers.ts +39 -19
- package/src/runtime/channels/channel-envelope.ts +547 -20
- package/src/runtime/channels/channel-receive-loops.ts +93 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +2 -2
- package/src/runtime/channels/channel-socket-registry.ts +3 -3
- package/src/runtime/diagnostics/runtime-metrics.ts +3 -1
- package/src/runtime/execution/serial-execution-queue.ts +13 -13
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +40 -39
- package/src/runtime/foundation/service-liveness-registry.ts +1 -1
- package/src/runtime/foundation/service-mailbox.ts +6 -1
- package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
- package/src/runtime/foundation/service-stateful-registry.ts +39 -14
- package/src/runtime/foundation/service-stateful-runtime.ts +87 -21
- package/src/runtime/foundation/service-stateful-wire-codec.ts +18 -0
- package/src/runtime/foundation/service-wire-constants.generated.ts +10 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -7
- package/src/runtime/host/actor-placement-coordinator.ts +1 -1
- package/src/runtime/host/actor-transfer-runtime.ts +3 -3
- package/src/runtime/host/application-job-queue.ts +1 -1
- package/src/runtime/host/index.ts +183 -44
- package/src/runtime/host/location-runtime-owner.ts +2 -2
- package/src/runtime/host/service-relocation-host-runtime.ts +101 -65
- package/src/runtime/host/spot-address-transport.ts +67 -61
- package/src/runtime/locations/actor-location-claims.ts +14 -14
- package/src/runtime/locations/auto-connect-loop.ts +24 -16
- package/src/runtime/locations/auto-connect-planner.ts +2 -5
- package/src/runtime/locations/auto-connect-reconciler.ts +37 -24
- package/src/runtime/locations/in-memory-location-store.ts +1 -74
- package/src/runtime/locations/location-store-repository.ts +32 -153
- package/src/runtime/locations/runtime.ts +16 -28
- package/src/runtime/messaging/creation-payload-codec.ts +3 -3
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/index.ts +28 -4
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +1 -1
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +16 -6
- package/src/runtime/spots/spot-actor-packet-drain.ts +21 -6
- package/src/runtime/spots/spot-entry-activation.ts +1 -1
- package/src/runtime/spots/spot-node-runtime-manager.ts +8 -6
- package/src/runtime/spots/spot-route-packet-dispatch.ts +8 -4
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +3 -1
- package/src/runtime/spots/spot-serial-executor.ts +1 -1
- package/src/runtime/spots/spot-subscription-dispatch.ts +3 -1
- package/src/runtime/spots/spot-timer.ts +1 -1
- package/src/runtime/streams/actor-session-binding-registry.ts +30 -3
- package/src/runtime/streams/index.ts +30 -4
- package/src/runtime/streams/managed-stream.ts +2 -1
- package/src/runtime/streams/session-calls.ts +9 -14
- package/src/runtime/streams/session-context.ts +6 -11
- package/src/runtime/streams/stream-session-runtime.ts +49 -20
|
@@ -4,7 +4,7 @@ import { inspectRuntime } from '../internal-observation';
|
|
|
4
4
|
import { encodeActorReply } from '../actors/actor-reply';
|
|
5
5
|
import { ZLinkStreamMessageKind } from '../streams/protocol';
|
|
6
6
|
import {
|
|
7
|
-
|
|
7
|
+
decodeApplicationPayload,
|
|
8
8
|
encodeMultipartApplicationPayload
|
|
9
9
|
} from '../foundation/service-wire-m6a-codec';
|
|
10
10
|
import {
|
|
@@ -80,6 +80,7 @@ import {
|
|
|
80
80
|
flowIfEnabled,
|
|
81
81
|
type ZLinkMessageFlowTracer
|
|
82
82
|
} from '../diagnostics/message-flow';
|
|
83
|
+
import { currentFlowContext } from '../diagnostics/flow-context';
|
|
83
84
|
import { dispatchErrorDetails } from '../diagnostics/dispatch-error-details';
|
|
84
85
|
import { isStructuralGuardEnabled, trackDiagnosticCompletion } from '../execution/state-lane';
|
|
85
86
|
import {
|
|
@@ -276,7 +277,7 @@ interface ZLinkHostRelocationOptions {
|
|
|
276
277
|
clear?(): void | Promise<void>;
|
|
277
278
|
};
|
|
278
279
|
readonly trackInstanceSpot?: (input: ZLinkTrackedInstanceAuthority) => void;
|
|
279
|
-
readonly
|
|
280
|
+
readonly observeActorAuthorityVersion?: (actorId: string, storeVersion: string) => void;
|
|
280
281
|
readonly reconcileStatefulAuthorityRoutes?: (signal?: AbortSignal) => Promise<void>;
|
|
281
282
|
readonly runtimeEventPublisher?: ZLinkRuntimeEventPublisher;
|
|
282
283
|
readonly metrics?: ZLinkRuntimeMetrics;
|
|
@@ -437,13 +438,13 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
437
438
|
});
|
|
438
439
|
}
|
|
439
440
|
|
|
440
|
-
|
|
441
|
+
readonly targetStages = new Map<string, LocalStage>();
|
|
441
442
|
private readonly terminalTargets = new BoundedReplayMap<string, string>(
|
|
442
443
|
RELOCATION_TARGET_TOMBSTONE_LIMIT
|
|
443
444
|
);
|
|
444
|
-
|
|
445
|
+
readonly targetPrepareOperations = new Map<string, TargetPrepareOperation>();
|
|
445
446
|
private readonly pendingReplyRelays = new Map<string, PendingRelocationReplyRelay>();
|
|
446
|
-
|
|
447
|
+
readonly pendingSessionRelocations = new Map<string, PendingSessionRelocation>();
|
|
447
448
|
private readonly terminalSessionRelocations = new BoundedReplayMap<
|
|
448
449
|
string,
|
|
449
450
|
TerminalSessionRelocationControl
|
|
@@ -457,7 +458,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
457
458
|
SERVICE_CONTROL_TERMINAL_CAPACITY
|
|
458
459
|
);
|
|
459
460
|
private readonly sourceRelocationIds = new Set<string>();
|
|
460
|
-
|
|
461
|
+
readonly targetAssemblies = new Map<string, TargetPayloadAssembly>();
|
|
461
462
|
/**
|
|
462
463
|
* Terminal restore failures (assembly/checksum/factory/restore error): the
|
|
463
464
|
* target already sent relocationFailed (command 53) once. An exact-identity
|
|
@@ -484,7 +485,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
484
485
|
private readonly terminalActorJoinSourceLeaves = new BoundedReplayMap<string, string>(
|
|
485
486
|
SERVICE_CONTROL_TERMINAL_CAPACITY
|
|
486
487
|
);
|
|
487
|
-
|
|
488
|
+
readonly codec = new ServiceRelocationAuthorityPayloadCodec();
|
|
488
489
|
/**
|
|
489
490
|
* Set once dispose() starts tearing assemblies down. A payload() rejection
|
|
490
491
|
* observed after this point is the shutdown itself, not a chunk-assembly or
|
|
@@ -493,7 +494,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
493
494
|
private disposed = false;
|
|
494
495
|
private readonly targetPreparationStop = new AbortController();
|
|
495
496
|
|
|
496
|
-
constructor(
|
|
497
|
+
constructor(readonly options: ZLinkHostRelocationOptions) {}
|
|
497
498
|
|
|
498
499
|
async relocateActorJoin(
|
|
499
500
|
input: Parameters<ZLinkActorJoinRelocation['relocateActorJoin']>[0]
|
|
@@ -1129,7 +1130,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
1129
1130
|
}
|
|
1130
1131
|
|
|
1131
1132
|
/** Sends the Ready reply once the async restore finished; failures replay on resend. */
|
|
1132
|
-
|
|
1133
|
+
async deliverTargetReady(
|
|
1133
1134
|
meshName: string,
|
|
1134
1135
|
operationKey: string,
|
|
1135
1136
|
request: ServiceMaintenanceRelocationPrepare,
|
|
@@ -1681,7 +1682,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
1681
1682
|
}
|
|
1682
1683
|
}
|
|
1683
1684
|
|
|
1684
|
-
|
|
1685
|
+
async relocateSpotAggregate(
|
|
1685
1686
|
meshName: string,
|
|
1686
1687
|
activation: ZLinkSpotActivation,
|
|
1687
1688
|
kind: 'user_spot' | 'instance_spot',
|
|
@@ -1962,7 +1963,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
1962
1963
|
const relocationMetric =
|
|
1963
1964
|
spotRegistration.relocation.kind === 'disabled'
|
|
1964
1965
|
? undefined
|
|
1965
|
-
: this.
|
|
1966
|
+
: this.startSourceRelocationMetric(meshName, kind, spotRegistration.relocation.kind);
|
|
1966
1967
|
try {
|
|
1967
1968
|
const waitForRelocationBoundary = (
|
|
1968
1969
|
activation as unknown as {
|
|
@@ -2041,7 +2042,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2041
2042
|
}
|
|
2042
2043
|
}
|
|
2043
2044
|
|
|
2044
|
-
|
|
2045
|
+
async relocateStandaloneActor(
|
|
2045
2046
|
meshName: string,
|
|
2046
2047
|
state: ZLinkActorRuntimeState,
|
|
2047
2048
|
target: ZLinkMeshNodeDescriptor | undefined,
|
|
@@ -2115,7 +2116,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2115
2116
|
const relocationMetric =
|
|
2116
2117
|
actorPolicy === 'disabled'
|
|
2117
2118
|
? undefined
|
|
2118
|
-
: this.
|
|
2119
|
+
: this.startSourceRelocationMetric(meshName, 'actor', actorPolicy, state.actorId);
|
|
2119
2120
|
try {
|
|
2120
2121
|
if (isRelocationDebugEnabled()) {
|
|
2121
2122
|
relocationDebug('standalone_actor.wait_budget', {
|
|
@@ -2158,7 +2159,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2158
2159
|
}
|
|
2159
2160
|
}
|
|
2160
2161
|
|
|
2161
|
-
|
|
2162
|
+
async relocatePerActorSpotShell(
|
|
2162
2163
|
meshName: string,
|
|
2163
2164
|
activation: ZLinkSpotActivation,
|
|
2164
2165
|
target: ZLinkMeshNodeDescriptor | undefined,
|
|
@@ -2277,11 +2278,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2277
2278
|
const relocationMetric =
|
|
2278
2279
|
spotRegistration.relocation.kind === 'disabled'
|
|
2279
2280
|
? undefined
|
|
2280
|
-
: this.
|
|
2281
|
-
meshName,
|
|
2282
|
-
'user_spot',
|
|
2283
|
-
spotRegistration.relocation.kind
|
|
2284
|
-
);
|
|
2281
|
+
: this.startSourceRelocationMetric(meshName, 'user_spot', spotRegistration.relocation.kind);
|
|
2285
2282
|
try {
|
|
2286
2283
|
await this.waitForRelocationBudgetHeadroom(String(target.rid), signal);
|
|
2287
2284
|
const captured = await new ServiceRelocationObjectCaptureOwner().captureUserSpotAggregate(
|
|
@@ -2473,7 +2470,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2473
2470
|
this.sourceRelocationIds.add(id);
|
|
2474
2471
|
}
|
|
2475
2472
|
|
|
2476
|
-
|
|
2473
|
+
async runCoordinator(
|
|
2477
2474
|
meshName: string,
|
|
2478
2475
|
target: ZLinkMeshNodeDescriptor,
|
|
2479
2476
|
primary: ZLinkAuthoritySnapshot,
|
|
@@ -2802,6 +2799,50 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2802
2799
|
);
|
|
2803
2800
|
}
|
|
2804
2801
|
|
|
2802
|
+
startSourceRelocationMetric(
|
|
2803
|
+
meshName: string,
|
|
2804
|
+
objectKind: 'actor' | 'user_spot' | 'instance_spot',
|
|
2805
|
+
policy: 'recreate' | 'snapshot',
|
|
2806
|
+
actorId?: string
|
|
2807
|
+
): ZLinkRelocationMetricOperation | undefined {
|
|
2808
|
+
const flow = objectKind === 'actor' ? this.options.messageFlow?.() : undefined;
|
|
2809
|
+
const flowContext = flow?.flowCreationEnabled() === true ? currentFlowContext() : undefined;
|
|
2810
|
+
const traceTerminal = (outcome: string): void => {
|
|
2811
|
+
if (flow === undefined || flowContext === undefined) return;
|
|
2812
|
+
const result =
|
|
2813
|
+
outcome === 'completed' ? 'succeeded' : outcome === 'shutdown' ? 'shutdown' : 'failed';
|
|
2814
|
+
flowIfEnabled(flow, ZLinkMessageFlowOutcome.Completed, result, flowContext.flowId)?.trace({
|
|
2815
|
+
outcome: ZLinkMessageFlowOutcome.Completed,
|
|
2816
|
+
result,
|
|
2817
|
+
surface: ZLinkDispatchErrorSurface.ActorRelocation,
|
|
2818
|
+
messageKind: ZLinkDispatchMessageKind.Control,
|
|
2819
|
+
meshName,
|
|
2820
|
+
actorId,
|
|
2821
|
+
flowId: flowContext.flowId,
|
|
2822
|
+
flowOrigin: flowContext.flowOrigin,
|
|
2823
|
+
errorMessage: result === 'failed' ? `source_relocation_${outcome}` : undefined
|
|
2824
|
+
});
|
|
2825
|
+
};
|
|
2826
|
+
const metric = this.options.metrics?.startRelocation(
|
|
2827
|
+
meshName,
|
|
2828
|
+
objectKind,
|
|
2829
|
+
policy,
|
|
2830
|
+
traceTerminal
|
|
2831
|
+
);
|
|
2832
|
+
if (metric !== undefined) return metric;
|
|
2833
|
+
if (flow === undefined || flowContext === undefined) return undefined;
|
|
2834
|
+
|
|
2835
|
+
let completed = false;
|
|
2836
|
+
return {
|
|
2837
|
+
recordBytes: (): void => {},
|
|
2838
|
+
complete: (outcome: string): void => {
|
|
2839
|
+
if (completed) return;
|
|
2840
|
+
completed = true;
|
|
2841
|
+
traceTerminal(outcome);
|
|
2842
|
+
}
|
|
2843
|
+
};
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2805
2846
|
/** Streams the payload chunks of one stage under the effective in-flight budgets. */
|
|
2806
2847
|
private async sendRelocationStateChunks(
|
|
2807
2848
|
meshName: string,
|
|
@@ -2864,10 +2905,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2864
2905
|
}
|
|
2865
2906
|
|
|
2866
2907
|
/** Pre-seal admission wait — a full budget delays the next unit before seal. */
|
|
2867
|
-
|
|
2868
|
-
targetRid: string,
|
|
2869
|
-
signal?: AbortSignal
|
|
2870
|
-
): Promise<void> {
|
|
2908
|
+
async waitForRelocationBudgetHeadroom(targetRid: string, signal?: AbortSignal): Promise<void> {
|
|
2871
2909
|
await this.requireNodePayloadBudget().waitForHeadroom(signal);
|
|
2872
2910
|
await this.requirePeerPayloadBudget(targetRid).waitForHeadroom(signal);
|
|
2873
2911
|
}
|
|
@@ -2954,7 +2992,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2954
2992
|
}
|
|
2955
2993
|
|
|
2956
2994
|
/** Relocation flow §4.4: replay the whole batch on a different ready route. */
|
|
2957
|
-
|
|
2995
|
+
async resendSourceCutover(window: SourceCutoverWindow): Promise<void> {
|
|
2958
2996
|
const frames = window.frames;
|
|
2959
2997
|
if (frames === undefined) return;
|
|
2960
2998
|
const route = this.requireMeshNode(window.meshName).observePeerRoute?.(window.targetNodeRid);
|
|
@@ -2986,7 +3024,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
2986
3024
|
* A committed later owner has no Follow snapshot (Location runtime §10). An uncertain
|
|
2987
3025
|
* Store or lease result keeps the work retained and repeats the same decision.
|
|
2988
3026
|
*/
|
|
2989
|
-
|
|
3027
|
+
async settleSourceAuthority(
|
|
2990
3028
|
envelope: ServiceRelocationEnvelope,
|
|
2991
3029
|
primary: ZLinkAuthoritySnapshot,
|
|
2992
3030
|
target: ServiceWireRelocationTarget,
|
|
@@ -3098,7 +3136,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3098
3136
|
return this.sourceCutoverWindows.size === 0;
|
|
3099
3137
|
}
|
|
3100
3138
|
|
|
3101
|
-
|
|
3139
|
+
async releaseParticipantAuthorities(
|
|
3102
3140
|
envelope: ServiceRelocationEnvelope,
|
|
3103
3141
|
primaryKey: string,
|
|
3104
3142
|
signal?: AbortSignal
|
|
@@ -3122,11 +3160,17 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3122
3160
|
if (result.kind !== 'stored') {
|
|
3123
3161
|
throw new Error(`Participant '${participant.key}' recovery pointer release failed.`);
|
|
3124
3162
|
}
|
|
3163
|
+
if (participant.objectKind === 'actor') {
|
|
3164
|
+
this.options.observeActorAuthorityVersion?.(
|
|
3165
|
+
decodeAuthorityKey(key).globalId,
|
|
3166
|
+
result.storeVersion.value
|
|
3167
|
+
);
|
|
3168
|
+
}
|
|
3125
3169
|
}
|
|
3126
3170
|
}
|
|
3127
3171
|
|
|
3128
3172
|
/** Restores the hidden object and its saved-work prefix before Ready. */
|
|
3129
|
-
|
|
3173
|
+
async handlePrepareControl(
|
|
3130
3174
|
meshName: string,
|
|
3131
3175
|
stagingId: string,
|
|
3132
3176
|
request: ServiceMaintenanceRelocationPrepare,
|
|
@@ -3384,7 +3428,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3384
3428
|
* whole (the retransmission always resends the entire batch, so the exact
|
|
3385
3429
|
* span is the staged suffix of `boundaryRecordCount` records).
|
|
3386
3430
|
*/
|
|
3387
|
-
|
|
3431
|
+
reconcileBoundaryRelay(
|
|
3388
3432
|
stage: LocalStage,
|
|
3389
3433
|
request: ServiceMaintenanceRelocationCutover,
|
|
3390
3434
|
stagingId: string
|
|
@@ -3415,7 +3459,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3415
3459
|
);
|
|
3416
3460
|
}
|
|
3417
3461
|
|
|
3418
|
-
|
|
3462
|
+
beginTargetFinalize(
|
|
3419
3463
|
meshName: string,
|
|
3420
3464
|
stagingId: string,
|
|
3421
3465
|
stage: LocalStage,
|
|
@@ -3432,7 +3476,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3432
3476
|
return finalize;
|
|
3433
3477
|
}
|
|
3434
3478
|
|
|
3435
|
-
|
|
3479
|
+
async finalizeTargetStage(
|
|
3436
3480
|
meshName: string,
|
|
3437
3481
|
stagingId: string,
|
|
3438
3482
|
stage: LocalStage,
|
|
@@ -3484,15 +3528,6 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3484
3528
|
);
|
|
3485
3529
|
}
|
|
3486
3530
|
await stage.owner.normalize(stage.staging, authority, signal);
|
|
3487
|
-
// The target may have visited this Actor before and still retain that
|
|
3488
|
-
// tenure in its private Actor-client resolver. The target-only CAS is
|
|
3489
|
-
// now authoritative, so expire the old projection before OnJoinedActor
|
|
3490
|
-
// can issue an Actor request and deadlock behind source leave.
|
|
3491
|
-
for (const hidden of stage.staging.hidden.values()) {
|
|
3492
|
-
if (hidden.actor !== undefined) {
|
|
3493
|
-
this.options.invalidateActorRoute?.(hidden.actor.context.actorId);
|
|
3494
|
-
}
|
|
3495
|
-
}
|
|
3496
3531
|
await this.finalizeActorJoinProfiles(meshName, stage, signal);
|
|
3497
3532
|
await this.publishSessionRoutes(stage.staging);
|
|
3498
3533
|
stage.phase = 'open';
|
|
@@ -3572,7 +3607,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3572
3607
|
);
|
|
3573
3608
|
}
|
|
3574
3609
|
|
|
3575
|
-
|
|
3610
|
+
async finalizeActorJoinProfiles(
|
|
3576
3611
|
meshName: string,
|
|
3577
3612
|
stage: LocalStage,
|
|
3578
3613
|
signal?: AbortSignal
|
|
@@ -3605,7 +3640,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3605
3640
|
}
|
|
3606
3641
|
}
|
|
3607
3642
|
|
|
3608
|
-
|
|
3643
|
+
async submitActorJoinSourceLeave(
|
|
3609
3644
|
meshName: string,
|
|
3610
3645
|
sourceNodeRid: RoutingId,
|
|
3611
3646
|
relocationId: string,
|
|
@@ -3631,7 +3666,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3631
3666
|
}
|
|
3632
3667
|
}
|
|
3633
3668
|
|
|
3634
|
-
|
|
3669
|
+
acceptActorJoinSourceLeave(input: {
|
|
3635
3670
|
readonly transferId: string;
|
|
3636
3671
|
readonly actorId: string;
|
|
3637
3672
|
readonly succeeded: boolean;
|
|
@@ -3671,7 +3706,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3671
3706
|
);
|
|
3672
3707
|
}
|
|
3673
3708
|
|
|
3674
|
-
|
|
3709
|
+
async submitControlFrame(
|
|
3675
3710
|
meshName: string,
|
|
3676
3711
|
targetNodeRid: RoutingId,
|
|
3677
3712
|
frame: Buffer,
|
|
@@ -3685,7 +3720,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3685
3720
|
}
|
|
3686
3721
|
}
|
|
3687
3722
|
|
|
3688
|
-
|
|
3723
|
+
async clearTargetRelocationPublication(
|
|
3689
3724
|
stage: LocalStage,
|
|
3690
3725
|
primary: ZLinkAuthoritySnapshot,
|
|
3691
3726
|
signal?: AbortSignal
|
|
@@ -3714,6 +3749,12 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3714
3749
|
if (result.kind !== 'stored') {
|
|
3715
3750
|
throw new Error('Relocation target authority normalization CAS failed.');
|
|
3716
3751
|
}
|
|
3752
|
+
if (primary.allocation.objectKind === 'actor') {
|
|
3753
|
+
this.options.observeActorAuthorityVersion?.(
|
|
3754
|
+
decodeAuthorityKey(stage.staging.primaryAuthorityKey).globalId,
|
|
3755
|
+
result.storeVersion.value
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3717
3758
|
return { ...result, kind: 'snapshot' };
|
|
3718
3759
|
}
|
|
3719
3760
|
|
|
@@ -3793,7 +3834,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3793
3834
|
}
|
|
3794
3835
|
}
|
|
3795
3836
|
|
|
3796
|
-
|
|
3837
|
+
async sendReplyRelay(
|
|
3797
3838
|
meshName: string,
|
|
3798
3839
|
ackTargetNodeRid: RoutingId,
|
|
3799
3840
|
request: ServiceMaintenanceReplyRelay,
|
|
@@ -3911,7 +3952,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3911
3952
|
}
|
|
3912
3953
|
}
|
|
3913
3954
|
|
|
3914
|
-
|
|
3955
|
+
targetReplyRelayCoordinator(
|
|
3915
3956
|
meshName: string,
|
|
3916
3957
|
stage: LocalStage,
|
|
3917
3958
|
authority: ZLinkAuthoritySnapshot
|
|
@@ -3937,7 +3978,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3937
3978
|
};
|
|
3938
3979
|
}
|
|
3939
3980
|
|
|
3940
|
-
|
|
3981
|
+
async relayTerminalReply(
|
|
3941
3982
|
meshName: string,
|
|
3942
3983
|
stage: LocalStage,
|
|
3943
3984
|
coordinator: ServiceWireRelocationCoordinatorFence,
|
|
@@ -3987,9 +4028,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
3987
4028
|
);
|
|
3988
4029
|
}
|
|
3989
4030
|
|
|
3990
|
-
|
|
3991
|
-
staging: ServiceObjectRelocationStaging<LocalHidden>
|
|
3992
|
-
): Promise<void> {
|
|
4031
|
+
async publishSessionRoutes(staging: ServiceObjectRelocationStaging<LocalHidden>): Promise<void> {
|
|
3993
4032
|
for (const [key, hidden] of staging.hidden) {
|
|
3994
4033
|
if (hidden.actor === undefined) continue;
|
|
3995
4034
|
// The Session seal travels with the relocation envelope, not the Actor.
|
|
@@ -4001,7 +4040,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4001
4040
|
}
|
|
4002
4041
|
}
|
|
4003
4042
|
|
|
4004
|
-
|
|
4043
|
+
async sendControl(
|
|
4005
4044
|
meshName: string,
|
|
4006
4045
|
targetNodeRid: RoutingId,
|
|
4007
4046
|
request: ZLinkServiceRelocationControlRequest,
|
|
@@ -4132,7 +4171,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4132
4171
|
return authorities;
|
|
4133
4172
|
}
|
|
4134
4173
|
|
|
4135
|
-
|
|
4174
|
+
async reserveTargetForPrepare(
|
|
4136
4175
|
meshName: string,
|
|
4137
4176
|
prepare: ServiceMaintenanceRelocationPrepare,
|
|
4138
4177
|
envelope: ServiceRelocationEnvelope,
|
|
@@ -4206,7 +4245,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4206
4245
|
};
|
|
4207
4246
|
}
|
|
4208
4247
|
|
|
4209
|
-
|
|
4248
|
+
authorityPayloadForPublication(
|
|
4210
4249
|
payload: Uint8Array,
|
|
4211
4250
|
publication: ServiceRelocationPublication,
|
|
4212
4251
|
target?: {
|
|
@@ -4337,7 +4376,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4337
4376
|
}
|
|
4338
4377
|
}
|
|
4339
4378
|
|
|
4340
|
-
|
|
4379
|
+
async commitTargetReservation(
|
|
4341
4380
|
stage: LocalStage,
|
|
4342
4381
|
reservation: TargetRelocationReservation,
|
|
4343
4382
|
signal?: AbortSignal
|
|
@@ -4412,7 +4451,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4412
4451
|
}
|
|
4413
4452
|
}
|
|
4414
4453
|
|
|
4415
|
-
|
|
4454
|
+
async readAggregateForCommitRetry(
|
|
4416
4455
|
prepared: ServicePreparedRelocationAggregate,
|
|
4417
4456
|
signal?: AbortSignal
|
|
4418
4457
|
): Promise<
|
|
@@ -4460,7 +4499,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4460
4499
|
return source === prepared.plan.participants.length ? { kind: 'source' } : { kind: 'stale' };
|
|
4461
4500
|
}
|
|
4462
4501
|
|
|
4463
|
-
|
|
4502
|
+
async materializeTargetEnvelope(
|
|
4464
4503
|
meshName: string,
|
|
4465
4504
|
envelope: ServiceRelocationEnvelope,
|
|
4466
4505
|
signal?: AbortSignal
|
|
@@ -4478,7 +4517,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4478
4517
|
}
|
|
4479
4518
|
|
|
4480
4519
|
/** Maps schema ordinals to the authoritative Location Store inventory. */
|
|
4481
|
-
|
|
4520
|
+
async resolveTargetParticipantInventory(
|
|
4482
4521
|
meshName: string,
|
|
4483
4522
|
request: ServiceMaintenanceRelocationPrepare,
|
|
4484
4523
|
envelope: ServiceRelocationEnvelope,
|
|
@@ -4635,7 +4674,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4635
4674
|
return value;
|
|
4636
4675
|
}
|
|
4637
4676
|
|
|
4638
|
-
|
|
4677
|
+
async captureApplication<T>(
|
|
4639
4678
|
policy: { readonly kind: 'disabled' | 'recreate' | 'snapshot'; readonly adapterType?: Type },
|
|
4640
4679
|
value: T,
|
|
4641
4680
|
signal?: AbortSignal
|
|
@@ -4776,11 +4815,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
|
|
|
4776
4815
|
return value;
|
|
4777
4816
|
}
|
|
4778
4817
|
|
|
4779
|
-
|
|
4780
|
-
meshName: string,
|
|
4781
|
-
spotId: RoutingId,
|
|
4782
|
-
seal: () => T
|
|
4783
|
-
): T | Promise<T> {
|
|
4818
|
+
afterSpotCloseDecision<T>(meshName: string, spotId: RoutingId, seal: () => T): T | Promise<T> {
|
|
4784
4819
|
const manager = this.requireSpotManager();
|
|
4785
4820
|
const sealAfterDecision = (): T => {
|
|
4786
4821
|
if (manager.isSpotClosing(meshName, spotId)) {
|
|
@@ -5129,6 +5164,7 @@ class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden>
|
|
|
5129
5164
|
value: hidden.authorityKey
|
|
5130
5165
|
} as ZLinkAuthorityKey);
|
|
5131
5166
|
const actorId = hidden.actor.context.actorId;
|
|
5167
|
+
this.options.observeActorAuthorityVersion?.(actorId, current.storeVersion.value);
|
|
5132
5168
|
const node = this.options.meshNode(this.meshName);
|
|
5133
5169
|
const restore = node?.restoreActorAuthority;
|
|
5134
5170
|
if (node === undefined || restore === undefined) {
|
|
@@ -5836,7 +5872,7 @@ function maintenanceReplyRelay(
|
|
|
5836
5872
|
const direct = packet.messageFollowOrigin?.requestSource !== undefined;
|
|
5837
5873
|
const application =
|
|
5838
5874
|
direct && completion.result.ok
|
|
5839
|
-
?
|
|
5875
|
+
? decodeApplicationPayload(
|
|
5840
5876
|
encodeMultipartApplicationPayload(
|
|
5841
5877
|
encodeActorReply(
|
|
5842
5878
|
Buffer.from(packet.header, 'base64'),
|
|
@@ -263,55 +263,53 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
263
263
|
return this.requests.request(timeoutMs, call.signal, async (requestOperation) => {
|
|
264
264
|
const deadline = createSpotAddressDeadline(requestOperation, call.signal);
|
|
265
265
|
try {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
|
|
274
|
-
if (resolution !== undefined && 'kind' in resolution)
|
|
275
|
-
call = this.reactivationCall(resolution, call);
|
|
276
|
-
deadline.requireRemaining();
|
|
277
|
-
if (existing === undefined) {
|
|
278
|
-
return await this.requestToMissingInstance(spotId, request, call, deadline, resolution);
|
|
279
|
-
}
|
|
280
|
-
this.validateExisting(existing, call);
|
|
281
|
-
try {
|
|
282
|
-
return await this.requestToExistingSpot(spotId, request, call, existing, deadline);
|
|
283
|
-
} catch (error) {
|
|
284
|
-
if (isSpotRouteRefreshError(error)) {
|
|
285
|
-
this.options.resolver()?.invalidate?.(spotId);
|
|
286
|
-
}
|
|
287
|
-
// Failover policy §4.4: SpotMoving is the owner's Ready owner-fence
|
|
288
|
-
// refusal, made before admission. With Instance intent, one authority
|
|
289
|
-
// read under the same deadline decides: Missing means Close released
|
|
290
|
-
// the incarnation, so the request activates a new one. Any other
|
|
291
|
-
// answer, and any message the owner admitted, keeps this terminal.
|
|
292
|
-
if (
|
|
293
|
-
call.instanceSpot &&
|
|
294
|
-
isOwnerFenceRefusal(error) &&
|
|
295
|
-
(await waitRequestReply(
|
|
296
|
-
this.resolveExisting(spotId, deadline.signal),
|
|
297
|
-
'Spot address resolve',
|
|
298
|
-
requestOperation,
|
|
299
|
-
() => deadline.close()
|
|
300
|
-
)) === undefined
|
|
301
|
-
) {
|
|
302
|
-
deadline.requireRemaining();
|
|
303
|
-
return await this.requestToMissingInstance(spotId, request, call, deadline);
|
|
304
|
-
}
|
|
305
|
-
this.reportInstanceRequestError(
|
|
306
|
-
spotId,
|
|
307
|
-
request,
|
|
308
|
-
error,
|
|
309
|
-
existing.routerChannelId,
|
|
310
|
-
existing.targetNodeRid,
|
|
311
|
-
existing.stableType,
|
|
312
|
-
addressedInstanceErrorReason(error)
|
|
266
|
+
for (;;) {
|
|
267
|
+
deadline.requireRemaining();
|
|
268
|
+
const resolution = await waitRequestReply(
|
|
269
|
+
this.resolveExisting(spotId, deadline.signal, call),
|
|
270
|
+
'Spot address resolve',
|
|
271
|
+
requestOperation,
|
|
272
|
+
() => deadline.close()
|
|
313
273
|
);
|
|
314
|
-
|
|
274
|
+
const existing =
|
|
275
|
+
resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
|
|
276
|
+
if (resolution !== undefined && 'kind' in resolution)
|
|
277
|
+
call = this.reactivationCall(resolution, call);
|
|
278
|
+
deadline.requireRemaining();
|
|
279
|
+
try {
|
|
280
|
+
if (existing === undefined) {
|
|
281
|
+
return await this.requestToMissingInstance(
|
|
282
|
+
spotId,
|
|
283
|
+
request,
|
|
284
|
+
call,
|
|
285
|
+
deadline,
|
|
286
|
+
resolution
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
this.validateExisting(existing, call);
|
|
290
|
+
return await this.requestToExistingSpot(spotId, request, call, existing, deadline);
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (
|
|
293
|
+
(existing !== undefined || isPreAdmissionStaleRoute(error)) &&
|
|
294
|
+
isSpotRouteRefreshError(error)
|
|
295
|
+
) {
|
|
296
|
+
this.options.resolver()?.invalidate?.(spotId);
|
|
297
|
+
}
|
|
298
|
+
// §9 keeps admission-before-stale-route handling in this logical request.
|
|
299
|
+
if (call.instanceSpot && isPreAdmissionStaleRoute(error)) continue;
|
|
300
|
+
if (existing !== undefined) {
|
|
301
|
+
this.reportInstanceRequestError(
|
|
302
|
+
spotId,
|
|
303
|
+
request,
|
|
304
|
+
error,
|
|
305
|
+
existing.routerChannelId,
|
|
306
|
+
existing.targetNodeRid,
|
|
307
|
+
existing.stableType,
|
|
308
|
+
addressedInstanceErrorReason(error)
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
315
313
|
}
|
|
316
314
|
} catch (error) {
|
|
317
315
|
if (
|
|
@@ -348,9 +346,13 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
348
346
|
existing.stableType,
|
|
349
347
|
existing.targetNodeRid
|
|
350
348
|
);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
349
|
+
// The address request owns the terminal entry. Observe the wire stage so
|
|
350
|
+
// a pre-admission refusal can reach the authority decision in §9.
|
|
351
|
+
const stage = new Promise<TReply>((resolve, reject) => {
|
|
352
|
+
const result = this.options.routed.requestToSpot<TReply>(
|
|
353
|
+
existing,
|
|
354
|
+
request,
|
|
355
|
+
{
|
|
354
356
|
instanceSpot: call.instanceSpot,
|
|
355
357
|
timeoutMs: deadline.requireRemaining(),
|
|
356
358
|
deadlineMs: deadline.deadlineMs,
|
|
@@ -358,11 +360,15 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
358
360
|
metadata: call.metadata,
|
|
359
361
|
onAdmitted: call.onAdmitted,
|
|
360
362
|
requestOperation: deadline.operation
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
operationCompleted: (_id, value) => resolve(value as TReply),
|
|
366
|
+
operationFailed: (_id, error) => reject(error)
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
if (result.operation === undefined) void mapZLinkRequestReply(result).then(resolve, reject);
|
|
370
|
+
});
|
|
371
|
+
const reply = await waitRequestReply(stage, 'Spot request', deadline.operation);
|
|
366
372
|
this.traceInstanceAddress(
|
|
367
373
|
ZLinkMessageFlowOutcome.ReplyReceived,
|
|
368
374
|
ZLinkDispatchMessageKind.Request,
|
|
@@ -778,19 +784,19 @@ function isSpotRouteRefreshError(error: unknown): error is ZLinkFrameworkExcepti
|
|
|
778
784
|
if (!(error instanceof ZLinkFrameworkException)) return false;
|
|
779
785
|
const kind = internalFrameworkErrorKind(error);
|
|
780
786
|
return (
|
|
787
|
+
isPreAdmissionStaleRoute(error) ||
|
|
781
788
|
kind === ZLinkFrameworkInternalErrorKind.SpotRouteNotFound ||
|
|
782
|
-
kind === ZLinkFrameworkInternalErrorKind.SpotGenerationStale ||
|
|
783
|
-
kind === ZLinkFrameworkInternalErrorKind.SpotMoving ||
|
|
784
789
|
kind === ZLinkFrameworkInternalErrorKind.RequestTargetNotFound ||
|
|
785
|
-
kind === ZLinkFrameworkInternalErrorKind.ActorLocationStale ||
|
|
786
790
|
kind === ZLinkFrameworkInternalErrorKind.RouteNotConnected
|
|
787
791
|
);
|
|
788
792
|
}
|
|
789
793
|
|
|
790
|
-
function
|
|
794
|
+
function isPreAdmissionStaleRoute(error: unknown): boolean {
|
|
791
795
|
return (
|
|
792
796
|
error instanceof ZLinkFrameworkException &&
|
|
793
|
-
internalFrameworkErrorKind(error) === ZLinkFrameworkInternalErrorKind.SpotMoving
|
|
797
|
+
(internalFrameworkErrorKind(error) === ZLinkFrameworkInternalErrorKind.SpotMoving ||
|
|
798
|
+
internalFrameworkErrorKind(error) === ZLinkFrameworkInternalErrorKind.ActorLocationStale ||
|
|
799
|
+
internalFrameworkErrorKind(error) === ZLinkFrameworkInternalErrorKind.SpotGenerationStale)
|
|
794
800
|
);
|
|
795
801
|
}
|
|
796
802
|
|