@zlink-systems/framework 0.29.1 → 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/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 +34 -23
- 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/host/actor-packet-relay.js +7 -7
- package/dist/runtime/host/actor-runtime-options-factory.js +1 -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.js +15 -11
- 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 +2 -2
- package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
- package/dist/runtime/locations/in-memory-authority-store.js +80 -8
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +19 -3
- package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
- package/dist/runtime/locations/location-store-repository.d.ts +3 -2
- package/dist/runtime/locations/location-store-repository.js +165 -22
- 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.js +3 -1
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
- package/dist/runtime/spots/spot-node-runtime-manager.js +4 -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/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/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 +61 -35
- package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
- package/src/runtime/foundation/service-topology-registry.ts +13 -7
- package/src/runtime/host/actor-packet-relay.ts +7 -0
- package/src/runtime/host/actor-runtime-options-factory.ts +1 -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 +24 -5
- 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 +113 -9
- package/src/runtime/locations/in-memory-location-store.ts +25 -3
- package/src/runtime/locations/internal-location-contracts.ts +4 -0
- package/src/runtime/locations/location-store-repository.ts +220 -15
- 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 +3 -0
- package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
- package/src/runtime/spots/spot-routing-internal.ts +14 -0
- package/src/runtime/spots/spot-runtime-ports.ts +2 -0
- package/src/runtime/streams/stream-session-runtime.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ZLINK_MAX_IDENTITY_TEXT_BYTES } from '../../contracts/Common/CoreTypes';
|
|
2
|
+
import type { ServiceLivenessConnection } from './service-liveness-registry';
|
|
2
3
|
import {
|
|
3
4
|
ZLINK_MAX_PUBLIC_WEIGHT,
|
|
4
5
|
isValidCapacity,
|
|
@@ -43,7 +44,8 @@ export interface AdmittedServicePeer {
|
|
|
43
44
|
readonly descriptor: ServiceNodeDescriptor;
|
|
44
45
|
// The Core selected-route generation this admission belongs to (Core ROUTER
|
|
45
46
|
// §10.1), as an opaque token compared only for equality.
|
|
46
|
-
readonly connectionId: string;
|
|
47
|
+
readonly connectionId: string | bigint;
|
|
48
|
+
readonly liveness?: ServiceLivenessConnection;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
export interface ServicePeerAdmissionExpectation {
|
|
@@ -103,12 +105,14 @@ export class ServiceTopologyRegistry {
|
|
|
103
105
|
|
|
104
106
|
admit(
|
|
105
107
|
descriptor: ServiceNodeDescriptor,
|
|
106
|
-
connectionId: string,
|
|
107
|
-
expected?: ServicePeerAdmissionExpectation
|
|
108
|
+
connectionId: string | bigint,
|
|
109
|
+
expected?: ServicePeerAdmissionExpectation,
|
|
110
|
+
admitLiveness?: () => ServiceLivenessConnection
|
|
108
111
|
): PeerAdmissionResult {
|
|
109
112
|
try {
|
|
110
113
|
validateDescriptor(descriptor);
|
|
111
|
-
requireText(connectionId, 'connectionId');
|
|
114
|
+
if (typeof connectionId === 'string') requireText(connectionId, 'connectionId');
|
|
115
|
+
else if (connectionId === 0n) throw new TypeError('connectionId must be nonzero.');
|
|
112
116
|
} catch (error) {
|
|
113
117
|
return 'invalidDescriptor';
|
|
114
118
|
}
|
|
@@ -154,14 +158,15 @@ export class ServiceTopologyRegistry {
|
|
|
154
158
|
// that route replaces the admission of a route it replaced.
|
|
155
159
|
this.peersByRid.set(descriptor.nodeRoutingId, {
|
|
156
160
|
descriptor: cloneDescriptor(descriptor),
|
|
157
|
-
connectionId
|
|
161
|
+
connectionId,
|
|
162
|
+
liveness: admitLiveness?.() ?? current?.liveness
|
|
158
163
|
});
|
|
159
164
|
this.remember(descriptor);
|
|
160
165
|
this.rebuildSelections();
|
|
161
166
|
return 'admitted';
|
|
162
167
|
}
|
|
163
168
|
|
|
164
|
-
disconnect(nodeRoutingId: string, connectionId: string): boolean {
|
|
169
|
+
disconnect(nodeRoutingId: string, connectionId: string | bigint): boolean {
|
|
165
170
|
const current = this.peersByRid.get(nodeRoutingId);
|
|
166
171
|
if (current === undefined || current.connectionId !== connectionId) return false;
|
|
167
172
|
this.peersByRid.delete(nodeRoutingId);
|
|
@@ -525,7 +530,8 @@ function cloneDescriptor(descriptor: ServiceNodeDescriptor): ServiceNodeDescript
|
|
|
525
530
|
function clonePeer(peer: AdmittedServicePeer): AdmittedServicePeer {
|
|
526
531
|
return {
|
|
527
532
|
descriptor: cloneDescriptor(peer.descriptor),
|
|
528
|
-
connectionId: peer.connectionId
|
|
533
|
+
connectionId: peer.connectionId,
|
|
534
|
+
liveness: peer.liveness
|
|
529
535
|
};
|
|
530
536
|
}
|
|
531
537
|
|
|
@@ -303,6 +303,7 @@ export class ZLinkActorPacketRelay {
|
|
|
303
303
|
const dispatch =
|
|
304
304
|
state?.spotId === undefined
|
|
305
305
|
? this.requireSpotNodeRuntime().dispatchEntryActorPacket(
|
|
306
|
+
'remote',
|
|
306
307
|
relay.actorId,
|
|
307
308
|
[header, body],
|
|
308
309
|
false,
|
|
@@ -310,6 +311,7 @@ export class ZLinkActorPacketRelay {
|
|
|
310
311
|
fallbackActorRef
|
|
311
312
|
)
|
|
312
313
|
: this.requireSpotManager().dispatchRoutedActorPacket(
|
|
314
|
+
'remote',
|
|
313
315
|
state.spotId,
|
|
314
316
|
relay.actorId,
|
|
315
317
|
[header, body],
|
|
@@ -356,6 +358,7 @@ export class ZLinkActorPacketRelay {
|
|
|
356
358
|
const dispatch =
|
|
357
359
|
state?.spotId === undefined
|
|
358
360
|
? this.requireSpotNodeRuntime().dispatchEntryActorPacket(
|
|
361
|
+
'remote',
|
|
359
362
|
relay.actorId,
|
|
360
363
|
[header, body],
|
|
361
364
|
false,
|
|
@@ -363,6 +366,7 @@ export class ZLinkActorPacketRelay {
|
|
|
363
366
|
fallbackActorRef
|
|
364
367
|
)
|
|
365
368
|
: this.requireSpotManager().dispatchRoutedActorPacket(
|
|
369
|
+
'remote',
|
|
366
370
|
state.spotId,
|
|
367
371
|
relay.actorId,
|
|
368
372
|
[header, body],
|
|
@@ -423,6 +427,7 @@ export class ZLinkActorPacketRelay {
|
|
|
423
427
|
const response =
|
|
424
428
|
state?.spotId === undefined
|
|
425
429
|
? await this.requireSpotNodeRuntime().dispatchEntryActorPacket(
|
|
430
|
+
'remote',
|
|
426
431
|
relay.actorId,
|
|
427
432
|
[header, body],
|
|
428
433
|
relay.returnResponse === true,
|
|
@@ -430,6 +435,7 @@ export class ZLinkActorPacketRelay {
|
|
|
430
435
|
fallbackActorRef
|
|
431
436
|
)
|
|
432
437
|
: await this.requireSpotManager().dispatchRoutedActorPacket(
|
|
438
|
+
'remote',
|
|
433
439
|
state.spotId,
|
|
434
440
|
relay.actorId,
|
|
435
441
|
[header, body],
|
|
@@ -892,6 +898,7 @@ export class ZLinkActorPacketRelay {
|
|
|
892
898
|
this.options.detachedTaskRunner.runDetached('local actor packet relay', async () => {
|
|
893
899
|
try {
|
|
894
900
|
const response = await this.requireSpotManager().dispatchRoutedActorPacket(
|
|
901
|
+
'local',
|
|
895
902
|
spotId,
|
|
896
903
|
actor.actorId,
|
|
897
904
|
[header, body],
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { SeverityNumber } from '@opentelemetry/api-logs';
|
|
2
|
+
import { telemetryLogger } from '../diagnostics/message-flow';
|
|
1
3
|
import { MILLISECONDS_PER_SECOND } from '../diagnostics/runtime-metrics';
|
|
2
4
|
import { ZLinkApplicationJobQueueProfile } from '../../contracts/Dispatch';
|
|
3
5
|
import {
|
|
@@ -11,6 +13,7 @@ import {
|
|
|
11
13
|
import { readFileSync } from 'node:fs';
|
|
12
14
|
import { availableParallelism } from 'node:os';
|
|
13
15
|
import type {
|
|
16
|
+
ApplicationJobOrigin,
|
|
14
17
|
ApplicationJobPermitPort,
|
|
15
18
|
ApplicationJobQueuePort
|
|
16
19
|
} from '../application-jobs/contracts';
|
|
@@ -122,7 +125,10 @@ export function resolveApplicationJobQueueConfiguration(
|
|
|
122
125
|
export class ApplicationJobQueuePermit implements ApplicationJobPermitPort {
|
|
123
126
|
private state: 'reserved' | 'queued' | 'released' = 'reserved';
|
|
124
127
|
|
|
125
|
-
constructor(
|
|
128
|
+
constructor(
|
|
129
|
+
private readonly owner: ApplicationJobQueue,
|
|
130
|
+
readonly origin: ApplicationJobOrigin
|
|
131
|
+
) {}
|
|
126
132
|
|
|
127
133
|
markApplicationQueued(): void {
|
|
128
134
|
if (this.state !== 'reserved') {
|
|
@@ -149,6 +155,7 @@ export class ApplicationJobQueuePermit implements ApplicationJobPermitPort {
|
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
interface CapacityWaiter {
|
|
158
|
+
readonly origin: ApplicationJobOrigin;
|
|
152
159
|
readonly resolve: (permit: ApplicationJobQueuePermit) => void;
|
|
153
160
|
readonly reject: (reason: unknown) => void;
|
|
154
161
|
readonly signal?: AbortSignal;
|
|
@@ -164,6 +171,8 @@ interface CapacityWaiter {
|
|
|
164
171
|
* directly to the oldest live waiter without allocating the configured limit.
|
|
165
172
|
*/
|
|
166
173
|
export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
174
|
+
private localWaiters = 0;
|
|
175
|
+
private localBacklogLogged = false;
|
|
167
176
|
private reservedSupplyPermits = 0n;
|
|
168
177
|
private queuedApplicationJobs = 0n;
|
|
169
178
|
private peakPermitsInUse = 0n;
|
|
@@ -191,7 +200,8 @@ export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
|
191
200
|
constructor(
|
|
192
201
|
private readonly configuration: ApplicationJobQueueConfiguration,
|
|
193
202
|
private readonly nowMs: () => number = () => performance.now(),
|
|
194
|
-
private readonly handlerStartGate?: () => boolean
|
|
203
|
+
private readonly handlerStartGate?: () => boolean,
|
|
204
|
+
private readonly loggerFailureReporter?: (error: unknown) => void
|
|
195
205
|
) {
|
|
196
206
|
this.receiveFlowController = new ApplicationJobReceiveFlowController(this, (state) => state);
|
|
197
207
|
}
|
|
@@ -242,16 +252,33 @@ export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
|
242
252
|
this.receiveFlowController.unregister(target);
|
|
243
253
|
}
|
|
244
254
|
|
|
245
|
-
acquire(
|
|
255
|
+
acquire(
|
|
256
|
+
signal: AbortSignal | undefined,
|
|
257
|
+
origin: ApplicationJobOrigin
|
|
258
|
+
): Promise<ApplicationJobQueuePermit> {
|
|
259
|
+
return new Promise((resolve, reject) => {
|
|
260
|
+
const permit = this.acquireOrResume(resolve, reject, signal, origin);
|
|
261
|
+
if (permit !== undefined) resolve(permit);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
acquireOrResume(
|
|
266
|
+
resume: (permit: ApplicationJobQueuePermit) => void,
|
|
267
|
+
reject: (reason: unknown) => void,
|
|
268
|
+
signal: AbortSignal | undefined,
|
|
269
|
+
origin: ApplicationJobOrigin
|
|
270
|
+
): ApplicationJobQueuePermit | undefined {
|
|
246
271
|
if (signal?.aborted === true) {
|
|
247
|
-
|
|
272
|
+
reject(abortReason(signal));
|
|
273
|
+
return undefined;
|
|
248
274
|
}
|
|
249
275
|
if (this.waiters.length === 0 && this.permitsInUse() < this.limit()) {
|
|
250
|
-
return
|
|
276
|
+
return this.reserve(origin);
|
|
251
277
|
}
|
|
252
278
|
|
|
253
|
-
|
|
279
|
+
new Promise<ApplicationJobQueuePermit>((resolve, reject) => {
|
|
254
280
|
const waiter: CapacityWaiter = {
|
|
281
|
+
origin,
|
|
255
282
|
resolve,
|
|
256
283
|
reject,
|
|
257
284
|
signal,
|
|
@@ -262,9 +289,14 @@ export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
|
262
289
|
};
|
|
263
290
|
this.waiters.push(waiter);
|
|
264
291
|
this.capacityWaitCount += 1n;
|
|
292
|
+
const warningCount = this.updateLocalWaiters(origin, 1);
|
|
265
293
|
signal?.addEventListener('abort', waiter.abort, { once: true });
|
|
266
294
|
this.drainWaiters();
|
|
267
|
-
|
|
295
|
+
if (warningCount !== undefined) this.logLocalBacklog(warningCount);
|
|
296
|
+
})
|
|
297
|
+
.then(resume)
|
|
298
|
+
.catch(reject);
|
|
299
|
+
return undefined;
|
|
268
300
|
}
|
|
269
301
|
|
|
270
302
|
snapshot(): ApplicationJobQueueSnapshot {
|
|
@@ -356,12 +388,15 @@ export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
|
356
388
|
return this.reservedSupplyPermits + this.queuedApplicationJobs;
|
|
357
389
|
}
|
|
358
390
|
|
|
359
|
-
private reserve(
|
|
391
|
+
private reserve(
|
|
392
|
+
origin: ApplicationJobOrigin,
|
|
393
|
+
evaluatePressure = true
|
|
394
|
+
): ApplicationJobQueuePermit {
|
|
360
395
|
this.reservedSupplyPermits += 1n;
|
|
361
396
|
const current = this.permitsInUse();
|
|
362
397
|
if (current > this.peakPermitsInUse) this.peakPermitsInUse = current;
|
|
363
398
|
if (evaluatePressure) this.evaluatePressure();
|
|
364
|
-
return new ApplicationJobQueuePermit(this);
|
|
399
|
+
return new ApplicationJobQueuePermit(this, origin);
|
|
365
400
|
}
|
|
366
401
|
|
|
367
402
|
private drainWaiters(): void {
|
|
@@ -371,7 +406,7 @@ export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
|
371
406
|
waiter.active = false;
|
|
372
407
|
waiter.signal?.removeEventListener('abort', waiter.abort);
|
|
373
408
|
this.recordCompletedWait(waiter);
|
|
374
|
-
waiter.resolve(this.reserve(false));
|
|
409
|
+
waiter.resolve(this.reserve(waiter.origin, false));
|
|
375
410
|
}
|
|
376
411
|
}
|
|
377
412
|
|
|
@@ -387,11 +422,43 @@ export class ApplicationJobQueue implements ApplicationJobQueuePort {
|
|
|
387
422
|
}
|
|
388
423
|
|
|
389
424
|
private recordCompletedWait(waiter: CapacityWaiter): void {
|
|
425
|
+
this.updateLocalWaiters(waiter.origin, -1);
|
|
390
426
|
if (waiter.metricsEpoch !== this.metricsEpoch) return;
|
|
391
427
|
const durationMs = Math.max(0, this.nowMs() - waiter.startedAtMs);
|
|
392
428
|
this.capacityWaitDurationSeconds += durationMs / MILLISECONDS_PER_SECOND;
|
|
393
429
|
}
|
|
394
430
|
|
|
431
|
+
private updateLocalWaiters(origin: ApplicationJobOrigin, delta: number): number | undefined {
|
|
432
|
+
if (origin !== 'local') return undefined;
|
|
433
|
+
this.localWaiters += delta;
|
|
434
|
+
if (this.localWaiters === 0) this.localBacklogLogged = false;
|
|
435
|
+
if (!this.localBacklogLogged && this.localWaiters > Number(this.limit())) {
|
|
436
|
+
this.localBacklogLogged = true;
|
|
437
|
+
return this.localWaiters;
|
|
438
|
+
}
|
|
439
|
+
return undefined;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private logLocalBacklog(localWaiters: number): void {
|
|
443
|
+
try {
|
|
444
|
+
telemetryLogger.emit({
|
|
445
|
+
eventName: 'zlink.runtime.host.local_job_backlog_exceeded',
|
|
446
|
+
timestamp: new Date(),
|
|
447
|
+
severityNumber: SeverityNumber.WARN,
|
|
448
|
+
severityText: 'WARN',
|
|
449
|
+
body: 'Same-host jobs waiting for a host permit exceeded the application job queue maximum.',
|
|
450
|
+
attributes: {
|
|
451
|
+
source_kind: 'host',
|
|
452
|
+
source_name: 'zlink.runtime.host',
|
|
453
|
+
local_waiters: localWaiters,
|
|
454
|
+
effective_maximum: Number(this.limit())
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
} catch (error) {
|
|
458
|
+
this.loggerFailureReporter?.(error);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
395
462
|
private evaluatePressure(): void {
|
|
396
463
|
const permitsInUse = this.permitsInUse();
|
|
397
464
|
const next =
|
|
@@ -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,
|
|
@@ -2235,6 +2246,9 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2235
2246
|
});
|
|
2236
2247
|
const coordinator = (this.userSpotCoordinator = new ZLinkUserSpotCreationCoordinator({
|
|
2237
2248
|
store: locationStore,
|
|
2249
|
+
relocationPolicy: (meshName, stableType) =>
|
|
2250
|
+
this.options.registration.spotNodes.get(meshName)?.spotFactoryRegistrations?.[stableType]
|
|
2251
|
+
?.relocation.kind,
|
|
2238
2252
|
publishReadyRoute: (meshName, route) => {
|
|
2239
2253
|
this.cachedLocationSpotRouteResolver?.invalidate?.(route.spot.spotId);
|
|
2240
2254
|
this.spotNodeRuntime?.meshNode(meshName)?.rememberSpotRoute?.(route);
|
|
@@ -2757,6 +2771,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2757
2771
|
},
|
|
2758
2772
|
meshRecordDispatcher: (meshName: string, owner: ReadyRecord, record: ReceiveRecord) =>
|
|
2759
2773
|
this.dispatchMeshRecord(
|
|
2774
|
+
currentApplicationJobOrigin,
|
|
2760
2775
|
meshName,
|
|
2761
2776
|
owner,
|
|
2762
2777
|
record,
|
|
@@ -2767,6 +2782,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2767
2782
|
}
|
|
2768
2783
|
|
|
2769
2784
|
private async dispatchMeshRecord(
|
|
2785
|
+
applicationJobOrigin: () => ApplicationJobOrigin,
|
|
2770
2786
|
meshName: string,
|
|
2771
2787
|
owner: ReadyRecord,
|
|
2772
2788
|
record: ReceiveRecord,
|
|
@@ -2968,7 +2984,7 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
2968
2984
|
);
|
|
2969
2985
|
}
|
|
2970
2986
|
return this.admission.run(meshName, 'RouteMesh Actor dispatch', () =>
|
|
2971
|
-
this.spotManager!.dispatchMeshActor(meshName, owner, record)
|
|
2987
|
+
this.spotManager!.dispatchMeshActor(applicationJobOrigin(), meshName, owner, record)
|
|
2972
2988
|
);
|
|
2973
2989
|
case ReceiveKind.SendReady:
|
|
2974
2990
|
return Promise.resolve();
|
|
@@ -3012,7 +3028,10 @@ export class ZLinkFrameworkRuntimeHost
|
|
|
3012
3028
|
try {
|
|
3013
3029
|
state.taskRunner.runDetached('mesh-node-local-route-dispatch', async () => {
|
|
3014
3030
|
try {
|
|
3015
|
-
const permit = await this.applicationJobQueue.acquire(
|
|
3031
|
+
const permit = await this.applicationJobQueue.acquire(
|
|
3032
|
+
state.abortController.signal,
|
|
3033
|
+
'local'
|
|
3034
|
+
);
|
|
3016
3035
|
permit.markApplicationQueued();
|
|
3017
3036
|
await runWithApplicationJobPermit(permit, () =>
|
|
3018
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,
|