@zlink-systems/framework 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Channels/IZLinkFanoutClient.d.ts +0 -6
- package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +1 -0
- package/dist/runtime/activation-admission.d.ts +29 -0
- package/dist/runtime/activation-admission.js +61 -0
- package/dist/runtime/actors/actor-context.js +6 -6
- package/dist/runtime/actors/actor-handoff.d.ts +9 -3
- package/dist/runtime/actors/actor-handoff.js +28 -17
- package/dist/runtime/actors/actor-local-native-join.js +2 -18
- package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
- package/dist/runtime/actors/actor-remote-joiner.js +6 -8
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
- package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
- package/dist/runtime/actors/deferred-join-completion.d.ts +14 -0
- package/dist/runtime/actors/deferred-join-completion.js +20 -0
- package/dist/runtime/actors/index.d.ts +1 -1
- package/dist/runtime/actors/index.js +15 -5
- package/dist/runtime/admission.d.ts +5 -1
- package/dist/runtime/admission.js +4 -0
- package/dist/runtime/backend/contracts/index.d.ts +2 -10
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -9
- package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +6 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +12 -28
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +1 -1
- package/dist/runtime/backend/node/node-event-loop-poller.js +8 -2
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +11 -3
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +12 -9
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +61 -29
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
- package/dist/runtime/backend/raw-binding-port.d.ts +12 -0
- package/dist/runtime/channels/channel-clients.d.ts +0 -1
- package/dist/runtime/channels/channel-clients.js +0 -8
- package/dist/runtime/channels/channel-outbound-operations.js +2 -10
- package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
- package/dist/runtime/channels/channel-runtime-manager.js +1 -12
- package/dist/runtime/channels/channel-socket-registry.d.ts +17 -4
- package/dist/runtime/channels/channel-socket-registry.js +49 -62
- package/dist/runtime/channels/channel-transports.d.ts +0 -3
- package/dist/runtime/channels/fanout-location-runtime.js +3 -9
- package/dist/runtime/execution/index.d.ts +18 -8
- package/dist/runtime/execution/index.js +55 -29
- package/dist/runtime/execution/serial-execution-queue.d.ts +5 -6
- package/dist/runtime/execution/serial-execution-queue.js +49 -15
- package/dist/runtime/foundation/listener-records.d.ts +11 -0
- package/dist/runtime/foundation/listener-records.js +20 -0
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +10 -21
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +66 -392
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +8 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +23 -2
- package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
- package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +16 -4
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +6 -13
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -7
- package/dist/runtime/foundation/service-stateful-runtime.js +100 -60
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +9 -4
- package/dist/runtime/foundation/service-stateful-wire-codec.js +153 -90
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -2
- package/dist/runtime/foundation/service-topology-registry.js +6 -30
- package/dist/runtime/host/actor-transfer-runtime.d.ts +17 -15
- package/dist/runtime/host/actor-transfer-runtime.js +73 -86
- package/dist/runtime/host/index.d.ts +6 -2
- package/dist/runtime/host/index.js +63 -37
- package/dist/runtime/host/remote-bound-session-relay.js +4 -3
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -0
- package/dist/runtime/host/route-mesh-runtime.js +7 -5
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +50 -8
- package/dist/runtime/host/service-relocation-host-runtime.js +343 -270
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +7 -4
- package/dist/runtime/host/spot-runtime-options-factory.js +4 -8
- package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +11 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +85 -87
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -6
- package/dist/runtime/locations/lifecycle.d.ts +1 -1
- package/dist/runtime/locations/lifecycle.js +2 -2
- package/dist/runtime/locations/resolvers.js +7 -2
- package/dist/runtime/locations/spot-location-claims.d.ts +2 -2
- package/dist/runtime/locations/spot-location-claims.js +3 -27
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +5 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +3 -3
- package/dist/runtime/spots/index.d.ts +25 -19
- package/dist/runtime/spots/index.js +207 -205
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +34 -31
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
- package/dist/runtime/spots/spot-activation-state.js +4 -17
- package/dist/runtime/spots/spot-activation.d.ts +8 -6
- package/dist/runtime/spots/spot-activation.js +54 -49
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +1 -1
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-join-dispatch.js +3 -5
- package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -0
- package/dist/runtime/spots/spot-actor-membership.js +26 -12
- package/dist/runtime/spots/spot-entry-activation.d.ts +1 -2
- package/dist/runtime/spots/spot-entry-activation.js +0 -1
- package/dist/runtime/spots/spot-manager-public.js +1 -1
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +1 -1
- package/dist/runtime/spots/spot-native-actor-join-admission.js +2 -2
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +5 -5
- package/dist/runtime/spots/spot-node-runtime-manager.js +7 -11
- package/dist/runtime/spots/spot-outbound.js +1 -29
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-actor-admission.js +10 -0
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -6
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +2 -70
- package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -5
- package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
- package/dist/runtime/spots/spot-serial-executor.js +8 -1
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
- package/dist/runtime/spots/spot-serial-turn-executor.js +8 -4
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +13 -15
- package/dist/runtime/streams/actor-session-binding-registry.js +19 -171
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +3 -4
- package/dist/runtime/streams/bound-session-service.js +1 -18
- package/dist/runtime/streams/index.d.ts +2 -0
- package/dist/runtime/streams/index.js +19 -19
- package/dist/runtime/streams/session-serial-executor.js +2 -2
- package/package.json +3 -3
- package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
- package/src/internal.ts +1 -0
- package/src/runtime/activation-admission.ts +78 -0
- package/src/runtime/actors/actor-context.ts +6 -6
- package/src/runtime/actors/actor-handoff.ts +31 -23
- package/src/runtime/actors/actor-local-native-join.ts +3 -42
- package/src/runtime/actors/actor-remote-joiner.ts +6 -25
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
- package/src/runtime/actors/actor-source-transfer.ts +5 -18
- package/src/runtime/actors/deferred-join-completion.ts +40 -0
- package/src/runtime/actors/index.ts +22 -9
- package/src/runtime/admission.ts +5 -1
- package/src/runtime/backend/contracts/index.ts +2 -13
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -10
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
- package/src/runtime/backend/node/node-backend-adapter-support.ts +9 -29
- package/src/runtime/backend/node/node-event-loop-poller.ts +14 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +17 -3
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +65 -32
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +2 -2
- package/src/runtime/backend/raw-binding-port.ts +13 -0
- package/src/runtime/channels/channel-clients.ts +0 -11
- package/src/runtime/channels/channel-outbound-operations.ts +3 -11
- package/src/runtime/channels/channel-runtime-manager.ts +4 -15
- package/src/runtime/channels/channel-socket-registry.ts +69 -71
- package/src/runtime/channels/channel-transports.ts +0 -3
- package/src/runtime/channels/fanout-location-runtime.ts +4 -16
- package/src/runtime/execution/index.ts +68 -30
- package/src/runtime/execution/serial-execution-queue.ts +52 -20
- package/src/runtime/foundation/listener-records.ts +21 -0
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +66 -466
- package/src/runtime/foundation/service-authority-payload-codec.ts +10 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +30 -9
- package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
- package/src/runtime/foundation/service-relocation-object-owner.ts +18 -5
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +6 -14
- package/src/runtime/foundation/service-stateful-runtime.ts +151 -89
- package/src/runtime/foundation/service-stateful-wire-codec.ts +203 -121
- package/src/runtime/foundation/service-topology-registry.ts +8 -48
- package/src/runtime/host/actor-transfer-runtime.ts +94 -166
- package/src/runtime/host/index.ts +119 -54
- package/src/runtime/host/remote-bound-session-relay.ts +4 -3
- package/src/runtime/host/route-mesh-runtime.ts +9 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +495 -376
- package/src/runtime/host/spot-runtime-options-factory.ts +24 -13
- package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
- package/src/runtime/host/user-spot-creation-coordinator.ts +147 -142
- package/src/runtime/locations/in-memory-provider-location-store.ts +11 -7
- package/src/runtime/locations/lifecycle.ts +3 -2
- package/src/runtime/locations/resolvers.ts +19 -13
- package/src/runtime/locations/spot-location-claims.ts +5 -34
- package/src/runtime/protocol/service_wire_codec.generated.ts +9 -2
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +3 -3
- package/src/runtime/spots/index.ts +341 -295
- package/src/runtime/spots/spot-activation-registry.ts +41 -31
- package/src/runtime/spots/spot-activation-state.ts +4 -16
- package/src/runtime/spots/spot-activation.ts +102 -80
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +2 -2
- package/src/runtime/spots/spot-actor-join-dispatch.ts +6 -7
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
- package/src/runtime/spots/spot-actor-membership.ts +81 -17
- package/src/runtime/spots/spot-entry-activation.ts +0 -3
- package/src/runtime/spots/spot-manager-public.ts +8 -4
- package/src/runtime/spots/spot-native-actor-join-admission.ts +2 -2
- package/src/runtime/spots/spot-node-runtime-manager.ts +12 -18
- package/src/runtime/spots/spot-outbound.ts +4 -47
- package/src/runtime/spots/spot-routed-actor-admission.ts +20 -0
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -76
- package/src/runtime/spots/spot-runtime-ports.ts +6 -17
- package/src/runtime/spots/spot-serial-executor.ts +9 -1
- package/src/runtime/spots/spot-serial-turn-executor.ts +10 -4
- package/src/runtime/streams/actor-session-binding-registry.ts +20 -308
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +2 -12
- package/src/runtime/streams/bound-session-service.ts +2 -36
- package/src/runtime/streams/index.ts +29 -27
- package/src/runtime/streams/session-serial-executor.ts +2 -2
- package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
- package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
- package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
|
@@ -4,12 +4,11 @@ import type {
|
|
|
4
4
|
RoutingId,
|
|
5
5
|
ZLinkActor,
|
|
6
6
|
ZLinkActorJoinOperationId,
|
|
7
|
-
ZLinkMessage,
|
|
8
7
|
ZLinkMessageSerializer,
|
|
9
|
-
ZLinkRelocationStore,
|
|
10
8
|
ZLinkSpot
|
|
11
9
|
} from '../../contracts';
|
|
12
|
-
import { ZLinkSpotKind } from '../../contracts';
|
|
10
|
+
import { ZLinkEncodedPayload, ZLinkMessage, ZLinkSpotKind } from '../../contracts';
|
|
11
|
+
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
13
12
|
import type {
|
|
14
13
|
ZLinkAggregateId,
|
|
15
14
|
ZLinkAuthoritySnapshot,
|
|
@@ -33,11 +32,9 @@ import {
|
|
|
33
32
|
type ZLinkActorHandoffReplayPreparation,
|
|
34
33
|
type ZLinkActorRoutedJoinTransport,
|
|
35
34
|
type ZLinkActorTransferRegistry,
|
|
36
|
-
|
|
37
|
-
ZLinkDeferredJoinAcceptedJournal,
|
|
35
|
+
createDeferredJoinCompletion,
|
|
38
36
|
rewriteActorAuthorityRoute,
|
|
39
|
-
type
|
|
40
|
-
type ZLinkDeferredJoinRootIdentity,
|
|
37
|
+
type ZLinkDeferredJoinCompletion,
|
|
41
38
|
type ZLinkRemoteBoundSessionTarget
|
|
42
39
|
} from '../actors';
|
|
43
40
|
import type { ZLinkActorRuntimeState } from '../actors/actor-runtime-state';
|
|
@@ -198,7 +195,6 @@ export interface ZLinkActorTransferRuntimeOptions {
|
|
|
198
195
|
readonly authorityStore: () =>
|
|
199
196
|
(ZLinkAuthorityStore & ZLinkObjectCreationStore & ZLinkOwnerLeaseStore) | undefined;
|
|
200
197
|
readonly currentOwner: () => ZLinkLocationOwnerToken | undefined;
|
|
201
|
-
readonly relocationStore: () => ZLinkRelocationStore | undefined;
|
|
202
198
|
/** Live admitted peers of a mesh; used to stop retries against a gone session owner. */
|
|
203
199
|
readonly liveDescriptors?: (
|
|
204
200
|
meshName: string,
|
|
@@ -229,43 +225,31 @@ export class ZLinkActorTransferRuntime {
|
|
|
229
225
|
notifySubmitted?: () => Promise<void>;
|
|
230
226
|
}
|
|
231
227
|
>();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
>(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
ZLinkDeferredJoinAcceptedRoot
|
|
239
|
-
>(DEFERRED_JOIN_TERMINAL_CAPACITY);
|
|
228
|
+
// Spot Actor membership sections 4-5: Join completion idempotency is
|
|
229
|
+
// process-local. These maps end with the process; nothing is replayed.
|
|
230
|
+
private readonly activeDeferredJoinTerminals = new Map<string, Promise<void>>();
|
|
231
|
+
private readonly deferredJoinTerminals = new BoundedReplayMap<string, true>(
|
|
232
|
+
DEFERRED_JOIN_TERMINAL_CAPACITY
|
|
233
|
+
);
|
|
240
234
|
|
|
241
235
|
constructor(private readonly options: ZLinkActorTransferRuntimeOptions) {}
|
|
242
236
|
|
|
243
|
-
beginDeferredActorHandoff(
|
|
244
|
-
actor: ZLinkActor,
|
|
245
|
-
state: ZLinkActorRuntimeState,
|
|
246
|
-
operationId: string
|
|
247
|
-
): void {
|
|
237
|
+
beginDeferredActorHandoff(actor: ZLinkActor, state: ZLinkActorRuntimeState): void {
|
|
248
238
|
const actorId = actor.context.actorId;
|
|
249
239
|
this.options.actorHandoff.beginProvisional(
|
|
250
240
|
actorId,
|
|
251
|
-
operationId,
|
|
252
241
|
requireSourceObjectGeneration(actorId, state)
|
|
253
242
|
);
|
|
254
243
|
}
|
|
255
244
|
|
|
256
|
-
promoteDeferredActorHandoff(
|
|
257
|
-
actor
|
|
258
|
-
_state: ZLinkActorRuntimeState,
|
|
259
|
-
operationId: string
|
|
260
|
-
): void {
|
|
261
|
-
this.options.actorHandoff.promoteProvisional(actor.context.actorId, operationId);
|
|
245
|
+
promoteDeferredActorHandoff(actor: ZLinkActor, _state: ZLinkActorRuntimeState): void {
|
|
246
|
+
this.options.actorHandoff.promoteProvisional(actor.context.actorId);
|
|
262
247
|
}
|
|
263
248
|
|
|
264
249
|
async completeDeferredActorHandoff(
|
|
265
250
|
actor: ZLinkActor,
|
|
266
251
|
target: ZLinkSpotRouteTarget,
|
|
267
|
-
_targetActorRef: ActorRef
|
|
268
|
-
operationId: string
|
|
252
|
+
_targetActorRef: ActorRef
|
|
269
253
|
): Promise<void> {
|
|
270
254
|
const actorId = actor.context.actorId;
|
|
271
255
|
if (!this.options.actorHandoff.isProvisional(actorId)) return;
|
|
@@ -275,7 +259,6 @@ export class ZLinkActorTransferRuntime {
|
|
|
275
259
|
}
|
|
276
260
|
const admitted = this.options.actorHandoff.admitDeferredPrefix(
|
|
277
261
|
actorId,
|
|
278
|
-
operationId,
|
|
279
262
|
(drain) => manager.admitRoutedActorPacketPrefix(target.spotId, actorId, drain),
|
|
280
263
|
this.options.prepareApplicationJob
|
|
281
264
|
);
|
|
@@ -284,110 +267,70 @@ export class ZLinkActorTransferRuntime {
|
|
|
284
267
|
|
|
285
268
|
async cancelDeferredActorHandoff(
|
|
286
269
|
actor: ZLinkActor,
|
|
287
|
-
|
|
288
|
-
operationId: string
|
|
270
|
+
state: ZLinkActorRuntimeState
|
|
289
271
|
): Promise<void> {
|
|
290
|
-
const admitted = this.admitDeferredSourcePrefix(actor,
|
|
272
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state);
|
|
291
273
|
void this.observeHandoffReplay(admitted.terminal);
|
|
292
274
|
}
|
|
293
275
|
|
|
294
|
-
|
|
276
|
+
prepareDeferredJoinAccepted(
|
|
295
277
|
actorId: string,
|
|
296
278
|
operationId: ZLinkActorJoinOperationId,
|
|
297
279
|
actorRef: ActorRef,
|
|
298
280
|
rawReply: Uint8Array,
|
|
299
|
-
replyContentType?: string
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
): Promise<ZLinkDeferredJoinAcceptedRoot> {
|
|
303
|
-
return await this.requireDeferredJoinJournal().prepare(
|
|
304
|
-
actorId,
|
|
305
|
-
operationId,
|
|
306
|
-
actorRef,
|
|
307
|
-
rawReply,
|
|
308
|
-
replyContentType,
|
|
309
|
-
signal,
|
|
310
|
-
canonicalInventoryDigest
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
async isDeferredJoinAcceptedRootPublication(
|
|
315
|
-
reference: string,
|
|
316
|
-
checksumCrc32c: number,
|
|
317
|
-
expected: ZLinkDeferredJoinRootIdentity,
|
|
318
|
-
signal?: AbortSignal
|
|
319
|
-
): Promise<boolean> {
|
|
320
|
-
const relocation = this.options.relocationStore();
|
|
321
|
-
return relocation === undefined
|
|
322
|
-
? false
|
|
323
|
-
: await isDeferredJoinAcceptedRootPublication(
|
|
324
|
-
relocation,
|
|
325
|
-
reference,
|
|
326
|
-
checksumCrc32c,
|
|
327
|
-
expected,
|
|
328
|
-
signal
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
async discardDeferredJoinAccepted(
|
|
333
|
-
root: ZLinkDeferredJoinAcceptedRoot,
|
|
334
|
-
signal?: AbortSignal
|
|
335
|
-
): Promise<void> {
|
|
336
|
-
await this.requireDeferredJoinJournal().discardPrepared(root, signal);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
markDeferredJoinAcceptedCommitted(
|
|
340
|
-
root: ZLinkDeferredJoinAcceptedRoot,
|
|
341
|
-
actorRef: ActorRef,
|
|
342
|
-
signal?: AbortSignal
|
|
343
|
-
): Promise<ZLinkDeferredJoinAcceptedRoot> {
|
|
344
|
-
return this.requireDeferredJoinJournal().markCommitted(root, actorRef, signal);
|
|
281
|
+
replyContentType?: string
|
|
282
|
+
): ZLinkDeferredJoinCompletion {
|
|
283
|
+
return createDeferredJoinCompletion(actorId, operationId, actorRef, rawReply, replyContentType);
|
|
345
284
|
}
|
|
346
285
|
|
|
347
|
-
|
|
348
|
-
|
|
286
|
+
/**
|
|
287
|
+
* Runs the Accepted completion callback once in the target Actor mailbox.
|
|
288
|
+
* A repeated delivery of the same OperationId in this process observes the
|
|
289
|
+
* first terminal (completion idempotency only).
|
|
290
|
+
*/
|
|
291
|
+
async deliverDeferredJoinAccepted(
|
|
292
|
+
completion: ZLinkDeferredJoinCompletion,
|
|
349
293
|
actor: ZLinkActor,
|
|
350
294
|
actorRef: ActorRef,
|
|
351
295
|
submitMailbox: <T>(operation: () => Promise<T>) => Promise<T>,
|
|
352
296
|
signal?: AbortSignal
|
|
353
|
-
): Promise<
|
|
354
|
-
const terminalKey = deferredJoinTerminalKey(
|
|
355
|
-
|
|
356
|
-
if (terminal !== undefined) {
|
|
297
|
+
): Promise<void> {
|
|
298
|
+
const terminalKey = deferredJoinTerminalKey(completion);
|
|
299
|
+
if (this.deferredJoinTerminals.get(terminalKey) !== undefined) {
|
|
357
300
|
this.deferredJoinTerminals.touch(terminalKey);
|
|
358
|
-
return
|
|
301
|
+
return;
|
|
359
302
|
}
|
|
360
303
|
const active = this.activeDeferredJoinTerminals.get(terminalKey);
|
|
361
304
|
if (active !== undefined) return await waitForOperation(active, signal);
|
|
362
|
-
const
|
|
363
|
-
|
|
305
|
+
const delivery = this.deliverDeferredJoinAcceptedCore(
|
|
306
|
+
completion,
|
|
364
307
|
actor,
|
|
365
308
|
actorRef,
|
|
366
309
|
submitMailbox
|
|
367
310
|
);
|
|
368
|
-
this.activeDeferredJoinTerminals.set(terminalKey,
|
|
369
|
-
void
|
|
370
|
-
(
|
|
371
|
-
this.deferredJoinTerminals.remember(terminalKey,
|
|
372
|
-
if (this.activeDeferredJoinTerminals.get(terminalKey) ===
|
|
311
|
+
this.activeDeferredJoinTerminals.set(terminalKey, delivery);
|
|
312
|
+
void delivery.then(
|
|
313
|
+
() => {
|
|
314
|
+
this.deferredJoinTerminals.remember(terminalKey, true);
|
|
315
|
+
if (this.activeDeferredJoinTerminals.get(terminalKey) === delivery) {
|
|
373
316
|
this.activeDeferredJoinTerminals.delete(terminalKey);
|
|
374
317
|
}
|
|
375
318
|
},
|
|
376
319
|
() => {
|
|
377
|
-
if (this.activeDeferredJoinTerminals.get(terminalKey) ===
|
|
320
|
+
if (this.activeDeferredJoinTerminals.get(terminalKey) === delivery) {
|
|
378
321
|
this.activeDeferredJoinTerminals.delete(terminalKey);
|
|
379
322
|
}
|
|
380
323
|
}
|
|
381
324
|
);
|
|
382
|
-
return await waitForOperation(
|
|
325
|
+
return await waitForOperation(delivery, signal);
|
|
383
326
|
}
|
|
384
327
|
|
|
385
|
-
private async
|
|
386
|
-
|
|
328
|
+
private async deliverDeferredJoinAcceptedCore(
|
|
329
|
+
completion: ZLinkDeferredJoinCompletion,
|
|
387
330
|
actor: ZLinkActor,
|
|
388
331
|
actorRef: ActorRef,
|
|
389
332
|
submitMailbox: <T>(operation: () => Promise<T>) => Promise<T>
|
|
390
|
-
): Promise<
|
|
333
|
+
): Promise<void> {
|
|
391
334
|
const targetActorRef = this.options
|
|
392
335
|
.actorManager()
|
|
393
336
|
?.getState(actor.context.actorId)?.nativeActorRef;
|
|
@@ -395,47 +338,35 @@ export class ZLinkActorTransferRuntime {
|
|
|
395
338
|
targetActorRef === undefined
|
|
396
339
|
? actorRef
|
|
397
340
|
: toFrameworkActorRef(targetActorRef, actor.context.meshName);
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
current,
|
|
408
|
-
actor,
|
|
409
|
-
currentActorRef,
|
|
410
|
-
submitMailbox
|
|
411
|
-
);
|
|
412
|
-
return current;
|
|
413
|
-
} catch (error) {
|
|
414
|
-
lastError = error;
|
|
415
|
-
if (attempt < 2) {
|
|
416
|
-
await new Promise<void>((resolve) => {
|
|
417
|
-
const timer = setTimeout(resolve, 10 << attempt);
|
|
418
|
-
timer.unref();
|
|
419
|
-
});
|
|
420
|
-
current =
|
|
421
|
-
(await this.requireDeferredJoinJournal().recover(currentActorRef.actorId)) ?? current;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
throw lastError;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
private requireDeferredJoinJournal(): ZLinkDeferredJoinAcceptedJournal {
|
|
429
|
-
const authority = this.options.authorityStore();
|
|
430
|
-
const relocation = this.options.relocationStore();
|
|
431
|
-
if (authority === undefined || relocation === undefined) {
|
|
432
|
-
throw new Error('Cross-node deferred Actor Join requires Location and Relocation Stores.');
|
|
341
|
+
if (
|
|
342
|
+
completion.actor.actorId !== currentActorRef.actorId ||
|
|
343
|
+
completion.actor.objectGeneration !== currentActorRef.objectGeneration
|
|
344
|
+
) {
|
|
345
|
+
throw new Error(
|
|
346
|
+
'Deferred Join completion generation fence is stale ' +
|
|
347
|
+
`(completion ${completion.actor.actorId}/${completion.actor.objectGeneration}, ` +
|
|
348
|
+
`actor ${currentActorRef.actorId}/${currentActorRef.objectGeneration}).`
|
|
349
|
+
);
|
|
433
350
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
351
|
+
await submitMailbox(async () => {
|
|
352
|
+
await actor.onJoinCompleted?.({
|
|
353
|
+
status: 'accepted',
|
|
354
|
+
operationId: completion.operationId,
|
|
355
|
+
actor: currentActorRef,
|
|
356
|
+
reply:
|
|
357
|
+
completion.rawReply.byteLength === 0
|
|
358
|
+
? undefined
|
|
359
|
+
: completion.replyContentType === undefined
|
|
360
|
+
? ZLinkMessage.fromEncoded(ZLinkEncodedPayload.from(completion.rawReply))
|
|
361
|
+
: wrapFrameworkPayloadMessage(
|
|
362
|
+
RuntimeMessage.from(completion.rawReply),
|
|
363
|
+
this.options.messageSerializers,
|
|
364
|
+
completion.replyContentType,
|
|
365
|
+
undefined,
|
|
366
|
+
'reply'
|
|
367
|
+
)
|
|
368
|
+
});
|
|
369
|
+
});
|
|
439
370
|
}
|
|
440
371
|
|
|
441
372
|
private async prepareSourceActorLeave(
|
|
@@ -471,13 +402,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
471
402
|
private async beginSourceActorMove(
|
|
472
403
|
actor: ZLinkActor,
|
|
473
404
|
state: ZLinkActorRuntimeState,
|
|
474
|
-
|
|
405
|
+
deferredJoin = false
|
|
475
406
|
): Promise<void> {
|
|
476
|
-
if (
|
|
477
|
-
|
|
478
|
-
this.options.actorHandoff.isProvisional(actor.context.actorId)
|
|
479
|
-
) {
|
|
480
|
-
this.promoteDeferredActorHandoff(actor, state, deferredOperationId);
|
|
407
|
+
if (deferredJoin && this.options.actorHandoff.isProvisional(actor.context.actorId)) {
|
|
408
|
+
this.promoteDeferredActorHandoff(actor, state);
|
|
481
409
|
}
|
|
482
410
|
state.beginMove();
|
|
483
411
|
if (!this.options.actorHandoff.isActive(actor.context.actorId)) {
|
|
@@ -499,10 +427,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
499
427
|
});
|
|
500
428
|
}
|
|
501
429
|
} catch (error) {
|
|
502
|
-
if (
|
|
430
|
+
if (!deferredJoin) {
|
|
503
431
|
this.options.actorHandoff.cancel(actor.context.actorId);
|
|
504
432
|
} else {
|
|
505
|
-
const admitted = this.admitDeferredSourcePrefix(actor, state
|
|
433
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state);
|
|
506
434
|
void this.observeHandoffReplay(admitted.terminal);
|
|
507
435
|
}
|
|
508
436
|
state.endMove();
|
|
@@ -513,7 +441,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
513
441
|
private async cancelSourceActorMove(
|
|
514
442
|
actor: ZLinkActor,
|
|
515
443
|
state: ZLinkActorRuntimeState,
|
|
516
|
-
|
|
444
|
+
deferredJoin = false,
|
|
517
445
|
replayStart: Promise<void> = Promise.resolve()
|
|
518
446
|
): Promise<void> {
|
|
519
447
|
try {
|
|
@@ -522,16 +450,11 @@ export class ZLinkActorTransferRuntime {
|
|
|
522
450
|
}
|
|
523
451
|
} finally {
|
|
524
452
|
try {
|
|
525
|
-
if (
|
|
453
|
+
if (!deferredJoin) {
|
|
526
454
|
const admitted = this.admitCanceledSourcePrefix(actor, state, replayStart);
|
|
527
455
|
void this.observeHandoffReplay(admitted.terminal);
|
|
528
456
|
} else {
|
|
529
|
-
const admitted = this.admitDeferredSourcePrefix(
|
|
530
|
-
actor,
|
|
531
|
-
state,
|
|
532
|
-
deferredOperationId,
|
|
533
|
-
replayStart
|
|
534
|
-
);
|
|
457
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state, replayStart);
|
|
535
458
|
void this.observeHandoffReplay(admitted.terminal);
|
|
536
459
|
}
|
|
537
460
|
} finally {
|
|
@@ -564,7 +487,6 @@ export class ZLinkActorTransferRuntime {
|
|
|
564
487
|
private admitDeferredSourcePrefix(
|
|
565
488
|
actor: ZLinkActor,
|
|
566
489
|
state: ZLinkActorRuntimeState,
|
|
567
|
-
operationId: string,
|
|
568
490
|
replayStart: Promise<void> = Promise.resolve()
|
|
569
491
|
): ZLinkActorHandoffPrefixAdmission {
|
|
570
492
|
const queue = this.sourceHandoffPrefixQueue(actor, state);
|
|
@@ -574,7 +496,6 @@ export class ZLinkActorTransferRuntime {
|
|
|
574
496
|
}
|
|
575
497
|
return this.options.actorHandoff.admitDeferredPrefix(
|
|
576
498
|
actor.context.actorId,
|
|
577
|
-
operationId,
|
|
578
499
|
queue,
|
|
579
500
|
this.options.prepareApplicationJob,
|
|
580
501
|
replayStart
|
|
@@ -614,10 +535,10 @@ export class ZLinkActorTransferRuntime {
|
|
|
614
535
|
state: ZLinkActorRuntimeState,
|
|
615
536
|
signal?: AbortSignal,
|
|
616
537
|
lifecycleAuthority: 'framework' | 'core' = 'framework',
|
|
617
|
-
|
|
538
|
+
deferredJoin = false,
|
|
618
539
|
relocation?: ServiceWireOperationId
|
|
619
540
|
) {
|
|
620
|
-
await this.beginSourceActorMove(actor, state,
|
|
541
|
+
await this.beginSourceActorMove(actor, state, deferredJoin);
|
|
621
542
|
const relocationMetric =
|
|
622
543
|
state.meshName === undefined
|
|
623
544
|
? undefined
|
|
@@ -762,7 +683,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
762
683
|
this.coreSourceLeaves.delete(actor.context.actorId);
|
|
763
684
|
const replayGate = createHandoffReplayGate();
|
|
764
685
|
try {
|
|
765
|
-
await this.cancelSourceActorMove(actor, state,
|
|
686
|
+
await this.cancelSourceActorMove(actor, state, deferredJoin, replayGate.start);
|
|
766
687
|
await this.restoreSourceActor(actor, sourceSpotId);
|
|
767
688
|
if (sealId !== undefined) {
|
|
768
689
|
await this.observeBoundSessionSealAbort(actor, state);
|
|
@@ -776,7 +697,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
776
697
|
relocationMetric?.complete('failed');
|
|
777
698
|
const replayGate = createHandoffReplayGate();
|
|
778
699
|
try {
|
|
779
|
-
await this.cancelSourceActorMove(actor, state,
|
|
700
|
+
await this.cancelSourceActorMove(actor, state, deferredJoin, replayGate.start);
|
|
780
701
|
if (sourceLeaveStarted) await this.restoreSourceActor(actor, sourceSpotId);
|
|
781
702
|
if (sealId !== undefined) {
|
|
782
703
|
await this.observeBoundSessionSealAbort(actor, state);
|
|
@@ -810,6 +731,7 @@ export class ZLinkActorTransferRuntime {
|
|
|
810
731
|
targetOwnerFence: ZLinkActorMessageFollowOwnerFence
|
|
811
732
|
): Promise<void>;
|
|
812
733
|
rollback(): Promise<void>;
|
|
734
|
+
discard(reason: unknown): void;
|
|
813
735
|
}> {
|
|
814
736
|
relocationDebug('maintenance_session.begin', {
|
|
815
737
|
actorId: actor.context.actorId,
|
|
@@ -866,6 +788,11 @@ export class ZLinkActorTransferRuntime {
|
|
|
866
788
|
terminal = 'committed';
|
|
867
789
|
}
|
|
868
790
|
},
|
|
791
|
+
discard: (reason) => {
|
|
792
|
+
if (terminal !== 'prepared') return;
|
|
793
|
+
terminal = 'rolledBack';
|
|
794
|
+
this.options.actorHandoff.failPending(actor.context.actorId, reason);
|
|
795
|
+
},
|
|
869
796
|
rollback: async () => {
|
|
870
797
|
if (terminal !== 'prepared') return;
|
|
871
798
|
terminal = 'rolledBack';
|
|
@@ -1870,7 +1797,8 @@ export class ZLinkActorTransferRuntime {
|
|
|
1870
1797
|
previousAuthorityOwnerGeneration: target.previousAuthorityOwnerGeneration,
|
|
1871
1798
|
targetAuthorityOwnerGeneration: ownershipGeneration,
|
|
1872
1799
|
targetNodeRid: String(actorRef.nodeRid),
|
|
1873
|
-
targetNodeGeneration: authority.allocation.descriptorLifecycleGeneration
|
|
1800
|
+
targetNodeGeneration: authority.allocation.descriptorLifecycleGeneration,
|
|
1801
|
+
targetOwnerLeaseGeneration: authority.ownerLeaseGeneration
|
|
1874
1802
|
}
|
|
1875
1803
|
},
|
|
1876
1804
|
this.options.shutdownSignal?.()
|
|
@@ -1885,10 +1813,10 @@ function relocationDebug(marker: string, detail: Record<string, unknown>): void
|
|
|
1885
1813
|
console.error('[zlink.runtime.relocation]', marker, detail);
|
|
1886
1814
|
}
|
|
1887
1815
|
|
|
1888
|
-
function deferredJoinTerminalKey(
|
|
1816
|
+
function deferredJoinTerminalKey(completion: ZLinkDeferredJoinCompletion): string {
|
|
1889
1817
|
return (
|
|
1890
|
-
`${
|
|
1891
|
-
operationIdentityKey(
|
|
1818
|
+
`${completion.actor.actorId}:${completion.actor.objectGeneration.toString()}:` +
|
|
1819
|
+
operationIdentityKey(completion.operationId)
|
|
1892
1820
|
);
|
|
1893
1821
|
}
|
|
1894
1822
|
|