@zlink-systems/framework 0.29.0 → 0.30.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/Configuration/Builders.d.ts +1 -2
- package/dist/contracts/Configuration/Configs.d.ts +0 -5
- package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
- package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
- package/dist/contracts/Configuration/index.d.ts +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +3 -1
- package/dist/runtime/actors/actor-handoff.d.ts +3 -2
- package/dist/runtime/actors/actor-handoff.js +9 -4
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +1 -0
- package/dist/runtime/actors/index.d.ts +2 -0
- package/dist/runtime/actors/index.js +21 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +3 -1
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
- package/dist/runtime/application-jobs/contracts.d.ts +5 -1
- package/dist/runtime/backend/contracts/index.d.ts +10 -19
- package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
- package/dist/runtime/backend/mesh-completion-table.js +28 -18
- package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
- package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
- package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
- package/dist/runtime/channels/channel-receive-loops.js +3 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
- package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
- package/dist/runtime/channels/channel-socket-registry.js +59 -82
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow.js +3 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
- package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
- package/dist/runtime/foundation/service-liveness-registry.js +57 -44
- package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
- package/dist/runtime/foundation/service-mailbox.js +2 -1
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +60 -41
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
- package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
- package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
- package/dist/runtime/foundation/service-topology-registry.js +9 -4
- package/dist/runtime/handlers/handler-instance-scope.js +1 -1
- package/dist/runtime/host/actor-packet-relay.js +7 -7
- package/dist/runtime/host/actor-placement-coordinator.d.ts +2 -1
- package/dist/runtime/host/actor-placement-coordinator.js +2 -1
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -1
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -1
- package/dist/runtime/host/application-job-queue.d.ts +11 -4
- package/dist/runtime/host/application-job-queue.js +66 -10
- package/dist/runtime/host/entry-actor-runtime.js +1 -1
- package/dist/runtime/host/index.d.ts +1 -1
- package/dist/runtime/host/index.js +18 -13
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
- package/dist/runtime/host/instance-activation-authority.js +89 -25
- package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
- package/dist/runtime/host/spot-address-transport.d.ts +1 -0
- package/dist/runtime/host/spot-address-transport.js +25 -12
- package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
- package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -2
- package/dist/runtime/locations/in-memory-authority-store.d.ts +5 -2
- package/dist/runtime/locations/in-memory-authority-store.js +107 -14
- package/dist/runtime/locations/in-memory-location-store.d.ts +3 -3
- package/dist/runtime/locations/in-memory-location-store.js +31 -13
- package/dist/runtime/locations/internal-location-contracts.d.ts +8 -0
- package/dist/runtime/locations/location-store-repository.d.ts +4 -2
- package/dist/runtime/locations/location-store-repository.js +209 -33
- package/dist/runtime/locations/resolvers.d.ts +2 -1
- package/dist/runtime/locations/resolvers.js +10 -1
- package/dist/runtime/messaging/submission-result.d.ts +1 -1
- package/dist/runtime/messaging/submission-result.js +2 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
- package/dist/runtime/spots/index.d.ts +4 -3
- package/dist/runtime/spots/index.js +14 -14
- package/dist/runtime/spots/spot-activation.d.ts +2 -1
- package/dist/runtime/spots/spot-activation.js +4 -4
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
- package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
- package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
- package/dist/runtime/spots/spot-entry-activation.js +6 -1
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +3 -1
- package/dist/runtime/spots/spot-node-runtime-manager.js +10 -11
- package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
- package/dist/runtime/spots/spot-serial-executor.js +10 -1
- package/dist/runtime/streams/stream-session-runtime.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Configuration/Builders.ts +1 -2
- package/src/contracts/Configuration/Configs.ts +0 -6
- package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
- package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
- package/src/contracts/Configuration/index.ts +1 -6
- package/src/internal.ts +1 -0
- package/src/runtime/actors/actor-handoff.ts +13 -4
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
- package/src/runtime/actors/index.ts +77 -42
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
- package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
- package/src/runtime/application-jobs/contracts.ts +14 -1
- package/src/runtime/backend/contracts/index.ts +10 -18
- package/src/runtime/backend/mesh-completion-table.ts +36 -19
- package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
- package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
- package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
- package/src/runtime/backend/raw-binding-port.ts +12 -2
- package/src/runtime/channels/channel-receive-loops.ts +3 -3
- package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
- package/src/runtime/channels/channel-socket-registry.ts +84 -130
- package/src/runtime/diagnostics/message-flow.ts +1 -1
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
- package/src/runtime/foundation/service-liveness-registry.ts +68 -59
- package/src/runtime/foundation/service-mailbox.ts +7 -1
- package/src/runtime/foundation/service-stateful-runtime.ts +109 -77
- package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
- package/src/runtime/foundation/service-topology-registry.ts +13 -7
- package/src/runtime/handlers/handler-instance-scope.ts +2 -1
- package/src/runtime/host/actor-packet-relay.ts +7 -0
- package/src/runtime/host/actor-placement-coordinator.ts +8 -2
- package/src/runtime/host/actor-runtime-options-factory.ts +7 -0
- package/src/runtime/host/application-job-queue.ts +77 -10
- package/src/runtime/host/entry-actor-runtime.ts +1 -0
- package/src/runtime/host/index.ts +30 -7
- package/src/runtime/host/instance-activation-authority.ts +132 -27
- package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
- package/src/runtime/host/spot-address-transport.ts +45 -22
- package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
- package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
- package/src/runtime/locations/domain-store-contract.ts +6 -2
- package/src/runtime/locations/in-memory-authority-store.ts +153 -12
- package/src/runtime/locations/in-memory-location-store.ts +39 -13
- package/src/runtime/locations/internal-location-contracts.ts +10 -0
- package/src/runtime/locations/location-store-repository.ts +295 -36
- package/src/runtime/locations/resolvers.ts +25 -2
- package/src/runtime/messaging/submission-result.ts +2 -2
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
- package/src/runtime/spots/index.ts +16 -0
- package/src/runtime/spots/spot-activation.ts +5 -0
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
- package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
- package/src/runtime/spots/spot-entry-activation.ts +7 -0
- package/src/runtime/spots/spot-node-runtime-manager.ts +14 -12
- package/src/runtime/spots/spot-routing-internal.ts +14 -0
- package/src/runtime/spots/spot-runtime-ports.ts +2 -0
- package/src/runtime/spots/spot-serial-executor.ts +10 -4
- package/src/runtime/streams/stream-session-runtime.ts +1 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ApplicationJobOrigin } from '../application-jobs/contracts';
|
|
2
|
+
import { currentApplicationJobOrigin } from '../application-jobs/application-job-queue-scope';
|
|
1
3
|
import { listAllMeshNodeDescriptors } from '../locations/location-store-pages';
|
|
2
4
|
import { ZlinkStreamContentType } from '@zlink-systems/stream-wire';
|
|
3
5
|
import { randomBytes, randomUUID } from 'node:crypto';
|
|
@@ -349,7 +351,12 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
349
351
|
} catch {
|
|
350
352
|
return false;
|
|
351
353
|
}
|
|
352
|
-
}
|
|
354
|
+
},
|
|
355
|
+
(error) =>
|
|
356
|
+
(this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException(
|
|
357
|
+
'logger-provider',
|
|
358
|
+
error
|
|
359
|
+
)
|
|
353
360
|
);
|
|
354
361
|
this.capacityStatus = new HostCapacityStatusProjection(
|
|
355
362
|
options.registration.coreHwm,
|
|
@@ -721,13 +728,13 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
721
728
|
sessionRelocationWire: () => this.serviceRelocation,
|
|
722
729
|
clearRemoteActorPacketTarget: (actorId) =>
|
|
723
730
|
this.boundSessionRelay.clearRemoteActorPacketTarget(actorId),
|
|
724
|
-
prepareApplicationJob: async (preparationSignal) => {
|
|
731
|
+
prepareApplicationJob: async (preparationSignal, origin) => {
|
|
725
732
|
const runtimeSignal = this.executionState?.abortController.signal;
|
|
726
733
|
const signal =
|
|
727
734
|
runtimeSignal === undefined
|
|
728
735
|
? preparationSignal
|
|
729
736
|
: AbortSignal.any([runtimeSignal, preparationSignal]);
|
|
730
|
-
const permit = await this.applicationJobQueue.acquire(signal);
|
|
737
|
+
const permit = await this.applicationJobQueue.acquire(signal, origin);
|
|
731
738
|
let state: 'ready' | 'running' | 'closed' = 'ready';
|
|
732
739
|
let closedReason: unknown;
|
|
733
740
|
let abort: (() => void) | undefined;
|
|
@@ -1722,6 +1729,10 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
1722
1729
|
activationNode.registerAsyncInstanceActivationAuthority?.(
|
|
1723
1730
|
new ZLinkInstanceActivationAuthority({
|
|
1724
1731
|
store: locationStore,
|
|
1732
|
+
relocationPolicy: (stableType) =>
|
|
1733
|
+
this.options.registration.spotNodes.get(meshName)?.instanceSpotFactoryRegistrations?.[
|
|
1734
|
+
stableType
|
|
1735
|
+
]?.relocation.kind,
|
|
1725
1736
|
relocationStore: this.options.registration.locations.relocationStoreInstance,
|
|
1726
1737
|
meshName,
|
|
1727
1738
|
owner: () => this.locationOwner.currentRuntime?.currentOwnerToken,
|
|
@@ -2016,6 +2027,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2016
2027
|
| 'actorRefResolver'
|
|
2017
2028
|
| 'actorCreatedNotifier'
|
|
2018
2029
|
| 'actorDestroyedCleanup'
|
|
2030
|
+
| 'terminateActorActivation'
|
|
2019
2031
|
| 'locationLifecycle'
|
|
2020
2032
|
| 'boundSessionFactory'
|
|
2021
2033
|
| 'shutdownSignal'
|
|
@@ -2139,6 +2151,9 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2139
2151
|
}
|
|
2140
2152
|
this.actorPlacement ??= new ZLinkActorPlacementCoordinator({
|
|
2141
2153
|
store: locationStore,
|
|
2154
|
+
actorRelocationPolicy: (meshName, stableType) =>
|
|
2155
|
+
this.options.registration.spotNodes.get(meshName)?.actorFactoryRegistrations?.[stableType]
|
|
2156
|
+
?.relocation.kind,
|
|
2142
2157
|
remoteCreate: (meshName, targetNodeRid, request, timeoutMs) => {
|
|
2143
2158
|
const node = this.spotNodeRuntime?.meshNode(meshName);
|
|
2144
2159
|
if (node === undefined) {
|
|
@@ -2194,14 +2209,12 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2194
2209
|
const capability = descriptor.objectCapabilities.find(
|
|
2195
2210
|
(candidate) => candidate.objectKind === 'actor' && candidate.stableType === stableType
|
|
2196
2211
|
);
|
|
2197
|
-
const actors = descriptor.populationCapacity.actors;
|
|
2198
2212
|
return (
|
|
2199
2213
|
descriptor.state === ZLinkFrameworkRuntimeState.Serving &&
|
|
2200
2214
|
descriptor.objectRole === 'server' &&
|
|
2201
2215
|
descriptor.placementWeight > 0 &&
|
|
2202
2216
|
descriptor.entrySpotId !== undefined &&
|
|
2203
2217
|
excludedNodeRids?.has(String(descriptor.rid)) !== true &&
|
|
2204
|
-
(actors.limit === 0 || actors.active + actors.reserved < actors.limit) &&
|
|
2205
2218
|
capability !== undefined
|
|
2206
2219
|
);
|
|
2207
2220
|
}
|
|
@@ -2233,6 +2246,9 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2233
2246
|
});
|
|
2234
2247
|
const coordinator = (this.userSpotCoordinator = new ZLinkUserSpotCreationCoordinator({
|
|
2235
2248
|
store: locationStore,
|
|
2249
|
+
relocationPolicy: (meshName, stableType) =>
|
|
2250
|
+
this.options.registration.spotNodes.get(meshName)?.spotFactoryRegistrations?.[stableType]
|
|
2251
|
+
?.relocation.kind,
|
|
2236
2252
|
publishReadyRoute: (meshName, route) => {
|
|
2237
2253
|
this.cachedLocationSpotRouteResolver?.invalidate?.(route.spot.spotId);
|
|
2238
2254
|
this.spotNodeRuntime?.meshNode(meshName)?.rememberSpotRoute?.(route);
|
|
@@ -2592,6 +2608,8 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2592
2608
|
|
|
2593
2609
|
private actorRuntimeOptionsFactory(): ZLinkActorRuntimeOptionsFactory {
|
|
2594
2610
|
return new ZLinkActorRuntimeOptionsFactory({
|
|
2611
|
+
terminateActorActivation: (actor, terminal) =>
|
|
2612
|
+
this.spotNodeRuntime?.terminateActorActivation(actor, terminal) ?? terminal(),
|
|
2595
2613
|
registration: this.options.registration,
|
|
2596
2614
|
messageFlow: () => this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink).flow,
|
|
2597
2615
|
routeTransport: this.routeTransport,
|
|
@@ -2753,6 +2771,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2753
2771
|
},
|
|
2754
2772
|
meshRecordDispatcher: (meshName: string, owner: ReadyRecord, record: ReceiveRecord) =>
|
|
2755
2773
|
this.dispatchMeshRecord(
|
|
2774
|
+
currentApplicationJobOrigin,
|
|
2756
2775
|
meshName,
|
|
2757
2776
|
owner,
|
|
2758
2777
|
record,
|
|
@@ -2763,6 +2782,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2763
2782
|
}
|
|
2764
2783
|
|
|
2765
2784
|
private async dispatchMeshRecord(
|
|
2785
|
+
applicationJobOrigin: () => ApplicationJobOrigin,
|
|
2766
2786
|
meshName: string,
|
|
2767
2787
|
owner: ReadyRecord,
|
|
2768
2788
|
record: ReceiveRecord,
|
|
@@ -2964,7 +2984,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2964
2984
|
);
|
|
2965
2985
|
}
|
|
2966
2986
|
return this.admission.run(meshName, 'RouteMesh Actor dispatch', () =>
|
|
2967
|
-
this.spotManager!.dispatchMeshActor(meshName, owner, record)
|
|
2987
|
+
this.spotManager!.dispatchMeshActor(applicationJobOrigin(), meshName, owner, record)
|
|
2968
2988
|
);
|
|
2969
2989
|
case ReceiveKind.SendReady:
|
|
2970
2990
|
return Promise.resolve();
|
|
@@ -3008,7 +3028,10 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
3008
3028
|
try {
|
|
3009
3029
|
state.taskRunner.runDetached('mesh-node-local-route-dispatch', async () => {
|
|
3010
3030
|
try {
|
|
3011
|
-
const permit = await this.applicationJobQueue.acquire(
|
|
3031
|
+
const permit = await this.applicationJobQueue.acquire(
|
|
3032
|
+
state.abortController.signal,
|
|
3033
|
+
'local'
|
|
3034
|
+
);
|
|
3012
3035
|
permit.markApplicationQueued();
|
|
3013
3036
|
await runWithApplicationJobPermit(permit, () =>
|
|
3014
3037
|
channelRuntime.dispatchLocalMeshRoute(meshName, sourceNodeRid, ownedParts)
|
|
@@ -41,6 +41,7 @@ import { putNewRelocationBlob, relocationBlobReference } from '../locations/relo
|
|
|
41
41
|
|
|
42
42
|
import {
|
|
43
43
|
encodeInstanceActivationRecoveryEnvelope,
|
|
44
|
+
decodeInstanceActivationRecoveryEnvelope,
|
|
44
45
|
type ServiceInstanceActivationRecoveryEnvelope
|
|
45
46
|
} from '../foundation/service-instance-activation-recovery-codec';
|
|
46
47
|
|
|
@@ -57,6 +58,9 @@ interface PendingReservation {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export interface ZLinkInstanceActivationAuthorityOptions {
|
|
61
|
+
readonly relocationPolicy?: (
|
|
62
|
+
stableType: string
|
|
63
|
+
) => import('../locations/internal-location-contracts').ZLinkObjectReserveRequest['actorRelocationPolicy'];
|
|
60
64
|
readonly store: ZLinkObjectCreationStore & ZLinkAuthorityStore;
|
|
61
65
|
readonly relocationStore?: ZLinkRelocationStore;
|
|
62
66
|
readonly meshName: string;
|
|
@@ -73,9 +77,101 @@ export class ZLinkInstanceActivationAuthority implements ServiceAsyncInstanceAct
|
|
|
73
77
|
|
|
74
78
|
constructor(private readonly options: ZLinkInstanceActivationAuthorityOptions) {}
|
|
75
79
|
|
|
76
|
-
async read(
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
async read(
|
|
81
|
+
target: ServiceInstanceActivationTarget,
|
|
82
|
+
instanceIntent?: true,
|
|
83
|
+
activation?: ServiceInstanceActivationRecoveryEnvelope,
|
|
84
|
+
acceptsLocal?: (route: ServiceInstanceRouteFence) => boolean
|
|
85
|
+
): Promise<ServiceInstanceAuthorityRead> {
|
|
86
|
+
const key = authorityKey(target.targetSpotId);
|
|
87
|
+
const current = await this.options.store.readAuthority(key);
|
|
88
|
+
if (current.kind !== 'snapshot') return { kind: 'missing' };
|
|
89
|
+
const ready = decodeServiceInstanceAuthorityPayload(current.payload);
|
|
90
|
+
const resolved = readyRead(current, target, ready);
|
|
91
|
+
if (
|
|
92
|
+
ready?.state === 'ready' &&
|
|
93
|
+
resolved.kind === 'ready' &&
|
|
94
|
+
acceptsLocal?.(resolved.route) === true
|
|
95
|
+
) {
|
|
96
|
+
return resolved;
|
|
97
|
+
}
|
|
98
|
+
if (
|
|
99
|
+
activation !== undefined &&
|
|
100
|
+
current.allocation.objectKind === 'instance_spot' &&
|
|
101
|
+
routingIdsEqual(current.allocation.descriptor.rid, target.targetNodeRid) &&
|
|
102
|
+
current.allocation.descriptorLifecycleGeneration === target.targetNodeGeneration
|
|
103
|
+
) {
|
|
104
|
+
const reference =
|
|
105
|
+
current.pendingCreation?.requestContentReference ?? ready?.activationRecovery?.reference;
|
|
106
|
+
if (reference !== undefined) {
|
|
107
|
+
const root = await this.options.relocationStore?.read(relocationBlobReference(reference));
|
|
108
|
+
if (root?.kind !== 'found') {
|
|
109
|
+
throw new ZLinkFrameworkException(
|
|
110
|
+
ZLinkFrameworkErrorKind.DataLost,
|
|
111
|
+
'Stored Instance activation is missing.'
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
let stored: ServiceInstanceActivationRecoveryEnvelope;
|
|
115
|
+
try {
|
|
116
|
+
stored = decodeInstanceActivationRecoveryEnvelope(root.bytes);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (!(error instanceof TypeError || error instanceof RangeError)) throw error;
|
|
119
|
+
throw new ZLinkFrameworkException(
|
|
120
|
+
ZLinkFrameworkErrorKind.ProtocolError,
|
|
121
|
+
'Stored Instance activation is invalid.'
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (
|
|
125
|
+
stored.operation.high === activation.operation.high &&
|
|
126
|
+
stored.operation.low === activation.operation.low &&
|
|
127
|
+
(stored.targetMeshName !== activation.targetMeshName ||
|
|
128
|
+
stored.target.stableType !== target.stableType ||
|
|
129
|
+
stored.target.descriptorVersion !== target.descriptorVersion ||
|
|
130
|
+
stored.deadlineUnixMs !== activation.deadlineUnixMs ||
|
|
131
|
+
(stored.metadataFrame === undefined) !== (activation.metadataFrame === undefined) ||
|
|
132
|
+
(stored.metadataFrame !== undefined &&
|
|
133
|
+
activation.metadataFrame !== undefined &&
|
|
134
|
+
Buffer.compare(stored.metadataFrame, activation.metadataFrame) !== 0))
|
|
135
|
+
) {
|
|
136
|
+
throw new ZLinkFrameworkException(
|
|
137
|
+
ZLinkFrameworkErrorKind.ProtocolError,
|
|
138
|
+
'Instance route does not match the stored activation.'
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
instanceIntent === true &&
|
|
146
|
+
current.allocation.state === 'active' &&
|
|
147
|
+
ready?.state === 'ready'
|
|
148
|
+
) {
|
|
149
|
+
if (
|
|
150
|
+
current.allocation.objectKind !== 'instance_spot' ||
|
|
151
|
+
current.allocation.stableType !== target.stableType
|
|
152
|
+
) {
|
|
153
|
+
throw createInternalFrameworkException(
|
|
154
|
+
ZLinkFrameworkInternalErrorKind.SpotTypeMismatch,
|
|
155
|
+
'Instance activation type does not match the current authority.'
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
const released = await this.options.store.releaseEndedReservation?.(
|
|
159
|
+
key,
|
|
160
|
+
current.storeVersion.value,
|
|
161
|
+
undefined,
|
|
162
|
+
{
|
|
163
|
+
key: { kind: 'instance_spot', globalId: target.targetSpotId },
|
|
164
|
+
intent: { stableType: target.stableType },
|
|
165
|
+
actorRelocationPolicy: this.options.relocationPolicy?.(target.stableType)
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
if (released === true) return { kind: 'missing' };
|
|
169
|
+
const refreshed = await this.options.store.readAuthority(key);
|
|
170
|
+
return refreshed.kind === 'snapshot'
|
|
171
|
+
? readyRead(refreshed, target, decodeServiceInstanceAuthorityPayload(refreshed.payload))
|
|
172
|
+
: { kind: 'missing' };
|
|
173
|
+
}
|
|
174
|
+
return resolved;
|
|
79
175
|
}
|
|
80
176
|
|
|
81
177
|
async reserve(
|
|
@@ -117,6 +213,7 @@ export class ZLinkInstanceActivationAuthority implements ServiceAsyncInstanceAct
|
|
|
117
213
|
reserved = await this.options.store.reserve(
|
|
118
214
|
{
|
|
119
215
|
key: { kind: 'instance_spot', globalId: target.targetSpotId },
|
|
216
|
+
actorRelocationPolicy: this.options.relocationPolicy?.(target.stableType),
|
|
120
217
|
intent: {
|
|
121
218
|
stableType: target.stableType,
|
|
122
219
|
requestContentReference: stored.reference.value,
|
|
@@ -310,7 +407,11 @@ export class ZLinkInstanceActivationAuthority implements ServiceAsyncInstanceAct
|
|
|
310
407
|
}
|
|
311
408
|
const current = await this.options.store.readAuthority(authorityKey(target.targetSpotId));
|
|
312
409
|
if (current.kind === 'snapshot') {
|
|
313
|
-
const ready = readyRead(
|
|
410
|
+
const ready = readyRead(
|
|
411
|
+
current,
|
|
412
|
+
target,
|
|
413
|
+
decodeServiceInstanceAuthorityPayload(current.payload)
|
|
414
|
+
);
|
|
314
415
|
if (ready.kind === 'ready') {
|
|
315
416
|
this.pending.delete(reservation.token);
|
|
316
417
|
return { kind: 'lost', route: ready.route };
|
|
@@ -344,7 +445,7 @@ export class ZLinkInstanceActivationAuthority implements ServiceAsyncInstanceAct
|
|
|
344
445
|
throw new Error('Instance activation authority changed before inbox release.');
|
|
345
446
|
}
|
|
346
447
|
const recovery = decoded.activationRecovery;
|
|
347
|
-
if (recovery === undefined) return routeFromSnapshot(current);
|
|
448
|
+
if (recovery === undefined) return routeFromSnapshot(current, decoded.spotId);
|
|
348
449
|
let completed = current;
|
|
349
450
|
if (recovery.replayCursor < recovery.inboxSequence) {
|
|
350
451
|
const cursorStored = await this.options.store.compareExchangeAuthority(
|
|
@@ -459,22 +560,19 @@ export class ZLinkInstanceActivationAuthority implements ServiceAsyncInstanceAct
|
|
|
459
560
|
|
|
460
561
|
function readyRead(
|
|
461
562
|
snapshot: ZLinkAuthoritySnapshot,
|
|
462
|
-
target: ServiceInstanceActivationTarget
|
|
563
|
+
target: ServiceInstanceActivationTarget,
|
|
564
|
+
decoded: ReturnType<typeof decodeServiceInstanceAuthorityPayload>
|
|
463
565
|
): ServiceInstanceAuthorityRead {
|
|
464
|
-
const decoded =
|
|
465
|
-
decodeServiceReadySpotAuthority(snapshot.payload) ??
|
|
466
|
-
decodeServiceClosingSpotAuthority(snapshot.payload);
|
|
467
|
-
const creating = decodeServiceInstanceAuthorityPayload(snapshot.payload);
|
|
468
566
|
if (
|
|
469
|
-
|
|
567
|
+
decoded?.state === 'coldActivating' &&
|
|
470
568
|
snapshot.allocation.objectKind === 'instance_spot' &&
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
routingIdsEqual(
|
|
569
|
+
decoded.stableType === target.stableType &&
|
|
570
|
+
decoded.spotId === target.targetSpotId &&
|
|
571
|
+
decoded.ownerId === snapshot.ownerId &&
|
|
572
|
+
decoded.ownerLeaseGeneration === snapshot.ownerLeaseGeneration &&
|
|
573
|
+
decoded.ownerMeshName === snapshot.allocation.descriptor.meshName &&
|
|
574
|
+
decoded.ownerNodeGeneration === snapshot.allocation.descriptorLifecycleGeneration &&
|
|
575
|
+
routingIdsEqual(decoded.ownerNodeRid, snapshot.allocation.descriptor.rid) &&
|
|
478
576
|
routingIdsEqual(target.targetNodeRid, snapshot.allocation.descriptor.rid) &&
|
|
479
577
|
target.targetNodeGeneration === snapshot.allocation.descriptorLifecycleGeneration
|
|
480
578
|
) {
|
|
@@ -486,7 +584,8 @@ function readyRead(
|
|
|
486
584
|
};
|
|
487
585
|
}
|
|
488
586
|
if (
|
|
489
|
-
decoded
|
|
587
|
+
decoded === undefined ||
|
|
588
|
+
decoded.state === 'coldActivating' ||
|
|
490
589
|
decoded.stableType !== target.stableType ||
|
|
491
590
|
decoded.spotId !== target.targetSpotId ||
|
|
492
591
|
snapshot.allocation.objectKind !== 'instance_spot' ||
|
|
@@ -501,7 +600,7 @@ function readyRead(
|
|
|
501
600
|
) {
|
|
502
601
|
return { kind: 'missing' };
|
|
503
602
|
}
|
|
504
|
-
return { kind: 'ready', route: routeFromSnapshot(snapshot), authority: snapshot };
|
|
603
|
+
return { kind: 'ready', route: routeFromSnapshot(snapshot, decoded.spotId), authority: snapshot };
|
|
505
604
|
}
|
|
506
605
|
|
|
507
606
|
function requireCommitIdentity(
|
|
@@ -529,17 +628,23 @@ function requireCommitIdentity(
|
|
|
529
628
|
}
|
|
530
629
|
}
|
|
531
630
|
|
|
532
|
-
function routeFromSnapshot(
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
if (
|
|
537
|
-
|
|
631
|
+
function routeFromSnapshot(
|
|
632
|
+
snapshot: ZLinkAuthoritySnapshot,
|
|
633
|
+
spotId?: string
|
|
634
|
+
): ServiceInstanceRouteFence {
|
|
635
|
+
if (spotId === undefined) {
|
|
636
|
+
const decoded =
|
|
637
|
+
decodeServiceReadySpotAuthority(snapshot.payload) ??
|
|
638
|
+
decodeServiceClosingSpotAuthority(snapshot.payload);
|
|
639
|
+
if (decoded?.kind !== 'instance_spot') {
|
|
640
|
+
throw new Error('Instance authority is not Ready.');
|
|
641
|
+
}
|
|
642
|
+
spotId = decoded.spotId;
|
|
538
643
|
}
|
|
539
644
|
return {
|
|
540
645
|
targetNodeRid: String(snapshot.allocation.descriptor.rid),
|
|
541
646
|
targetNodeGeneration: snapshot.allocation.descriptorLifecycleGeneration,
|
|
542
|
-
targetSpotId:
|
|
647
|
+
targetSpotId: spotId,
|
|
543
648
|
objectGeneration: snapshot.objectGeneration,
|
|
544
649
|
ownerId: snapshot.ownerId,
|
|
545
650
|
authorityOwnerGeneration: snapshot.authorityOwnerGeneration,
|
|
@@ -4812,6 +4812,7 @@ class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden>
|
|
|
4812
4812
|
throw new Error('Relocated Entry Spot Actor dispatch is unavailable.');
|
|
4813
4813
|
}
|
|
4814
4814
|
return runtime.dispatchEntryActorPacket(
|
|
4815
|
+
'remote',
|
|
4815
4816
|
hidden.actor!.context.actorId,
|
|
4816
4817
|
parts,
|
|
4817
4818
|
returnResponse,
|
|
@@ -4820,6 +4821,7 @@ class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden>
|
|
|
4820
4821
|
);
|
|
4821
4822
|
}
|
|
4822
4823
|
return this.requireSpotManager().dispatchRoutedActorPacket(
|
|
4824
|
+
'remote',
|
|
4823
4825
|
state.spotId,
|
|
4824
4826
|
hidden.actor!.context.actorId,
|
|
4825
4827
|
parts,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ServiceInstanceColdActivationTarget } from '../foundation/service-stateful-wire-codec';
|
|
1
2
|
import { ZLinkFrameworkException, ZLinkSpotKind, type RoutingId } from '../../contracts';
|
|
2
3
|
import {
|
|
3
4
|
ZLinkRuntimeDispatchErrorAction as ZLinkDispatchErrorAction,
|
|
@@ -44,7 +45,11 @@ import type {
|
|
|
44
45
|
ZLinkSpotAddressTransport,
|
|
45
46
|
ZLinkSpotRoutedTransport
|
|
46
47
|
} from '../spots/spot-outbound';
|
|
47
|
-
import type {
|
|
48
|
+
import type {
|
|
49
|
+
ZLinkSpotRouteResolver,
|
|
50
|
+
ZLinkSpotRouteTarget,
|
|
51
|
+
ZLinkInstanceReactivationRoute
|
|
52
|
+
} from '../spots/spot-routing-internal';
|
|
48
53
|
|
|
49
54
|
export interface ZLinkHostSpotAddressTransportOptions {
|
|
50
55
|
readonly resolver: () => ZLinkSpotRouteResolver | undefined;
|
|
@@ -65,13 +70,7 @@ export function hasObjectClientCapability(role: 'none' | 'client' | 'server' | u
|
|
|
65
70
|
type MissingTarget = {
|
|
66
71
|
readonly meshName: string;
|
|
67
72
|
readonly node: ZLinkBackendMeshNode;
|
|
68
|
-
readonly target:
|
|
69
|
-
readonly targetNodeRid: string;
|
|
70
|
-
readonly targetNodeGeneration: bigint;
|
|
71
|
-
readonly targetSpotId: string;
|
|
72
|
-
readonly stableType: string;
|
|
73
|
-
readonly descriptorVersion: string;
|
|
74
|
-
};
|
|
73
|
+
readonly target: ServiceInstanceColdActivationTarget;
|
|
75
74
|
};
|
|
76
75
|
|
|
77
76
|
type MissingTargetSelection =
|
|
@@ -106,7 +105,10 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
106
105
|
const activationDeadlineUnixMs = BigInt(
|
|
107
106
|
Math.round(Date.now() + this.options.defaultRequestTimeoutMs)
|
|
108
107
|
);
|
|
109
|
-
const
|
|
108
|
+
const resolution = await this.resolveExisting(spotId, undefined, call);
|
|
109
|
+
const existing = resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
|
|
110
|
+
if (resolution !== undefined && 'kind' in resolution)
|
|
111
|
+
call = this.reactivationCall(resolution, call);
|
|
110
112
|
if (existing !== undefined) {
|
|
111
113
|
this.validateExisting(existing, call);
|
|
112
114
|
try {
|
|
@@ -166,7 +168,7 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
166
168
|
if (!call.instanceSpot) {
|
|
167
169
|
return { status: ZLinkSubmitStatus.TargetNotFound };
|
|
168
170
|
}
|
|
169
|
-
const selected = this.selectMissingTarget(spotId, call);
|
|
171
|
+
const selected = this.selectMissingTarget(spotId, call, resolution);
|
|
170
172
|
if (selected.kind === 'unsupported') {
|
|
171
173
|
this.traceInstanceAddress(
|
|
172
174
|
ZLinkMessageFlowOutcome.Dropped,
|
|
@@ -252,10 +254,13 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
252
254
|
const timeoutMs = call.timeoutMs ?? this.options.defaultRequestTimeoutMs;
|
|
253
255
|
const deadline = createSpotAddressDeadline(timeoutMs, call.signal);
|
|
254
256
|
try {
|
|
255
|
-
const
|
|
257
|
+
const resolution = await this.resolveExisting(spotId, deadline.signal, call);
|
|
258
|
+
const existing = resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
|
|
259
|
+
if (resolution !== undefined && 'kind' in resolution)
|
|
260
|
+
call = this.reactivationCall(resolution, call);
|
|
256
261
|
deadline.requireRemaining();
|
|
257
262
|
if (existing === undefined) {
|
|
258
|
-
return await this.requestToMissingInstance(spotId, request, call, deadline);
|
|
263
|
+
return await this.requestToMissingInstance(spotId, request, call, deadline, resolution);
|
|
259
264
|
}
|
|
260
265
|
this.validateExisting(existing, call);
|
|
261
266
|
try {
|
|
@@ -351,7 +356,8 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
351
356
|
spotId: RoutingId,
|
|
352
357
|
request: unknown,
|
|
353
358
|
call: ZLinkSpotAddressCallOptions,
|
|
354
|
-
deadline: ZLinkSpotAddressDeadline
|
|
359
|
+
deadline: ZLinkSpotAddressDeadline,
|
|
360
|
+
current?: ZLinkSpotRouteTarget | ZLinkInstanceReactivationRoute
|
|
355
361
|
): Promise<TReply> {
|
|
356
362
|
if (!call.instanceSpot) {
|
|
357
363
|
throw createInternalFrameworkException(
|
|
@@ -359,7 +365,7 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
359
365
|
`Spot '${String(spotId)}' has no Ready authority.`
|
|
360
366
|
);
|
|
361
367
|
}
|
|
362
|
-
const selected = this.selectMissingTarget(spotId, call);
|
|
368
|
+
const selected = this.selectMissingTarget(spotId, call, current);
|
|
363
369
|
if (selected.kind === 'capacity') {
|
|
364
370
|
throw missingInstancePlacementCapacity(spotId, call.instanceSpotType);
|
|
365
371
|
}
|
|
@@ -507,14 +513,20 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
507
513
|
|
|
508
514
|
private async resolveExisting(
|
|
509
515
|
spotId: RoutingId,
|
|
510
|
-
signal?: AbortSignal
|
|
511
|
-
|
|
516
|
+
signal?: AbortSignal,
|
|
517
|
+
call?: ZLinkSpotAddressCallOptions
|
|
518
|
+
): Promise<ZLinkSpotRouteTarget | ZLinkInstanceReactivationRoute | undefined> {
|
|
512
519
|
const resolver = this.options.resolver();
|
|
513
520
|
if (resolver === undefined) {
|
|
514
521
|
throw new Error('Global Spot address resolution requires a Location Store.');
|
|
515
522
|
}
|
|
516
523
|
try {
|
|
517
|
-
return await awaitWithAbort(
|
|
524
|
+
return await awaitWithAbort(
|
|
525
|
+
call?.instanceSpot === true
|
|
526
|
+
? resolver.resolve(spotId, signal, true)
|
|
527
|
+
: resolver.resolve(spotId, signal),
|
|
528
|
+
signal
|
|
529
|
+
);
|
|
518
530
|
} catch (error) {
|
|
519
531
|
if (
|
|
520
532
|
error instanceof ZLinkFrameworkException &&
|
|
@@ -526,9 +538,18 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
526
538
|
}
|
|
527
539
|
}
|
|
528
540
|
|
|
541
|
+
private reactivationCall(
|
|
542
|
+
route: ZLinkInstanceReactivationRoute,
|
|
543
|
+
call: ZLinkSpotAddressCallOptions
|
|
544
|
+
): ZLinkSpotAddressCallOptions {
|
|
545
|
+
this.validateExisting(route, call);
|
|
546
|
+
return { ...call, initialMeshName: route.meshName, instanceSpotType: route.stableType };
|
|
547
|
+
}
|
|
548
|
+
|
|
529
549
|
private selectMissingTarget(
|
|
530
550
|
spotId: RoutingId,
|
|
531
|
-
call: ZLinkSpotAddressCallOptions
|
|
551
|
+
call: ZLinkSpotAddressCallOptions,
|
|
552
|
+
current?: ZLinkSpotRouteTarget | ZLinkInstanceReactivationRoute
|
|
532
553
|
): MissingTargetSelection {
|
|
533
554
|
const configuredMeshes = this.options.meshNames();
|
|
534
555
|
if (
|
|
@@ -574,14 +595,15 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
574
595
|
const stableType =
|
|
575
596
|
call.instanceSpotType ?? (distinctTypes.length === 1 ? distinctTypes[0] : undefined);
|
|
576
597
|
if (stableType === undefined) {
|
|
577
|
-
if (distinctTypes.length === 0)
|
|
598
|
+
if (distinctTypes.length === 0)
|
|
599
|
+
return { kind: current === undefined ? 'unsupported' : 'unavailable' };
|
|
578
600
|
throw createInternalFrameworkException(
|
|
579
601
|
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
580
602
|
'Instance Spot type is required when multiple types are registered.'
|
|
581
603
|
);
|
|
582
604
|
}
|
|
583
605
|
if (canInspectPlacementTypes && !distinctTypes.includes(stableType)) {
|
|
584
|
-
return { kind: 'unsupported' };
|
|
606
|
+
return { kind: current === undefined ? 'unsupported' : 'unavailable' };
|
|
585
607
|
}
|
|
586
608
|
let unavailable = false;
|
|
587
609
|
let capacity = false;
|
|
@@ -600,6 +622,7 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
600
622
|
node,
|
|
601
623
|
target: {
|
|
602
624
|
...placement.target,
|
|
625
|
+
targetMeshName: meshName,
|
|
603
626
|
targetSpotId: String(spotId),
|
|
604
627
|
stableType
|
|
605
628
|
}
|
|
@@ -611,12 +634,12 @@ export class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport
|
|
|
611
634
|
}
|
|
612
635
|
if (unavailable) return { kind: 'unavailable' };
|
|
613
636
|
if (capacity) return { kind: 'capacity' };
|
|
614
|
-
if (unsupported) return { kind: 'unsupported' };
|
|
637
|
+
if (unsupported) return { kind: current === undefined ? 'unsupported' : 'unavailable' };
|
|
615
638
|
return { kind: 'unavailable' };
|
|
616
639
|
}
|
|
617
640
|
|
|
618
641
|
private validateExisting(
|
|
619
|
-
target:
|
|
642
|
+
target: Pick<ZLinkSpotRouteTarget, 'spotId' | 'spotKind' | 'stableType'>,
|
|
620
643
|
call: ZLinkSpotAddressCallOptions
|
|
621
644
|
): void {
|
|
622
645
|
if (!call.instanceSpot) return;
|
|
@@ -102,6 +102,7 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
102
102
|
Promise.resolve()
|
|
103
103
|
},
|
|
104
104
|
dispatchEntryActorPacket: (
|
|
105
|
+
origin,
|
|
105
106
|
actorId,
|
|
106
107
|
parts,
|
|
107
108
|
returnResponse,
|
|
@@ -117,6 +118,7 @@ export class ZLinkSpotRuntimeOptionsFactory {
|
|
|
117
118
|
);
|
|
118
119
|
}
|
|
119
120
|
return runtime.dispatchEntryActorPacket(
|
|
121
|
+
origin,
|
|
120
122
|
actorId,
|
|
121
123
|
parts,
|
|
122
124
|
returnResponse,
|
|
@@ -38,6 +38,10 @@ const DEFAULT_USER_SPOT_CLEANUP_TIMEOUT_MS = 1_000;
|
|
|
38
38
|
const DEFAULT_USER_SPOT_POLL_INTERVAL_MS = 10;
|
|
39
39
|
|
|
40
40
|
export interface ZLinkUserSpotCreationCoordinatorOptions {
|
|
41
|
+
readonly relocationPolicy?: (
|
|
42
|
+
meshName: string,
|
|
43
|
+
stableType: string
|
|
44
|
+
) => import('../locations/internal-location-contracts').ZLinkObjectReserveRequest['actorRelocationPolicy'];
|
|
41
45
|
readonly store: ZLinkObjectCreationStore & ZLinkAuthorityStore;
|
|
42
46
|
readonly target: (
|
|
43
47
|
request: Pick<ZLinkUserSpotCreationRequest, 'meshName' | 'stableType'>,
|
|
@@ -169,6 +173,10 @@ export class ZLinkUserSpotCreationCoordinator {
|
|
|
169
173
|
reserved = await this.options.store.reserve(
|
|
170
174
|
{
|
|
171
175
|
key: { kind: 'user_spot', globalId: String(request.spotId) },
|
|
176
|
+
actorRelocationPolicy: this.options.relocationPolicy?.(
|
|
177
|
+
target.meshName,
|
|
178
|
+
request.stableType
|
|
179
|
+
),
|
|
172
180
|
intent: {
|
|
173
181
|
stableType: request.stableType,
|
|
174
182
|
requestContentReference: contentReference,
|
|
@@ -37,9 +37,12 @@ import type {
|
|
|
37
37
|
ZLinkObjectCommitResult,
|
|
38
38
|
ZLinkObjectCreationCompleteRequest,
|
|
39
39
|
ZLinkObjectCreationCompleteResult,
|
|
40
|
-
ZLinkObjectReserveRequest,
|
|
41
40
|
ZLinkObjectReserveResult
|
|
42
41
|
} from '../../contracts/Locations/Authority';
|
|
42
|
+
import type {
|
|
43
|
+
ZLinkObjectReserveRequest,
|
|
44
|
+
ZLinkEndedOwnerReleaseIntent
|
|
45
|
+
} from './internal-location-contracts';
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
48
|
* Framework-private domain repository. Provider implementations never
|
|
@@ -143,7 +146,8 @@ export interface ZLinkDomainLocationStore {
|
|
|
143
146
|
releaseEndedReservation?(
|
|
144
147
|
key: ZLinkAuthorityKey,
|
|
145
148
|
expectedStoreVersion: string,
|
|
146
|
-
signal?: AbortSignal
|
|
149
|
+
signal?: AbortSignal,
|
|
150
|
+
request?: ZLinkEndedOwnerReleaseIntent
|
|
147
151
|
): Promise<boolean>;
|
|
148
152
|
abort(
|
|
149
153
|
request: ZLinkObjectAbortRequest,
|