@zlink-systems/framework 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Channels/IZLinkFanoutClient.d.ts +0 -6
- package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +1 -0
- package/dist/runtime/activation-admission.d.ts +29 -0
- package/dist/runtime/activation-admission.js +61 -0
- package/dist/runtime/actors/actor-context.js +6 -6
- package/dist/runtime/actors/actor-handoff.d.ts +9 -3
- package/dist/runtime/actors/actor-handoff.js +28 -17
- package/dist/runtime/actors/actor-local-native-join.js +2 -18
- package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
- package/dist/runtime/actors/actor-remote-joiner.js +6 -8
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
- package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
- package/dist/runtime/actors/deferred-join-completion.d.ts +14 -0
- package/dist/runtime/actors/deferred-join-completion.js +20 -0
- package/dist/runtime/actors/index.d.ts +1 -1
- package/dist/runtime/actors/index.js +15 -5
- package/dist/runtime/admission.d.ts +5 -1
- package/dist/runtime/admission.js +4 -0
- package/dist/runtime/backend/contracts/index.d.ts +2 -10
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -9
- package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +6 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +12 -28
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +1 -1
- package/dist/runtime/backend/node/node-event-loop-poller.js +8 -2
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +11 -3
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +12 -9
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +61 -29
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
- package/dist/runtime/backend/raw-binding-port.d.ts +12 -0
- package/dist/runtime/channels/channel-clients.d.ts +0 -1
- package/dist/runtime/channels/channel-clients.js +0 -8
- package/dist/runtime/channels/channel-outbound-operations.js +2 -10
- package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
- package/dist/runtime/channels/channel-runtime-manager.js +1 -12
- package/dist/runtime/channels/channel-socket-registry.d.ts +17 -4
- package/dist/runtime/channels/channel-socket-registry.js +49 -62
- package/dist/runtime/channels/channel-transports.d.ts +0 -3
- package/dist/runtime/channels/fanout-location-runtime.js +3 -9
- package/dist/runtime/execution/index.d.ts +18 -8
- package/dist/runtime/execution/index.js +55 -29
- package/dist/runtime/execution/serial-execution-queue.d.ts +5 -6
- package/dist/runtime/execution/serial-execution-queue.js +49 -15
- package/dist/runtime/foundation/listener-records.d.ts +11 -0
- package/dist/runtime/foundation/listener-records.js +20 -0
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +10 -21
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +66 -392
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +8 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +23 -2
- package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
- package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +16 -4
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +6 -13
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -7
- package/dist/runtime/foundation/service-stateful-runtime.js +100 -60
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +9 -4
- package/dist/runtime/foundation/service-stateful-wire-codec.js +153 -90
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -2
- package/dist/runtime/foundation/service-topology-registry.js +6 -30
- package/dist/runtime/host/actor-transfer-runtime.d.ts +17 -15
- package/dist/runtime/host/actor-transfer-runtime.js +73 -86
- package/dist/runtime/host/index.d.ts +6 -2
- package/dist/runtime/host/index.js +63 -37
- package/dist/runtime/host/remote-bound-session-relay.js +4 -3
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -0
- package/dist/runtime/host/route-mesh-runtime.js +7 -5
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +50 -8
- package/dist/runtime/host/service-relocation-host-runtime.js +343 -270
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +7 -4
- package/dist/runtime/host/spot-runtime-options-factory.js +4 -8
- package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +11 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +85 -87
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -6
- package/dist/runtime/locations/lifecycle.d.ts +1 -1
- package/dist/runtime/locations/lifecycle.js +2 -2
- package/dist/runtime/locations/resolvers.js +7 -2
- package/dist/runtime/locations/spot-location-claims.d.ts +2 -2
- package/dist/runtime/locations/spot-location-claims.js +3 -27
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +5 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +3 -3
- package/dist/runtime/spots/index.d.ts +25 -19
- package/dist/runtime/spots/index.js +207 -205
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +34 -31
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
- package/dist/runtime/spots/spot-activation-state.js +4 -17
- package/dist/runtime/spots/spot-activation.d.ts +8 -6
- package/dist/runtime/spots/spot-activation.js +54 -49
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +1 -1
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-join-dispatch.js +3 -5
- package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -0
- package/dist/runtime/spots/spot-actor-membership.js +26 -12
- package/dist/runtime/spots/spot-entry-activation.d.ts +1 -2
- package/dist/runtime/spots/spot-entry-activation.js +0 -1
- package/dist/runtime/spots/spot-manager-public.js +1 -1
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +1 -1
- package/dist/runtime/spots/spot-native-actor-join-admission.js +2 -2
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +5 -5
- package/dist/runtime/spots/spot-node-runtime-manager.js +7 -11
- package/dist/runtime/spots/spot-outbound.js +1 -29
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-actor-admission.js +10 -0
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -6
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +2 -70
- package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -5
- package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
- package/dist/runtime/spots/spot-serial-executor.js +8 -1
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
- package/dist/runtime/spots/spot-serial-turn-executor.js +8 -4
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +13 -15
- package/dist/runtime/streams/actor-session-binding-registry.js +19 -171
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +3 -4
- package/dist/runtime/streams/bound-session-service.js +1 -18
- package/dist/runtime/streams/index.d.ts +2 -0
- package/dist/runtime/streams/index.js +19 -19
- package/dist/runtime/streams/session-serial-executor.js +2 -2
- package/package.json +3 -3
- package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
- package/src/internal.ts +1 -0
- package/src/runtime/activation-admission.ts +78 -0
- package/src/runtime/actors/actor-context.ts +6 -6
- package/src/runtime/actors/actor-handoff.ts +31 -23
- package/src/runtime/actors/actor-local-native-join.ts +3 -42
- package/src/runtime/actors/actor-remote-joiner.ts +6 -25
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
- package/src/runtime/actors/actor-source-transfer.ts +5 -18
- package/src/runtime/actors/deferred-join-completion.ts +40 -0
- package/src/runtime/actors/index.ts +22 -9
- package/src/runtime/admission.ts +5 -1
- package/src/runtime/backend/contracts/index.ts +2 -13
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -10
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
- package/src/runtime/backend/node/node-backend-adapter-support.ts +9 -29
- package/src/runtime/backend/node/node-event-loop-poller.ts +14 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +17 -3
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +65 -32
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +2 -2
- package/src/runtime/backend/raw-binding-port.ts +13 -0
- package/src/runtime/channels/channel-clients.ts +0 -11
- package/src/runtime/channels/channel-outbound-operations.ts +3 -11
- package/src/runtime/channels/channel-runtime-manager.ts +4 -15
- package/src/runtime/channels/channel-socket-registry.ts +69 -71
- package/src/runtime/channels/channel-transports.ts +0 -3
- package/src/runtime/channels/fanout-location-runtime.ts +4 -16
- package/src/runtime/execution/index.ts +68 -30
- package/src/runtime/execution/serial-execution-queue.ts +52 -20
- package/src/runtime/foundation/listener-records.ts +21 -0
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +66 -466
- package/src/runtime/foundation/service-authority-payload-codec.ts +10 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +30 -9
- package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
- package/src/runtime/foundation/service-relocation-object-owner.ts +18 -5
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +6 -14
- package/src/runtime/foundation/service-stateful-runtime.ts +151 -89
- package/src/runtime/foundation/service-stateful-wire-codec.ts +203 -121
- package/src/runtime/foundation/service-topology-registry.ts +8 -48
- package/src/runtime/host/actor-transfer-runtime.ts +94 -166
- package/src/runtime/host/index.ts +119 -54
- package/src/runtime/host/remote-bound-session-relay.ts +4 -3
- package/src/runtime/host/route-mesh-runtime.ts +9 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +495 -376
- package/src/runtime/host/spot-runtime-options-factory.ts +24 -13
- package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
- package/src/runtime/host/user-spot-creation-coordinator.ts +147 -142
- package/src/runtime/locations/in-memory-provider-location-store.ts +11 -7
- package/src/runtime/locations/lifecycle.ts +3 -2
- package/src/runtime/locations/resolvers.ts +19 -13
- package/src/runtime/locations/spot-location-claims.ts +5 -34
- package/src/runtime/protocol/service_wire_codec.generated.ts +9 -2
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +3 -3
- package/src/runtime/spots/index.ts +341 -295
- package/src/runtime/spots/spot-activation-registry.ts +41 -31
- package/src/runtime/spots/spot-activation-state.ts +4 -16
- package/src/runtime/spots/spot-activation.ts +102 -80
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +2 -2
- package/src/runtime/spots/spot-actor-join-dispatch.ts +6 -7
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
- package/src/runtime/spots/spot-actor-membership.ts +81 -17
- package/src/runtime/spots/spot-entry-activation.ts +0 -3
- package/src/runtime/spots/spot-manager-public.ts +8 -4
- package/src/runtime/spots/spot-native-actor-join-admission.ts +2 -2
- package/src/runtime/spots/spot-node-runtime-manager.ts +12 -18
- package/src/runtime/spots/spot-outbound.ts +4 -47
- package/src/runtime/spots/spot-routed-actor-admission.ts +20 -0
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -76
- package/src/runtime/spots/spot-runtime-ports.ts +6 -17
- package/src/runtime/spots/spot-serial-executor.ts +9 -1
- package/src/runtime/spots/spot-serial-turn-executor.ts +10 -4
- package/src/runtime/streams/actor-session-binding-registry.ts +20 -308
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +2 -12
- package/src/runtime/streams/bound-session-service.ts +2 -36
- package/src/runtime/streams/index.ts +29 -27
- package/src/runtime/streams/session-serial-executor.ts +2 -2
- package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
- package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
- package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
|
@@ -4,6 +4,7 @@ exports.ZLinkActorTransferRuntime = void 0;
|
|
|
4
4
|
exports.committedActorOwnerFence = committedActorOwnerFence;
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
6
|
const contracts_1 = require("../../contracts");
|
|
7
|
+
const runtime_message_1 = require("../backend/runtime-message");
|
|
7
8
|
const authority_key_codec_1 = require("../locations/authority-key-codec");
|
|
8
9
|
const actors_1 = require("../actors");
|
|
9
10
|
const actor_retry_delay_1 = require("../actors/actor-retry-delay");
|
|
@@ -56,19 +57,21 @@ class ZLinkActorTransferRuntime {
|
|
|
56
57
|
options;
|
|
57
58
|
sourceDepartureTasks = new Map();
|
|
58
59
|
coreSourceLeaves = new Map();
|
|
60
|
+
// Spot Actor membership sections 4-5: Join completion idempotency is
|
|
61
|
+
// process-local. These maps end with the process; nothing is replayed.
|
|
59
62
|
activeDeferredJoinTerminals = new Map();
|
|
60
63
|
deferredJoinTerminals = new bounded_replay_map_1.BoundedReplayMap(DEFERRED_JOIN_TERMINAL_CAPACITY);
|
|
61
64
|
constructor(options) {
|
|
62
65
|
this.options = options;
|
|
63
66
|
}
|
|
64
|
-
beginDeferredActorHandoff(actor, state
|
|
67
|
+
beginDeferredActorHandoff(actor, state) {
|
|
65
68
|
const actorId = actor.context.actorId;
|
|
66
|
-
this.options.actorHandoff.beginProvisional(actorId,
|
|
69
|
+
this.options.actorHandoff.beginProvisional(actorId, requireSourceObjectGeneration(actorId, state));
|
|
67
70
|
}
|
|
68
|
-
promoteDeferredActorHandoff(actor, _state
|
|
69
|
-
this.options.actorHandoff.promoteProvisional(actor.context.actorId
|
|
71
|
+
promoteDeferredActorHandoff(actor, _state) {
|
|
72
|
+
this.options.actorHandoff.promoteProvisional(actor.context.actorId);
|
|
70
73
|
}
|
|
71
|
-
async completeDeferredActorHandoff(actor, target, _targetActorRef
|
|
74
|
+
async completeDeferredActorHandoff(actor, target, _targetActorRef) {
|
|
72
75
|
const actorId = actor.context.actorId;
|
|
73
76
|
if (!this.options.actorHandoff.isProvisional(actorId))
|
|
74
77
|
return;
|
|
@@ -76,91 +79,69 @@ class ZLinkActorTransferRuntime {
|
|
|
76
79
|
if (manager === undefined) {
|
|
77
80
|
throw new Error(`Actor '${actorId}' same-node Join has no local Spot manager.`);
|
|
78
81
|
}
|
|
79
|
-
const admitted = this.options.actorHandoff.admitDeferredPrefix(actorId,
|
|
82
|
+
const admitted = this.options.actorHandoff.admitDeferredPrefix(actorId, (drain) => manager.admitRoutedActorPacketPrefix(target.spotId, actorId, drain), this.options.prepareApplicationJob);
|
|
80
83
|
void this.observeHandoffReplay(admitted.terminal);
|
|
81
84
|
}
|
|
82
|
-
async cancelDeferredActorHandoff(actor,
|
|
83
|
-
const admitted = this.admitDeferredSourcePrefix(actor,
|
|
85
|
+
async cancelDeferredActorHandoff(actor, state) {
|
|
86
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state);
|
|
84
87
|
void this.observeHandoffReplay(admitted.terminal);
|
|
85
88
|
}
|
|
86
|
-
|
|
87
|
-
return
|
|
89
|
+
prepareDeferredJoinAccepted(actorId, operationId, actorRef, rawReply, replyContentType) {
|
|
90
|
+
return (0, actors_1.createDeferredJoinCompletion)(actorId, operationId, actorRef, rawReply, replyContentType);
|
|
88
91
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
markDeferredJoinAcceptedCommitted(root, actorRef, signal) {
|
|
99
|
-
return this.requireDeferredJoinJournal().markCommitted(root, actorRef, signal);
|
|
100
|
-
}
|
|
101
|
-
async commitAndDeliverDeferredJoinAccepted(root, actor, actorRef, submitMailbox, signal) {
|
|
102
|
-
const terminalKey = deferredJoinTerminalKey(root);
|
|
103
|
-
const terminal = this.deferredJoinTerminals.get(terminalKey);
|
|
104
|
-
if (terminal !== undefined) {
|
|
92
|
+
/**
|
|
93
|
+
* Runs the Accepted completion callback once in the target Actor mailbox.
|
|
94
|
+
* A repeated delivery of the same OperationId in this process observes the
|
|
95
|
+
* first terminal (completion idempotency only).
|
|
96
|
+
*/
|
|
97
|
+
async deliverDeferredJoinAccepted(completion, actor, actorRef, submitMailbox, signal) {
|
|
98
|
+
const terminalKey = deferredJoinTerminalKey(completion);
|
|
99
|
+
if (this.deferredJoinTerminals.get(terminalKey) !== undefined) {
|
|
105
100
|
this.deferredJoinTerminals.touch(terminalKey);
|
|
106
|
-
return
|
|
101
|
+
return;
|
|
107
102
|
}
|
|
108
103
|
const active = this.activeDeferredJoinTerminals.get(terminalKey);
|
|
109
104
|
if (active !== undefined)
|
|
110
105
|
return await waitForOperation(active, signal);
|
|
111
|
-
const
|
|
112
|
-
this.activeDeferredJoinTerminals.set(terminalKey,
|
|
113
|
-
void
|
|
114
|
-
this.deferredJoinTerminals.remember(terminalKey,
|
|
115
|
-
if (this.activeDeferredJoinTerminals.get(terminalKey) ===
|
|
106
|
+
const delivery = this.deliverDeferredJoinAcceptedCore(completion, actor, actorRef, submitMailbox);
|
|
107
|
+
this.activeDeferredJoinTerminals.set(terminalKey, delivery);
|
|
108
|
+
void delivery.then(() => {
|
|
109
|
+
this.deferredJoinTerminals.remember(terminalKey, true);
|
|
110
|
+
if (this.activeDeferredJoinTerminals.get(terminalKey) === delivery) {
|
|
116
111
|
this.activeDeferredJoinTerminals.delete(terminalKey);
|
|
117
112
|
}
|
|
118
113
|
}, () => {
|
|
119
|
-
if (this.activeDeferredJoinTerminals.get(terminalKey) ===
|
|
114
|
+
if (this.activeDeferredJoinTerminals.get(terminalKey) === delivery) {
|
|
120
115
|
this.activeDeferredJoinTerminals.delete(terminalKey);
|
|
121
116
|
}
|
|
122
117
|
});
|
|
123
|
-
return await waitForOperation(
|
|
118
|
+
return await waitForOperation(delivery, signal);
|
|
124
119
|
}
|
|
125
|
-
async
|
|
120
|
+
async deliverDeferredJoinAcceptedCore(completion, actor, actorRef, submitMailbox) {
|
|
126
121
|
const targetActorRef = this.options
|
|
127
122
|
.actorManager()
|
|
128
123
|
?.getState(actor.context.actorId)?.nativeActorRef;
|
|
129
124
|
const currentActorRef = targetActorRef === undefined
|
|
130
125
|
? actorRef
|
|
131
126
|
: (0, actors_1.toFrameworkActorRef)(targetActorRef, actor.context.meshName);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
current =
|
|
151
|
-
(await this.requireDeferredJoinJournal().recover(currentActorRef.actorId)) ?? current;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
throw lastError;
|
|
156
|
-
}
|
|
157
|
-
requireDeferredJoinJournal() {
|
|
158
|
-
const authority = this.options.authorityStore();
|
|
159
|
-
const relocation = this.options.relocationStore();
|
|
160
|
-
if (authority === undefined || relocation === undefined) {
|
|
161
|
-
throw new Error('Cross-node deferred Actor Join requires Location and Relocation Stores.');
|
|
162
|
-
}
|
|
163
|
-
return new actors_1.ZLinkDeferredJoinAcceptedJournal(authority, relocation, this.options.messageSerializers);
|
|
127
|
+
if (completion.actor.actorId !== currentActorRef.actorId ||
|
|
128
|
+
completion.actor.objectGeneration !== currentActorRef.objectGeneration) {
|
|
129
|
+
throw new Error('Deferred Join completion generation fence is stale ' +
|
|
130
|
+
`(completion ${completion.actor.actorId}/${completion.actor.objectGeneration}, ` +
|
|
131
|
+
`actor ${currentActorRef.actorId}/${currentActorRef.objectGeneration}).`);
|
|
132
|
+
}
|
|
133
|
+
await submitMailbox(async () => {
|
|
134
|
+
await actor.onJoinCompleted?.({
|
|
135
|
+
status: 'accepted',
|
|
136
|
+
operationId: completion.operationId,
|
|
137
|
+
actor: currentActorRef,
|
|
138
|
+
reply: completion.rawReply.byteLength === 0
|
|
139
|
+
? undefined
|
|
140
|
+
: completion.replyContentType === undefined
|
|
141
|
+
? contracts_1.ZLinkMessage.fromEncoded(contracts_1.ZLinkEncodedPayload.from(completion.rawReply))
|
|
142
|
+
: (0, payload_codec_1.wrapFrameworkPayloadMessage)(runtime_message_1.ZLinkBufferMessage.from(completion.rawReply), this.options.messageSerializers, completion.replyContentType, undefined, 'reply')
|
|
143
|
+
});
|
|
144
|
+
});
|
|
164
145
|
}
|
|
165
146
|
async prepareSourceActorLeave(actor, sourceSpotId, signal) {
|
|
166
147
|
if (sourceSpotId !== undefined) {
|
|
@@ -182,10 +163,9 @@ class ZLinkActorTransferRuntime {
|
|
|
182
163
|
}
|
|
183
164
|
await this.options.restoreEntrySpotActorJoined(actor, signal);
|
|
184
165
|
}
|
|
185
|
-
async beginSourceActorMove(actor, state,
|
|
186
|
-
if (
|
|
187
|
-
this.
|
|
188
|
-
this.promoteDeferredActorHandoff(actor, state, deferredOperationId);
|
|
166
|
+
async beginSourceActorMove(actor, state, deferredJoin = false) {
|
|
167
|
+
if (deferredJoin && this.options.actorHandoff.isProvisional(actor.context.actorId)) {
|
|
168
|
+
this.promoteDeferredActorHandoff(actor, state);
|
|
189
169
|
}
|
|
190
170
|
state.beginMove();
|
|
191
171
|
if (!this.options.actorHandoff.isActive(actor.context.actorId)) {
|
|
@@ -205,18 +185,18 @@ class ZLinkActorTransferRuntime {
|
|
|
205
185
|
}
|
|
206
186
|
}
|
|
207
187
|
catch (error) {
|
|
208
|
-
if (
|
|
188
|
+
if (!deferredJoin) {
|
|
209
189
|
this.options.actorHandoff.cancel(actor.context.actorId);
|
|
210
190
|
}
|
|
211
191
|
else {
|
|
212
|
-
const admitted = this.admitDeferredSourcePrefix(actor, state
|
|
192
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state);
|
|
213
193
|
void this.observeHandoffReplay(admitted.terminal);
|
|
214
194
|
}
|
|
215
195
|
state.endMove();
|
|
216
196
|
throw error;
|
|
217
197
|
}
|
|
218
198
|
}
|
|
219
|
-
async cancelSourceActorMove(actor, state,
|
|
199
|
+
async cancelSourceActorMove(actor, state, deferredJoin = false, replayStart = Promise.resolve()) {
|
|
220
200
|
try {
|
|
221
201
|
if (state.spotId !== undefined) {
|
|
222
202
|
await this.options.spotManager()?.cancelActorTransfer(state.spotId, actor.context.actorId);
|
|
@@ -224,12 +204,12 @@ class ZLinkActorTransferRuntime {
|
|
|
224
204
|
}
|
|
225
205
|
finally {
|
|
226
206
|
try {
|
|
227
|
-
if (
|
|
207
|
+
if (!deferredJoin) {
|
|
228
208
|
const admitted = this.admitCanceledSourcePrefix(actor, state, replayStart);
|
|
229
209
|
void this.observeHandoffReplay(admitted.terminal);
|
|
230
210
|
}
|
|
231
211
|
else {
|
|
232
|
-
const admitted = this.admitDeferredSourcePrefix(actor, state,
|
|
212
|
+
const admitted = this.admitDeferredSourcePrefix(actor, state, replayStart);
|
|
233
213
|
void this.observeHandoffReplay(admitted.terminal);
|
|
234
214
|
}
|
|
235
215
|
}
|
|
@@ -249,13 +229,13 @@ class ZLinkActorTransferRuntime {
|
|
|
249
229
|
}
|
|
250
230
|
return this.options.actorHandoff.admitCanceledPrefix(actor.context.actorId, queue, this.options.prepareApplicationJob, replayStart);
|
|
251
231
|
}
|
|
252
|
-
admitDeferredSourcePrefix(actor, state,
|
|
232
|
+
admitDeferredSourcePrefix(actor, state, replayStart = Promise.resolve()) {
|
|
253
233
|
const queue = this.sourceHandoffPrefixQueue(actor, state);
|
|
254
234
|
if (queue === undefined) {
|
|
255
235
|
this.options.actorHandoff.cancel(actor.context.actorId);
|
|
256
236
|
return { terminal: Promise.resolve() };
|
|
257
237
|
}
|
|
258
|
-
return this.options.actorHandoff.admitDeferredPrefix(actor.context.actorId,
|
|
238
|
+
return this.options.actorHandoff.admitDeferredPrefix(actor.context.actorId, queue, this.options.prepareApplicationJob, replayStart);
|
|
259
239
|
}
|
|
260
240
|
async observeHandoffReplay(release) {
|
|
261
241
|
try {
|
|
@@ -281,8 +261,8 @@ class ZLinkActorTransferRuntime {
|
|
|
281
261
|
}
|
|
282
262
|
return (drain) => manager.admitRoutedActorPacketPrefix(sourceSpotId, actor.context.actorId, drain);
|
|
283
263
|
}
|
|
284
|
-
async prepareSource(actor, state, signal, lifecycleAuthority = 'framework',
|
|
285
|
-
await this.beginSourceActorMove(actor, state,
|
|
264
|
+
async prepareSource(actor, state, signal, lifecycleAuthority = 'framework', deferredJoin = false, relocation) {
|
|
265
|
+
await this.beginSourceActorMove(actor, state, deferredJoin);
|
|
286
266
|
const relocationMetric = state.meshName === undefined
|
|
287
267
|
? undefined
|
|
288
268
|
: this.options.metrics?.startRelocation(state.meshName, 'actor', this.options.actorTransferRegistry.policy(state.actorType));
|
|
@@ -386,7 +366,7 @@ class ZLinkActorTransferRuntime {
|
|
|
386
366
|
this.coreSourceLeaves.delete(actor.context.actorId);
|
|
387
367
|
const replayGate = createHandoffReplayGate();
|
|
388
368
|
try {
|
|
389
|
-
await this.cancelSourceActorMove(actor, state,
|
|
369
|
+
await this.cancelSourceActorMove(actor, state, deferredJoin, replayGate.start);
|
|
390
370
|
await this.restoreSourceActor(actor, sourceSpotId);
|
|
391
371
|
if (sealId !== undefined) {
|
|
392
372
|
await this.observeBoundSessionSealAbort(actor, state);
|
|
@@ -402,7 +382,7 @@ class ZLinkActorTransferRuntime {
|
|
|
402
382
|
relocationMetric?.complete('failed');
|
|
403
383
|
const replayGate = createHandoffReplayGate();
|
|
404
384
|
try {
|
|
405
|
-
await this.cancelSourceActorMove(actor, state,
|
|
385
|
+
await this.cancelSourceActorMove(actor, state, deferredJoin, replayGate.start);
|
|
406
386
|
if (sourceLeaveStarted)
|
|
407
387
|
await this.restoreSourceActor(actor, sourceSpotId);
|
|
408
388
|
if (sealId !== undefined) {
|
|
@@ -465,6 +445,12 @@ class ZLinkActorTransferRuntime {
|
|
|
465
445
|
terminal = 'committed';
|
|
466
446
|
}
|
|
467
447
|
},
|
|
448
|
+
discard: (reason) => {
|
|
449
|
+
if (terminal !== 'prepared')
|
|
450
|
+
return;
|
|
451
|
+
terminal = 'rolledBack';
|
|
452
|
+
this.options.actorHandoff.failPending(actor.context.actorId, reason);
|
|
453
|
+
},
|
|
468
454
|
rollback: async () => {
|
|
469
455
|
if (terminal !== 'prepared')
|
|
470
456
|
return;
|
|
@@ -1201,7 +1187,8 @@ class ZLinkActorTransferRuntime {
|
|
|
1201
1187
|
previousAuthorityOwnerGeneration: target.previousAuthorityOwnerGeneration,
|
|
1202
1188
|
targetAuthorityOwnerGeneration: ownershipGeneration,
|
|
1203
1189
|
targetNodeRid: String(actorRef.nodeRid),
|
|
1204
|
-
targetNodeGeneration: authority.allocation.descriptorLifecycleGeneration
|
|
1190
|
+
targetNodeGeneration: authority.allocation.descriptorLifecycleGeneration,
|
|
1191
|
+
targetOwnerLeaseGeneration: authority.ownerLeaseGeneration
|
|
1205
1192
|
}
|
|
1206
1193
|
}, this.options.shutdownSignal?.());
|
|
1207
1194
|
return;
|
|
@@ -1214,9 +1201,9 @@ function relocationDebug(marker, detail) {
|
|
|
1214
1201
|
return;
|
|
1215
1202
|
console.error('[zlink.runtime.relocation]', marker, detail);
|
|
1216
1203
|
}
|
|
1217
|
-
function deferredJoinTerminalKey(
|
|
1218
|
-
return (`${
|
|
1219
|
-
(0, operation_identity_1.operationIdentityKey)(
|
|
1204
|
+
function deferredJoinTerminalKey(completion) {
|
|
1205
|
+
return (`${completion.actor.actorId}:${completion.actor.objectGeneration.toString()}:` +
|
|
1206
|
+
(0, operation_identity_1.operationIdentityKey)(completion.operationId));
|
|
1220
1207
|
}
|
|
1221
1208
|
function waitForOperation(operation, signal) {
|
|
1222
1209
|
if (signal === undefined)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ZLinkBackendContext, ZLinkBackendMeshNode } from '../backend';
|
|
2
2
|
import type { ZLinkFrameworkRegistration } from '../configuration';
|
|
3
|
-
import type { ZLinkMeshNodeDescriptor, ZLinkClientServerRuntime, ZLinkFanoutRuntime, ZLinkFrameworkRuntime, ZLinkFrameworkLifecycleOptions, ZLinkFrameworkRelocationOptions, ZLinkFrameworkRelocationResult, ZLinkObservedStatus, ZLinkFrameworkRuntimeStatus, ZLinkFrameworkTerminationResult, ZLinkRouteMeshRuntime } from '../../contracts';
|
|
3
|
+
import type { ZLinkMeshNodeDescriptor, ZLinkClientServerRuntime, ZLinkFanoutRuntime, ZLinkFrameworkRuntime, ZLinkListenerKind, ZLinkListenerStatus, ZLinkFrameworkLifecycleOptions, ZLinkFrameworkRelocationOptions, ZLinkFrameworkRelocationResult, ZLinkObservedStatus, ZLinkFrameworkRuntimeStatus, ZLinkFrameworkTerminationResult, ZLinkRouteMeshRuntime } from '../../contracts';
|
|
4
4
|
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
5
5
|
import type { ZLinkRuntimeEventPublisher } from '../diagnostics';
|
|
6
6
|
import type { ZLinkMessageFlowControl, ZLinkMessageFlowLogMode } from '../../contracts';
|
|
@@ -61,6 +61,7 @@ export declare class ZLinkFrameworkRuntimeHost implements ZLinkFrameworkRuntimeL
|
|
|
61
61
|
private actorManager?;
|
|
62
62
|
private actorPlacement?;
|
|
63
63
|
private spotManager?;
|
|
64
|
+
private userSpotCoordinator?;
|
|
64
65
|
private ownerLeaseRecoveryRuntime?;
|
|
65
66
|
private ownerLeaseRecoveryHandler?;
|
|
66
67
|
private registerUserSpotHandlers?;
|
|
@@ -71,6 +72,7 @@ export declare class ZLinkFrameworkRuntimeHost implements ZLinkFrameworkRuntimeL
|
|
|
71
72
|
private readonly capacityStatus;
|
|
72
73
|
private readonly metricRegistrations;
|
|
73
74
|
private readonly admission;
|
|
75
|
+
private readonly activationAdmission;
|
|
74
76
|
private cachedLocationSpotRouteResolver?;
|
|
75
77
|
private actorClientLocationResolver?;
|
|
76
78
|
private readonly messageFlowModeCell;
|
|
@@ -94,6 +96,8 @@ export declare class ZLinkFrameworkRuntimeHost implements ZLinkFrameworkRuntimeL
|
|
|
94
96
|
constructor(options: ZLinkFrameworkRuntimeHostOptions, internalOptions?: unknown);
|
|
95
97
|
get isStarted(): boolean;
|
|
96
98
|
get status(): ZLinkFrameworkRuntimeStatus;
|
|
99
|
+
private listenerRecords;
|
|
100
|
+
getListenerStatus(kind: ZLinkListenerKind, name: string): ZLinkListenerStatus;
|
|
97
101
|
observe(signal?: AbortSignal): AsyncIterable<ZLinkObservedStatus<ZLinkFrameworkRuntimeStatus>>;
|
|
98
102
|
resetCapacityMetrics(): void;
|
|
99
103
|
relocate(options: ZLinkFrameworkRelocationOptions): Promise<ZLinkFrameworkRelocationResult>;
|
|
@@ -150,7 +154,7 @@ export declare class ZLinkFrameworkRuntimeHost implements ZLinkFrameworkRuntimeL
|
|
|
150
154
|
private registerInstanceApplicationLifecycle;
|
|
151
155
|
setActorManager(actorManager: DefaultZLinkActorManager): void;
|
|
152
156
|
setSpotManager(spotManager: DefaultZLinkSpotManager): void;
|
|
153
|
-
createActorManagerOptions(): Pick<ZLinkActorManagerOptions, 'joinCoordinator' | 'actorMeshNameProvider' | 'actorLeaveSpot' | 'messageSerializers' | 'nativeActorNode' | 'nativeActorNodeProvider' | 'actorCreatedNodeRidProvider' | 'actorRefResolver' | 'actorCreatedNotifier' | 'actorDestroyedCleanup' | 'locationLifecycle' | 'boundSessionFactory' | 'shutdownSignal' | 'admission' | 'placementCreate'>;
|
|
157
|
+
createActorManagerOptions(): Pick<ZLinkActorManagerOptions, 'joinCoordinator' | 'actorMeshNameProvider' | 'actorLeaveSpot' | 'messageSerializers' | 'nativeActorNode' | 'nativeActorNodeProvider' | 'actorCreatedNodeRidProvider' | 'actorRefResolver' | 'actorCreatedNotifier' | 'actorDestroyedCleanup' | 'locationLifecycle' | 'boundSessionFactory' | 'shutdownSignal' | 'admission' | 'activationAdmission' | 'placementCreate'>;
|
|
154
158
|
createActorClientOptions(): ConstructorParameters<typeof DefaultZLinkActorClient>[0];
|
|
155
159
|
createLocationHandleResolver(): ZLinkStoreLocationResolvers | undefined;
|
|
156
160
|
createSpotManagerOptions(): Partial<ZLinkSpotManagerOptions>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ZLinkUserSpotCreationCoordinator = exports.ZLinkHostSpotAddressTransport = exports.ZLinkRelocationStateIncompatibleError = exports.ZLinkRouteMeshRuntimeCoordinator = exports.ZLinkRetiringRollbackError = exports.transferIdString = exports.ZLinkActorTransferAuthorityRuntime = exports.ZLinkFrameworkRuntimeHost = void 0;
|
|
4
4
|
exports.hasUnsupportedManualTopology = hasUnsupportedManualTopology;
|
|
5
5
|
exports.hasExactPeerReadiness = hasExactPeerReadiness;
|
|
6
|
+
const listener_records_1 = require("../foundation/listener-records");
|
|
6
7
|
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
7
8
|
const node_crypto_1 = require("node:crypto");
|
|
8
9
|
const runtime_message_1 = require("../backend/runtime-message");
|
|
@@ -46,7 +47,9 @@ const channel_runtime_options_factory_1 = require("./channel-runtime-options-fac
|
|
|
46
47
|
const spot_node_runtime_options_factory_1 = require("./spot-node-runtime-options-factory");
|
|
47
48
|
const runtime_shutdown_1 = require("./runtime-shutdown");
|
|
48
49
|
const admission_1 = require("../admission");
|
|
50
|
+
const activation_admission_1 = require("../activation-admission");
|
|
49
51
|
const route_mesh_runtime_1 = require("./route-mesh-runtime");
|
|
52
|
+
const service_relocation_coordinator_1 = require("../foundation/service-relocation-coordinator");
|
|
50
53
|
const ConfigurationException_1 = require("../../contracts/Configuration/ConfigurationException");
|
|
51
54
|
const stateful_authority_route_runtime_1 = require("./stateful-authority-route-runtime");
|
|
52
55
|
const instance_activation_authority_1 = require("./instance-activation-authority");
|
|
@@ -95,6 +98,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
95
98
|
actorManager;
|
|
96
99
|
actorPlacement;
|
|
97
100
|
spotManager;
|
|
101
|
+
userSpotCoordinator;
|
|
98
102
|
ownerLeaseRecoveryRuntime;
|
|
99
103
|
ownerLeaseRecoveryHandler;
|
|
100
104
|
registerUserSpotHandlers;
|
|
@@ -105,6 +109,11 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
105
109
|
capacityStatus;
|
|
106
110
|
metricRegistrations = [];
|
|
107
111
|
admission = new admission_1.ZLinkRuntimeAdmissionGate(() => this.ownerAdmissionOpen());
|
|
112
|
+
activationAdmission = new activation_admission_1.ZLinkActivationAdmission((meshName) => this.options.registration.spotNodes.get(meshName)?.activationConcurrencyLimit ?? 128, (meshName) => {
|
|
113
|
+
void this.spotNodeRuntime
|
|
114
|
+
?.publishMeshNodeState(this.runtimeState, this.executionState?.abortController.signal, meshName)
|
|
115
|
+
.catch(() => undefined);
|
|
116
|
+
});
|
|
108
117
|
cachedLocationSpotRouteResolver;
|
|
109
118
|
actorClientLocationResolver;
|
|
110
119
|
// Shared, runtime-mutable message-flow mode cell — installed once so
|
|
@@ -441,7 +450,6 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
441
450
|
actorTransferRegistry: this.actorTransferRegistry,
|
|
442
451
|
authorityStore: () => this.locationOwner.currentStores?.locationStore,
|
|
443
452
|
currentOwner: () => this.locationOwner.currentRuntime?.currentOwnerToken,
|
|
444
|
-
relocationStore: () => this.options.registration.locations.relocationStoreInstance,
|
|
445
453
|
liveDescriptors: (meshName, signal) => {
|
|
446
454
|
const runtime = this.locationOwner.currentRuntime;
|
|
447
455
|
if (runtime === undefined) {
|
|
@@ -527,7 +535,8 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
527
535
|
invalidateActorRoute: (actorId) => this.actorClientLocationResolver?.invalidateActorRoute(actorId),
|
|
528
536
|
reconcileStatefulAuthorityRoutes: (signal) => this.statefulAuthorityRoutes?.reconcile(signal) ?? Promise.resolve(),
|
|
529
537
|
runtimeEventPublisher: this.runtimeEventPublisher,
|
|
530
|
-
metrics: this.metrics
|
|
538
|
+
metrics: this.metrics,
|
|
539
|
+
activationAdmission: this.activationAdmission
|
|
531
540
|
});
|
|
532
541
|
this.actorTransferAuthorityRuntime = new actor_transfer_authority_runtime_1.ZLinkActorTransferAuthorityRuntime({
|
|
533
542
|
store: () => this.locationOwner.actorTransferStore(),
|
|
@@ -561,6 +570,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
561
570
|
},
|
|
562
571
|
hostState: () => this.runtimeState,
|
|
563
572
|
admission: this.admission,
|
|
573
|
+
activationAdmission: this.activationAdmission,
|
|
564
574
|
publishRetiring: (meshName, signal) => this.publishMeshRetiring(meshName, signal),
|
|
565
575
|
rollbackRetiring: (meshName, signal) => this.publishMeshServing(meshName, signal),
|
|
566
576
|
publishDraining: (meshName, signal) => this.publishMeshDraining(meshName, signal),
|
|
@@ -590,6 +600,15 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
590
600
|
observedAt: new Date()
|
|
591
601
|
};
|
|
592
602
|
}
|
|
603
|
+
// Bound listener records of the current runtime generation.
|
|
604
|
+
listenerRecords = new listener_records_1.ZLinkListenerRecords();
|
|
605
|
+
getListenerStatus(kind, name) {
|
|
606
|
+
const endpoint = this.listenerRecords.endpoint(kind, name);
|
|
607
|
+
if (endpoint === undefined || endpoint.length === 0) {
|
|
608
|
+
throw new ConfigurationException_1.ZLinkConfigurationException(`Listener '${kind}:${name}' is not configured or has not bound.`);
|
|
609
|
+
}
|
|
610
|
+
return { kind, name, endpoint, observedAt: new Date() };
|
|
611
|
+
}
|
|
593
612
|
observe(signal) {
|
|
594
613
|
const queue = new runtime_observation_queue_1.RuntimeEventQueue(undefined, signal);
|
|
595
614
|
this.runtimeObservers.add(queue);
|
|
@@ -704,6 +723,11 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
704
723
|
this.setRuntimeState(contracts_1.ZLinkFrameworkRuntimeState.Relocating);
|
|
705
724
|
const drained = await this.routeMeshCoordinator.relocateHost(remainingDeadlineMs(), stopStartingSignal);
|
|
706
725
|
if (drained.kind === 'forceStopped') {
|
|
726
|
+
// Settled authority on both sides or an expired source owner lease
|
|
727
|
+
// ends the host in Error (spec 30 §13).
|
|
728
|
+
if (drained.error instanceof service_relocation_coordinator_1.ServiceRelocationAuthorityError) {
|
|
729
|
+
return this.completeRelocation(blockedRelocation(mode, effectiveTargetApplicationVersion, contracts_1.ZLinkFrameworkRelocationReason.RelocationFailed));
|
|
730
|
+
}
|
|
707
731
|
return this.resetBlockedRelocation(blockedRelocation(mode, effectiveTargetApplicationVersion, stopStartingSignal.aborted
|
|
708
732
|
? contracts_1.ZLinkFrameworkRelocationReason.ShutdownRequested
|
|
709
733
|
: drained.error instanceof service_relocation_host_runtime_1.ZLinkRelocationStateIncompatibleError
|
|
@@ -947,6 +971,8 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
947
971
|
}
|
|
948
972
|
this.setRuntimeState(contracts_1.ZLinkFrameworkRuntimeState.Preparing);
|
|
949
973
|
this.lifecycleSink?.push('framework:start');
|
|
974
|
+
const listenerRecords = new listener_records_1.ZLinkListenerRecords();
|
|
975
|
+
this.listenerRecords = listenerRecords;
|
|
950
976
|
const channelAdapter = this.backendAdapterFactory.createChannelAdapter();
|
|
951
977
|
const context = channelAdapter.createContext();
|
|
952
978
|
const coreHwm = this.options.registration.coreHwm;
|
|
@@ -964,10 +990,13 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
964
990
|
this.messageFlowModeCell.mode =
|
|
965
991
|
this.options.registration.dispatch?.diagnostics.messageFlow ?? 'errors';
|
|
966
992
|
const dispatchErrors = this.createDispatchErrorReporter(this.executionState.errorSink);
|
|
967
|
-
channelRuntime = new channels_1.ZLinkChannelRuntimeManager(this.options.registration, channelAdapter, context, this.options.providerResolver, this.createChannelRuntimeOptions());
|
|
993
|
+
channelRuntime = new channels_1.ZLinkChannelRuntimeManager(this.options.registration, channelAdapter, context, this.options.providerResolver, { ...this.createChannelRuntimeOptions(), listenerRecords });
|
|
968
994
|
this.channelRuntime = channelRuntime;
|
|
969
995
|
channelRuntime.prepareMeshDispatch(this.executionState.taskRunner);
|
|
970
|
-
spotNodeRuntime = new spots_1.ZLinkSpotNodeRuntimeManager(
|
|
996
|
+
spotNodeRuntime = new spots_1.ZLinkSpotNodeRuntimeManager({
|
|
997
|
+
...this.createSpotNodeRuntimeOptions(context, dispatchErrors),
|
|
998
|
+
listenerRecords
|
|
999
|
+
});
|
|
971
1000
|
await spotNodeRuntime.start();
|
|
972
1001
|
this.spotNodeRuntime = spotNodeRuntime;
|
|
973
1002
|
this.registerUserSpotHandlers?.(spotNodeRuntime);
|
|
@@ -991,6 +1020,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
991
1020
|
}
|
|
992
1021
|
}
|
|
993
1022
|
streamRuntime = new streams_1.ZLinkStreamRuntimeManager({
|
|
1023
|
+
listenerRecords,
|
|
994
1024
|
registration: this.options.registration,
|
|
995
1025
|
backendAdapterFactory: this.backendAdapterFactory,
|
|
996
1026
|
context,
|
|
@@ -1076,7 +1106,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1076
1106
|
reserved: capacity.reserved,
|
|
1077
1107
|
limit: capacity.limit
|
|
1078
1108
|
})),
|
|
1079
|
-
activation:
|
|
1109
|
+
activation: this.activationAdmission.current(meshName),
|
|
1080
1110
|
instanceSpots: []
|
|
1081
1111
|
});
|
|
1082
1112
|
}
|
|
@@ -1112,6 +1142,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1112
1142
|
serviceRelocation: this.serviceRelocation,
|
|
1113
1143
|
ownedStores: registeredRuntimeStores(this.options.registration)
|
|
1114
1144
|
});
|
|
1145
|
+
this.listenerRecords.clear();
|
|
1115
1146
|
this.lifecycleSink?.push('framework:stopped');
|
|
1116
1147
|
if (this.shutdownOperation === undefined) {
|
|
1117
1148
|
this.setRuntimeState(contracts_1.ZLinkFrameworkRuntimeState.Stopped);
|
|
@@ -1180,6 +1211,11 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1180
1211
|
const activationNode = node;
|
|
1181
1212
|
const spotManager = this.spotManager;
|
|
1182
1213
|
if (spotManager !== undefined) {
|
|
1214
|
+
activationNode.setSpotAdmissionProvider?.({
|
|
1215
|
+
isClosing: (spotId) => spotManager.isSpotClosing(meshName, spotId),
|
|
1216
|
+
awaitCloseDecision: (spotId) => spotManager.pendingSpotCloseDecision(meshName, spotId),
|
|
1217
|
+
runtimeState: () => this.runtimeState
|
|
1218
|
+
});
|
|
1183
1219
|
this.registerInstanceApplicationLifecycle(meshName, activationNode, spotManager);
|
|
1184
1220
|
}
|
|
1185
1221
|
activationNode.registerAsyncInstanceActivationAuthority?.(new instance_activation_authority_1.ZLinkInstanceActivationAuthority({
|
|
@@ -1366,6 +1402,12 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1366
1402
|
setSpotManager(spotManager) {
|
|
1367
1403
|
this.spotManager = spotManager;
|
|
1368
1404
|
for (const [meshName, node] of this.spotNodeRuntime?.meshNodesByName ?? []) {
|
|
1405
|
+
const admissionNode = node;
|
|
1406
|
+
admissionNode.setSpotAdmissionProvider?.({
|
|
1407
|
+
isClosing: (spotId) => spotManager.isSpotClosing(meshName, spotId),
|
|
1408
|
+
awaitCloseDecision: (spotId) => spotManager.pendingSpotCloseDecision(meshName, spotId),
|
|
1409
|
+
runtimeState: () => this.runtimeState
|
|
1410
|
+
});
|
|
1369
1411
|
this.registerInstanceApplicationLifecycle(meshName, node, spotManager);
|
|
1370
1412
|
}
|
|
1371
1413
|
}
|
|
@@ -1373,6 +1415,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1373
1415
|
this.ensureLocationRuntime();
|
|
1374
1416
|
return {
|
|
1375
1417
|
...this.actorRuntimeOptionsFactory().createActorManagerOptions(),
|
|
1418
|
+
activationAdmission: this.activationAdmission,
|
|
1376
1419
|
placementCreate: async (actorId, actorType, createOnly, call, signal) => {
|
|
1377
1420
|
const placement = this.actorPlacement;
|
|
1378
1421
|
if (placement === undefined) {
|
|
@@ -1416,10 +1459,16 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1416
1459
|
?.meshNode(meshName)
|
|
1417
1460
|
?.completeClosedInstance?.(spotId, objectGeneration);
|
|
1418
1461
|
},
|
|
1419
|
-
beginInstanceIdleClosingAuthority: (meshName, spotId) => this.locationOwner.currentLifecycle?.beginInstanceSpotClosing(meshName, spotId) ??
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1462
|
+
beginInstanceIdleClosingAuthority: (meshName, spotId, onCommitted) => this.locationOwner.currentLifecycle?.beginInstanceSpotClosing(meshName, spotId, onCommitted) ?? Promise.resolve(undefined),
|
|
1463
|
+
beginInstanceClosingAuthority: (meshName, spotId, onCommitted) => this.locationOwner.currentLifecycle?.beginInstanceSpotClosing(meshName, spotId, onCommitted) ?? Promise.resolve(undefined),
|
|
1464
|
+
beginUserClosingAuthority: async (meshName, spotId, objectGeneration, onCommitted) => {
|
|
1465
|
+
const coordinator = this.userSpotCoordinator;
|
|
1466
|
+
const nodeRid = this.spotNodeRuntime?.meshNode(meshName)?.status().routingId;
|
|
1467
|
+
if (coordinator === undefined || nodeRid === undefined) {
|
|
1468
|
+
throw new ConfigurationException_1.ZLinkConfigurationException('User Spot context Close requires its authority coordinator.');
|
|
1469
|
+
}
|
|
1470
|
+
return await coordinator.beginOwnerClose({ spotId: spotId, objectGeneration, meshName, nodeRid }, onCommitted);
|
|
1471
|
+
},
|
|
1423
1472
|
createLocationSpotRouteResolver: () => this.createLocationSpotRouteResolver(),
|
|
1424
1473
|
boundSessionRelay: this.boundSessionRelay,
|
|
1425
1474
|
actorHandoff: this.actorHandoff,
|
|
@@ -1430,12 +1479,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1430
1479
|
admission: this.admission,
|
|
1431
1480
|
statefulExecutionAllowed: () => this.ownerAdmissionOpen()
|
|
1432
1481
|
}).create(this.actorTransferRuntime),
|
|
1433
|
-
|
|
1434
|
-
onInstanceActivationConcurrencyChanged: (meshName) => {
|
|
1435
|
-
void this.spotNodeRuntime
|
|
1436
|
-
?.publishMeshNodeState(this.runtimeState, this.executionState?.abortController.signal, meshName)
|
|
1437
|
-
.catch(() => undefined);
|
|
1438
|
-
}
|
|
1482
|
+
activationAdmission: this.activationAdmission
|
|
1439
1483
|
};
|
|
1440
1484
|
}
|
|
1441
1485
|
createPublicSpotManager(local) {
|
|
@@ -1511,7 +1555,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1511
1555
|
};
|
|
1512
1556
|
}
|
|
1513
1557
|
});
|
|
1514
|
-
const coordinator = new user_spot_creation_coordinator_1.ZLinkUserSpotCreationCoordinator({
|
|
1558
|
+
const coordinator = (this.userSpotCoordinator = new user_spot_creation_coordinator_1.ZLinkUserSpotCreationCoordinator({
|
|
1515
1559
|
store: locationStore,
|
|
1516
1560
|
publishReadyRoute: (meshName, route) => {
|
|
1517
1561
|
this.cachedLocationSpotRouteResolver?.invalidate?.(route.spot.spotId);
|
|
@@ -1589,7 +1633,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1589
1633
|
localStatus.lifecycleGeneration === selected.lifecycleGeneration
|
|
1590
1634
|
};
|
|
1591
1635
|
}
|
|
1592
|
-
});
|
|
1636
|
+
}));
|
|
1593
1637
|
const factories = new Map([...this.options.registration.spotNodes].map(([meshName, node]) => [
|
|
1594
1638
|
meshName,
|
|
1595
1639
|
new Map(Object.entries(node.spotFactoryRegistrations ?? {}))
|
|
@@ -1725,25 +1769,12 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1725
1769
|
}, signal);
|
|
1726
1770
|
},
|
|
1727
1771
|
close: async (record, signal) => {
|
|
1728
|
-
if (!local.hasActiveSpot(record.target.spotId)) {
|
|
1729
|
-
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotMoving, `User Spot '${record.target.spotId}' is not materialized on its authority owner.`, true);
|
|
1730
|
-
}
|
|
1731
|
-
if (!local.canCloseUserSpot(meshName, record.target.spotId)) {
|
|
1732
|
-
return {
|
|
1733
|
-
terminalResult: runtime_values_1.RequestResult.Ok,
|
|
1734
|
-
failureCode: 0,
|
|
1735
|
-
tail: {
|
|
1736
|
-
kind: 'userSpotClose',
|
|
1737
|
-
closed: false
|
|
1738
|
-
}
|
|
1739
|
-
};
|
|
1740
|
-
}
|
|
1741
1772
|
return {
|
|
1742
1773
|
terminalResult: runtime_values_1.RequestResult.Ok,
|
|
1743
1774
|
failureCode: 0,
|
|
1744
1775
|
tail: {
|
|
1745
1776
|
kind: 'userSpotClose',
|
|
1746
|
-
closed: await coordinator.handleRemoteClose(record, (spot, closeSignal) => local.
|
|
1777
|
+
closed: await coordinator.handleRemoteClose(record, (spot, beginAuthority, closeSignal) => local.closeUserWithAuthority(spot.meshName, spot.spotId, beginAuthority, closeSignal), signal, (spot) => local.isSpotClosing(spot.meshName, spot.spotId))
|
|
1747
1778
|
}
|
|
1748
1779
|
};
|
|
1749
1780
|
}
|
|
@@ -1905,12 +1936,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
1905
1936
|
});
|
|
1906
1937
|
},
|
|
1907
1938
|
meshRecordDispatcher: (meshName, owner, record) => this.dispatchMeshRecord(meshName, owner, record, this.executionState?.abortController.signal),
|
|
1908
|
-
|
|
1909
|
-
return (this.spotManager?.instanceActivationConcurrency(meshName) ?? {
|
|
1910
|
-
active: 0,
|
|
1911
|
-
limit: this.options.registration.spotNodes.get(meshName)?.activationConcurrencyLimit ?? 128
|
|
1912
|
-
});
|
|
1913
|
-
}
|
|
1939
|
+
activationConcurrency: (meshName) => this.activationAdmission.current(meshName)
|
|
1914
1940
|
};
|
|
1915
1941
|
}
|
|
1916
1942
|
async dispatchMeshRecord(meshName, owner, record, signal) {
|
|
@@ -338,7 +338,7 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
338
338
|
const owner = (0, actor_session_binding_runtime_owner_1.actorSessionBindingRuntimeOwner)(runtime);
|
|
339
339
|
const fingerprint = (0, service_stateful_wire_codec_1.encodeSessionRelocationRoute)(value).toString('base64');
|
|
340
340
|
if (value.route.action === 'abort') {
|
|
341
|
-
await owner.applyRelocation(value.actor.actorId, key, fingerprint,
|
|
341
|
+
await owner.applyRelocation(value.actor.actorId, key, fingerprint, async () => {
|
|
342
342
|
if (!(await runtime.abortActorRouteSeal(value.actor.actorId, key))) {
|
|
343
343
|
throw new bound_session_wire_1.ZLinkRemoteBoundSessionFenceError(`Actor '${value.actor.actorId}' command 44 abort lost its Session seal.`);
|
|
344
344
|
}
|
|
@@ -357,9 +357,10 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
357
357
|
nodeRid: (0, routing_id_1.decodeRoutingId)(committedRoute.targetNodeRid, undefined),
|
|
358
358
|
bindingGeneration: value.session.bindingGeneration,
|
|
359
359
|
ownershipGeneration: committedRoute.targetAuthorityOwnerGeneration,
|
|
360
|
-
ownerNodeGeneration: committedRoute.targetNodeGeneration
|
|
360
|
+
ownerNodeGeneration: committedRoute.targetNodeGeneration,
|
|
361
|
+
ownerLeaseGeneration: committedRoute.targetOwnerLeaseGeneration
|
|
361
362
|
};
|
|
362
|
-
await owner.applyRelocation(value.actor.actorId, key, fingerprint,
|
|
363
|
+
await owner.applyRelocation(value.actor.actorId, key, fingerprint, async () => {
|
|
363
364
|
await runtime.commitActorRoute(targetActorRef, undefined, {
|
|
364
365
|
confirmRemoteSessionBinding: 'send',
|
|
365
366
|
releaseSeal: { sealId: key }
|
|
@@ -9,6 +9,7 @@ type ZLinkMeshDrainResult = {
|
|
|
9
9
|
};
|
|
10
10
|
import type { ZLinkBackendMeshNode } from '../backend';
|
|
11
11
|
import type { ZLinkRuntimeAdmissionGate } from '../admission';
|
|
12
|
+
import type { ZLinkActivationAdmission } from '../activation-admission';
|
|
12
13
|
import type { ZLinkSpotNodeOptions } from '../configuration';
|
|
13
14
|
import { type ZLinkMeshNodeDescriptor } from '../../contracts';
|
|
14
15
|
export interface ZLinkRouteMeshRuntimeCoordinatorOptions {
|
|
@@ -20,6 +21,7 @@ export interface ZLinkRouteMeshRuntimeCoordinatorOptions {
|
|
|
20
21
|
readonly isLocationStoreHealthy?: () => boolean;
|
|
21
22
|
readonly hostState?: () => ZLinkFrameworkRuntimeState;
|
|
22
23
|
readonly admission: ZLinkRuntimeAdmissionGate;
|
|
24
|
+
readonly activationAdmission?: ZLinkActivationAdmission;
|
|
23
25
|
readonly publishRetiring: (meshName: string, signal: AbortSignal) => Promise<void>;
|
|
24
26
|
readonly rollbackRetiring: (meshName: string, signal: AbortSignal) => Promise<void>;
|
|
25
27
|
readonly publishDraining: (meshName: string, signal: AbortSignal) => Promise<void>;
|