@zlink-systems/framework 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  3. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  4. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  5. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  6. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  7. package/dist/contracts/Configuration/index.d.ts +1 -1
  8. package/dist/internal.d.ts +1 -0
  9. package/dist/internal.js +3 -1
  10. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  11. package/dist/runtime/actors/actor-handoff.js +9 -4
  12. package/dist/runtime/actors/actor-runtime-contracts.d.ts +1 -0
  13. package/dist/runtime/actors/index.d.ts +2 -0
  14. package/dist/runtime/actors/index.js +21 -6
  15. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +3 -1
  16. package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
  17. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
  18. package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
  19. package/dist/runtime/application-jobs/contracts.d.ts +5 -1
  20. package/dist/runtime/backend/contracts/index.d.ts +10 -19
  21. package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
  22. package/dist/runtime/backend/mesh-completion-table.js +28 -18
  23. package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
  24. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  25. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  26. package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
  27. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  28. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  29. package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
  30. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
  31. package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
  32. package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
  33. package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
  34. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  35. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  36. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  37. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  38. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  39. package/dist/runtime/diagnostics/message-flow.js +3 -3
  40. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
  41. package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
  42. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  43. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  44. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  45. package/dist/runtime/foundation/service-mailbox.js +2 -1
  46. package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
  47. package/dist/runtime/foundation/service-stateful-runtime.js +60 -41
  48. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
  49. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  50. package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
  51. package/dist/runtime/foundation/service-topology-registry.js +9 -4
  52. package/dist/runtime/handlers/handler-instance-scope.js +1 -1
  53. package/dist/runtime/host/actor-packet-relay.js +7 -7
  54. package/dist/runtime/host/actor-placement-coordinator.d.ts +2 -1
  55. package/dist/runtime/host/actor-placement-coordinator.js +2 -1
  56. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -1
  57. package/dist/runtime/host/actor-runtime-options-factory.js +2 -1
  58. package/dist/runtime/host/application-job-queue.d.ts +11 -4
  59. package/dist/runtime/host/application-job-queue.js +66 -10
  60. package/dist/runtime/host/entry-actor-runtime.js +1 -1
  61. package/dist/runtime/host/index.d.ts +1 -1
  62. package/dist/runtime/host/index.js +18 -13
  63. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  64. package/dist/runtime/host/instance-activation-authority.js +89 -25
  65. package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
  66. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  67. package/dist/runtime/host/spot-address-transport.js +25 -12
  68. package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
  69. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  70. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  71. package/dist/runtime/locations/domain-store-contract.d.ts +3 -2
  72. package/dist/runtime/locations/in-memory-authority-store.d.ts +5 -2
  73. package/dist/runtime/locations/in-memory-authority-store.js +107 -14
  74. package/dist/runtime/locations/in-memory-location-store.d.ts +3 -3
  75. package/dist/runtime/locations/in-memory-location-store.js +31 -13
  76. package/dist/runtime/locations/internal-location-contracts.d.ts +8 -0
  77. package/dist/runtime/locations/location-store-repository.d.ts +4 -2
  78. package/dist/runtime/locations/location-store-repository.js +209 -33
  79. package/dist/runtime/locations/resolvers.d.ts +2 -1
  80. package/dist/runtime/locations/resolvers.js +10 -1
  81. package/dist/runtime/messaging/submission-result.d.ts +1 -1
  82. package/dist/runtime/messaging/submission-result.js +2 -2
  83. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
  84. package/dist/runtime/spots/index.d.ts +4 -3
  85. package/dist/runtime/spots/index.js +14 -14
  86. package/dist/runtime/spots/spot-activation.d.ts +2 -1
  87. package/dist/runtime/spots/spot-activation.js +4 -4
  88. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  89. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  90. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  91. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  92. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  93. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  94. package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
  95. package/dist/runtime/spots/spot-entry-activation.js +6 -1
  96. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +3 -1
  97. package/dist/runtime/spots/spot-node-runtime-manager.js +10 -11
  98. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  99. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
  100. package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
  101. package/dist/runtime/spots/spot-serial-executor.js +10 -1
  102. package/dist/runtime/streams/stream-session-runtime.js +1 -1
  103. package/package.json +3 -3
  104. package/src/contracts/Configuration/Builders.ts +1 -2
  105. package/src/contracts/Configuration/Configs.ts +0 -6
  106. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  107. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  108. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  109. package/src/contracts/Configuration/index.ts +1 -6
  110. package/src/internal.ts +1 -0
  111. package/src/runtime/actors/actor-handoff.ts +13 -4
  112. package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
  113. package/src/runtime/actors/index.ts +77 -42
  114. package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
  115. package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
  116. package/src/runtime/application-jobs/contracts.ts +14 -1
  117. package/src/runtime/backend/contracts/index.ts +10 -18
  118. package/src/runtime/backend/mesh-completion-table.ts +36 -19
  119. package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
  120. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  121. package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
  122. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  123. package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
  124. package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
  125. package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
  126. package/src/runtime/backend/raw-binding-port.ts +12 -2
  127. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  128. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  129. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  130. package/src/runtime/diagnostics/message-flow.ts +1 -1
  131. package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
  132. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  133. package/src/runtime/foundation/service-mailbox.ts +7 -1
  134. package/src/runtime/foundation/service-stateful-runtime.ts +109 -77
  135. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
  136. package/src/runtime/foundation/service-topology-registry.ts +13 -7
  137. package/src/runtime/handlers/handler-instance-scope.ts +2 -1
  138. package/src/runtime/host/actor-packet-relay.ts +7 -0
  139. package/src/runtime/host/actor-placement-coordinator.ts +8 -2
  140. package/src/runtime/host/actor-runtime-options-factory.ts +7 -0
  141. package/src/runtime/host/application-job-queue.ts +77 -10
  142. package/src/runtime/host/entry-actor-runtime.ts +1 -0
  143. package/src/runtime/host/index.ts +30 -7
  144. package/src/runtime/host/instance-activation-authority.ts +132 -27
  145. package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
  146. package/src/runtime/host/spot-address-transport.ts +45 -22
  147. package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
  148. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  149. package/src/runtime/locations/domain-store-contract.ts +6 -2
  150. package/src/runtime/locations/in-memory-authority-store.ts +153 -12
  151. package/src/runtime/locations/in-memory-location-store.ts +39 -13
  152. package/src/runtime/locations/internal-location-contracts.ts +10 -0
  153. package/src/runtime/locations/location-store-repository.ts +295 -36
  154. package/src/runtime/locations/resolvers.ts +25 -2
  155. package/src/runtime/messaging/submission-result.ts +2 -2
  156. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
  157. package/src/runtime/spots/index.ts +16 -0
  158. package/src/runtime/spots/spot-activation.ts +5 -0
  159. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  160. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  161. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  162. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  163. package/src/runtime/spots/spot-entry-activation.ts +7 -0
  164. package/src/runtime/spots/spot-node-runtime-manager.ts +14 -12
  165. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  166. package/src/runtime/spots/spot-runtime-ports.ts +2 -0
  167. package/src/runtime/spots/spot-serial-executor.ts +10 -4
  168. package/src/runtime/streams/stream-session-runtime.ts +1 -1
@@ -1,4 +1,4 @@
1
- import type { ApplicationJobPermitPort, ApplicationJobQueuePort } from '../application-jobs/contracts';
1
+ import type { ApplicationJobOrigin, ApplicationJobPermitPort, ApplicationJobQueuePort } from '../application-jobs/contracts';
2
2
  export type ApplicationJobQueueProfileValue = 'compact' | 'low_latency' | 'balanced' | 'throughput';
3
3
  export interface ApplicationJobQueueOptions {
4
4
  readonly profile?: ApplicationJobQueueProfileValue;
@@ -39,8 +39,9 @@ export interface ApplicationJobQueueSnapshot extends ApplicationJobQueueConfigur
39
39
  export declare function resolveApplicationJobQueueConfiguration(options?: ApplicationJobQueueOptions, effectiveProcessorCount?: () => bigint): ApplicationJobQueueConfiguration;
40
40
  export declare class ApplicationJobQueuePermit implements ApplicationJobPermitPort {
41
41
  private readonly owner;
42
+ readonly origin: ApplicationJobOrigin;
42
43
  private state;
43
- constructor(owner: ApplicationJobQueue);
44
+ constructor(owner: ApplicationJobQueue, origin: ApplicationJobOrigin);
44
45
  markApplicationQueued(): void;
45
46
  releaseBeforeHandler(): void;
46
47
  releaseAfterInternalProcessing(): void;
@@ -55,6 +56,9 @@ export declare class ApplicationJobQueue implements ApplicationJobQueuePort {
55
56
  private readonly configuration;
56
57
  private readonly nowMs;
57
58
  private readonly handlerStartGate?;
59
+ private readonly loggerFailureReporter?;
60
+ private localWaiters;
61
+ private localBacklogLogged;
58
62
  private reservedSupplyPermits;
59
63
  private queuedApplicationJobs;
60
64
  private peakPermitsInUse;
@@ -73,11 +77,12 @@ export declare class ApplicationJobQueue implements ApplicationJobQueuePort {
73
77
  private readonly waiters;
74
78
  private readonly receiveFlowTargets;
75
79
  private readonly receiveFlowController;
76
- constructor(configuration: ApplicationJobQueueConfiguration, nowMs?: () => number, handlerStartGate?: (() => boolean) | undefined);
80
+ constructor(configuration: ApplicationJobQueueConfiguration, nowMs?: () => number, handlerStartGate?: (() => boolean) | undefined, loggerFailureReporter?: ((error: unknown) => void) | undefined);
77
81
  shouldHoldPermitBeforeHandler(): boolean;
78
82
  registerReceiveFlowTarget(identity: object, applyState: (state: ApplicationJobQueuePressureState) => void, failureSink?: (error: unknown) => void): boolean;
79
83
  unregisterReceiveFlowTarget(identity: object): void;
80
- acquire(signal?: AbortSignal): Promise<ApplicationJobQueuePermit>;
84
+ acquire(signal: AbortSignal | undefined, origin: ApplicationJobOrigin): Promise<ApplicationJobQueuePermit>;
85
+ acquireOrResume(resume: (permit: ApplicationJobQueuePermit) => void, reject: (reason: unknown) => void, signal: AbortSignal | undefined, origin: ApplicationJobOrigin): ApplicationJobQueuePermit | undefined;
81
86
  snapshot(): ApplicationJobQueueSnapshot;
82
87
  resetMetrics(): void;
83
88
  pressureState(): ApplicationJobQueuePressureState;
@@ -92,6 +97,8 @@ export declare class ApplicationJobQueue implements ApplicationJobQueuePort {
92
97
  private drainWaiters;
93
98
  private cancel;
94
99
  private recordCompletedWait;
100
+ private updateLocalWaiters;
101
+ private logLocalBacklog;
95
102
  private evaluatePressure;
96
103
  private pauseDurationAt;
97
104
  private cumulativePauseDurationAt;
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApplicationJobQueue = exports.ApplicationJobQueuePermit = void 0;
4
4
  exports.resolveApplicationJobQueueConfiguration = resolveApplicationJobQueueConfiguration;
5
5
  exports.nodeEffectiveProcessorCount = nodeEffectiveProcessorCount;
6
+ const api_logs_1 = require("@opentelemetry/api-logs");
7
+ const message_flow_1 = require("../diagnostics/message-flow");
6
8
  const runtime_metrics_1 = require("../diagnostics/runtime-metrics");
7
9
  const Dispatch_1 = require("../../contracts/Dispatch");
8
10
  const Registration_1 = require("../../contracts/Configuration/Registration");
@@ -50,9 +52,11 @@ function resolveApplicationJobQueueConfiguration(options = {}, effectiveProcesso
50
52
  }
51
53
  class ApplicationJobQueuePermit {
52
54
  owner;
55
+ origin;
53
56
  state = 'reserved';
54
- constructor(owner) {
57
+ constructor(owner, origin) {
55
58
  this.owner = owner;
59
+ this.origin = origin;
56
60
  }
57
61
  markApplicationQueued() {
58
62
  if (this.state !== 'reserved') {
@@ -86,6 +90,9 @@ class ApplicationJobQueue {
86
90
  configuration;
87
91
  nowMs;
88
92
  handlerStartGate;
93
+ loggerFailureReporter;
94
+ localWaiters = 0;
95
+ localBacklogLogged = false;
89
96
  reservedSupplyPermits = 0n;
90
97
  queuedApplicationJobs = 0n;
91
98
  peakPermitsInUse = 0n;
@@ -104,10 +111,11 @@ class ApplicationJobQueue {
104
111
  waiters = [];
105
112
  receiveFlowTargets = new Map();
106
113
  receiveFlowController;
107
- constructor(configuration, nowMs = () => performance.now(), handlerStartGate) {
114
+ constructor(configuration, nowMs = () => performance.now(), handlerStartGate, loggerFailureReporter) {
108
115
  this.configuration = configuration;
109
116
  this.nowMs = nowMs;
110
117
  this.handlerStartGate = handlerStartGate;
118
+ this.loggerFailureReporter = loggerFailureReporter;
111
119
  this.receiveFlowController = new receive_flow_controller_1.ApplicationJobReceiveFlowController(this, (state) => state);
112
120
  }
113
121
  shouldHoldPermitBeforeHandler() {
@@ -153,15 +161,24 @@ class ApplicationJobQueue {
153
161
  this.receiveFlowTargets.delete(identity);
154
162
  this.receiveFlowController.unregister(target);
155
163
  }
156
- acquire(signal) {
164
+ acquire(signal, origin) {
165
+ return new Promise((resolve, reject) => {
166
+ const permit = this.acquireOrResume(resolve, reject, signal, origin);
167
+ if (permit !== undefined)
168
+ resolve(permit);
169
+ });
170
+ }
171
+ acquireOrResume(resume, reject, signal, origin) {
157
172
  if (signal?.aborted === true) {
158
- return Promise.reject(abortReason(signal));
173
+ reject(abortReason(signal));
174
+ return undefined;
159
175
  }
160
176
  if (this.waiters.length === 0 && this.permitsInUse() < this.limit()) {
161
- return Promise.resolve(this.reserve());
177
+ return this.reserve(origin);
162
178
  }
163
- return new Promise((resolve, reject) => {
179
+ new Promise((resolve, reject) => {
164
180
  const waiter = {
181
+ origin,
165
182
  resolve,
166
183
  reject,
167
184
  signal,
@@ -172,9 +189,15 @@ class ApplicationJobQueue {
172
189
  };
173
190
  this.waiters.push(waiter);
174
191
  this.capacityWaitCount += 1n;
192
+ const warningCount = this.updateLocalWaiters(origin, 1);
175
193
  signal?.addEventListener('abort', waiter.abort, { once: true });
176
194
  this.drainWaiters();
177
- });
195
+ if (warningCount !== undefined)
196
+ this.logLocalBacklog(warningCount);
197
+ })
198
+ .then(resume)
199
+ .catch(reject);
200
+ return undefined;
178
201
  }
179
202
  snapshot() {
180
203
  const permitsInUse = this.permitsInUse();
@@ -253,14 +276,14 @@ class ApplicationJobQueue {
253
276
  permitsInUse() {
254
277
  return this.reservedSupplyPermits + this.queuedApplicationJobs;
255
278
  }
256
- reserve(evaluatePressure = true) {
279
+ reserve(origin, evaluatePressure = true) {
257
280
  this.reservedSupplyPermits += 1n;
258
281
  const current = this.permitsInUse();
259
282
  if (current > this.peakPermitsInUse)
260
283
  this.peakPermitsInUse = current;
261
284
  if (evaluatePressure)
262
285
  this.evaluatePressure();
263
- return new ApplicationJobQueuePermit(this);
286
+ return new ApplicationJobQueuePermit(this, origin);
264
287
  }
265
288
  drainWaiters() {
266
289
  while (this.waiters.length > 0 && this.permitsInUse() < this.limit()) {
@@ -270,7 +293,7 @@ class ApplicationJobQueue {
270
293
  waiter.active = false;
271
294
  waiter.signal?.removeEventListener('abort', waiter.abort);
272
295
  this.recordCompletedWait(waiter);
273
- waiter.resolve(this.reserve(false));
296
+ waiter.resolve(this.reserve(waiter.origin, false));
274
297
  }
275
298
  }
276
299
  cancel(waiter) {
@@ -286,11 +309,44 @@ class ApplicationJobQueue {
286
309
  this.drainWaiters();
287
310
  }
288
311
  recordCompletedWait(waiter) {
312
+ this.updateLocalWaiters(waiter.origin, -1);
289
313
  if (waiter.metricsEpoch !== this.metricsEpoch)
290
314
  return;
291
315
  const durationMs = Math.max(0, this.nowMs() - waiter.startedAtMs);
292
316
  this.capacityWaitDurationSeconds += durationMs / runtime_metrics_1.MILLISECONDS_PER_SECOND;
293
317
  }
318
+ updateLocalWaiters(origin, delta) {
319
+ if (origin !== 'local')
320
+ return undefined;
321
+ this.localWaiters += delta;
322
+ if (this.localWaiters === 0)
323
+ this.localBacklogLogged = false;
324
+ if (!this.localBacklogLogged && this.localWaiters > Number(this.limit())) {
325
+ this.localBacklogLogged = true;
326
+ return this.localWaiters;
327
+ }
328
+ return undefined;
329
+ }
330
+ logLocalBacklog(localWaiters) {
331
+ try {
332
+ message_flow_1.telemetryLogger.emit({
333
+ eventName: 'zlink.runtime.host.local_job_backlog_exceeded',
334
+ timestamp: new Date(),
335
+ severityNumber: api_logs_1.SeverityNumber.WARN,
336
+ severityText: 'WARN',
337
+ body: 'Same-host jobs waiting for a host permit exceeded the application job queue maximum.',
338
+ attributes: {
339
+ source_kind: 'host',
340
+ source_name: 'zlink.runtime.host',
341
+ local_waiters: localWaiters,
342
+ effective_maximum: Number(this.limit())
343
+ }
344
+ });
345
+ }
346
+ catch (error) {
347
+ this.loggerFailureReporter?.(error);
348
+ }
349
+ }
294
350
  evaluatePressure() {
295
351
  const permitsInUse = this.permitsInUse();
296
352
  const next = this.pressureStateValue === 'running'
@@ -66,7 +66,7 @@ class ZLinkEntryActorRuntimeService {
66
66
  }
67
67
  return {
68
68
  handled: true,
69
- response: await spotManager.dispatchRoutedActorPacket(spotId, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef)
69
+ response: await spotManager.dispatchRoutedActorPacket('remote', spotId, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef)
70
70
  };
71
71
  }
72
72
  requireActorManager() {
@@ -155,7 +155,7 @@ export declare class ZLinkFrameworkRuntimeHost implements ZLinkFrameworkRuntimeL
155
155
  private registerInstanceApplicationLifecycle;
156
156
  setActorManager(actorManager: DefaultZLinkActorManager): void;
157
157
  setSpotManager(spotManager: DefaultZLinkSpotManager): void;
158
- createActorManagerOptions(): Pick<ZLinkActorManagerOptions, 'joinCoordinator' | 'actorMeshNameProvider' | 'actorLeaveSpot' | 'messageSerializers' | 'nativeActorNode' | 'nativeActorNodeProvider' | 'actorCreatedNodeRidProvider' | 'actorRefResolver' | 'actorCreatedNotifier' | 'actorDestroyedCleanup' | 'locationLifecycle' | 'boundSessionFactory' | 'shutdownSignal' | 'admission' | 'activationAdmission' | 'placementCreate'>;
158
+ createActorManagerOptions(): Pick<ZLinkActorManagerOptions, 'joinCoordinator' | 'actorMeshNameProvider' | 'actorLeaveSpot' | 'messageSerializers' | 'nativeActorNode' | 'nativeActorNodeProvider' | 'actorCreatedNodeRidProvider' | 'actorRefResolver' | 'actorCreatedNotifier' | 'actorDestroyedCleanup' | 'terminateActorActivation' | 'locationLifecycle' | 'boundSessionFactory' | 'shutdownSignal' | 'admission' | 'activationAdmission' | 'placementCreate'>;
159
159
  createActorClientOptions(): ConstructorParameters<typeof DefaultZLinkActorClient>[0];
160
160
  createLocationHandleResolver(): ZLinkStoreLocationResolvers | undefined;
161
161
  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.ZLinkDrainingStatePublishError = exports.transferIdString = exports.ZLinkActorTransferAuthorityRuntime = exports.ZLinkFrameworkRuntimeHost = void 0;
4
4
  exports.hasUnsupportedManualTopology = hasUnsupportedManualTopology;
5
5
  exports.hasExactPeerReadiness = hasExactPeerReadiness;
6
+ const application_job_queue_scope_1 = require("../application-jobs/application-job-queue-scope");
6
7
  const location_store_pages_1 = require("../locations/location-store-pages");
7
8
  const stream_wire_1 = require("@zlink-systems/stream-wire");
8
9
  const node_crypto_1 = require("node:crypto");
@@ -21,7 +22,7 @@ const actor_message_follow_context_1 = require("../actors/actor-message-follow-c
21
22
  const actor_transport_delivery_gate_1 = require("../actors/actor-transport-delivery-gate");
22
23
  const admission_1 = require("../admission");
23
24
  const application_job_queue_handler_start_gate_1 = require("../application-jobs/application-job-queue-handler-start-gate");
24
- const application_job_queue_scope_1 = require("../application-jobs/application-job-queue-scope");
25
+ const application_job_queue_scope_2 = require("../application-jobs/application-job-queue-scope");
25
26
  const backend_1 = require("../backend");
26
27
  const runtime_message_1 = require("../backend/runtime-message");
27
28
  const runtime_values_1 = require("../backend/runtime-values");
@@ -161,7 +162,7 @@ class ZLinkFrameworkRuntimeHost {
161
162
  catch {
162
163
  return false;
163
164
  }
164
- });
165
+ }, (error) => (this.errorSink ?? this.preStartErrorSink).reportRuntimeTaskException('logger-provider', error));
165
166
  this.capacityStatus = new host_capacity_status_1.HostCapacityStatusProjection(options.registration.coreHwm, this.applicationJobQueue);
166
167
  this.clientServerRuntime = new topology_runtime_projections_1.ZLinkClientServerRuntimeProjection(() => this.channelRuntime, () => this.runtimeState);
167
168
  this.fanoutRuntime = new topology_runtime_projections_1.ZLinkFanoutRuntimeProjection(() => this.channelRuntime, () => this.runtimeState);
@@ -452,12 +453,12 @@ class ZLinkFrameworkRuntimeHost {
452
453
  },
453
454
  sessionRelocationWire: () => this.serviceRelocation,
454
455
  clearRemoteActorPacketTarget: (actorId) => this.boundSessionRelay.clearRemoteActorPacketTarget(actorId),
455
- prepareApplicationJob: async (preparationSignal) => {
456
+ prepareApplicationJob: async (preparationSignal, origin) => {
456
457
  const runtimeSignal = this.executionState?.abortController.signal;
457
458
  const signal = runtimeSignal === undefined
458
459
  ? preparationSignal
459
460
  : AbortSignal.any([runtimeSignal, preparationSignal]);
460
- const permit = await this.applicationJobQueue.acquire(signal);
461
+ const permit = await this.applicationJobQueue.acquire(signal, origin);
461
462
  let state = 'ready';
462
463
  let closedReason;
463
464
  let abort;
@@ -491,7 +492,7 @@ class ZLinkFrameworkRuntimeHost {
491
492
  state = 'running';
492
493
  signal.removeEventListener('abort', abort);
493
494
  try {
494
- return await (0, application_job_queue_scope_1.runWithApplicationJobPermit)(permit, operation);
495
+ return await (0, application_job_queue_scope_2.runWithApplicationJobPermit)(permit, operation);
495
496
  }
496
497
  finally {
497
498
  state = 'closed';
@@ -1245,6 +1246,7 @@ class ZLinkFrameworkRuntimeHost {
1245
1246
  }
1246
1247
  activationNode.registerAsyncInstanceActivationAuthority?.(new instance_activation_authority_1.ZLinkInstanceActivationAuthority({
1247
1248
  store: locationStore,
1249
+ relocationPolicy: (stableType) => this.options.registration.spotNodes.get(meshName)?.instanceSpotFactoryRegistrations?.[stableType]?.relocation.kind,
1248
1250
  relocationStore: this.options.registration.locations.relocationStoreInstance,
1249
1251
  meshName,
1250
1252
  owner: () => this.locationOwner.currentRuntime?.currentOwnerToken,
@@ -1511,6 +1513,8 @@ class ZLinkFrameworkRuntimeHost {
1511
1513
  }
1512
1514
  this.actorPlacement ??= new actor_placement_coordinator_1.ZLinkActorPlacementCoordinator({
1513
1515
  store: locationStore,
1516
+ actorRelocationPolicy: (meshName, stableType) => this.options.registration.spotNodes.get(meshName)?.actorFactoryRegistrations?.[stableType]
1517
+ ?.relocation.kind,
1514
1518
  remoteCreate: (meshName, targetNodeRid, request, timeoutMs) => {
1515
1519
  const node = this.spotNodeRuntime?.meshNode(meshName);
1516
1520
  if (node === undefined) {
@@ -1546,13 +1550,11 @@ class ZLinkFrameworkRuntimeHost {
1546
1550
  const descriptors = await (0, location_store_pages_1.listAllMeshNodeDescriptors)(locationStore, meshName, signal);
1547
1551
  const selected = await selectReadyLocationPlacementDescriptor(descriptors, meshNode, signal, (descriptor) => {
1548
1552
  const capability = descriptor.objectCapabilities.find((candidate) => candidate.objectKind === 'actor' && candidate.stableType === stableType);
1549
- const actors = descriptor.populationCapacity.actors;
1550
1553
  return (descriptor.state === contracts_1.ZLinkFrameworkRuntimeState.Serving &&
1551
1554
  descriptor.objectRole === 'server' &&
1552
1555
  descriptor.placementWeight > 0 &&
1553
1556
  descriptor.entrySpotId !== undefined &&
1554
1557
  excludedNodeRids?.has(String(descriptor.rid)) !== true &&
1555
- (actors.limit === 0 || actors.active + actors.reserved < actors.limit) &&
1556
1558
  capability !== undefined);
1557
1559
  });
1558
1560
  if (selected === undefined)
@@ -1579,6 +1581,8 @@ class ZLinkFrameworkRuntimeHost {
1579
1581
  });
1580
1582
  const coordinator = (this.userSpotCoordinator = new user_spot_creation_coordinator_1.ZLinkUserSpotCreationCoordinator({
1581
1583
  store: locationStore,
1584
+ relocationPolicy: (meshName, stableType) => this.options.registration.spotNodes.get(meshName)?.spotFactoryRegistrations?.[stableType]
1585
+ ?.relocation.kind,
1582
1586
  publishReadyRoute: (meshName, route) => {
1583
1587
  this.cachedLocationSpotRouteResolver?.invalidate?.(route.spot.spotId);
1584
1588
  this.spotNodeRuntime?.meshNode(meshName)?.rememberSpotRoute?.(route);
@@ -1832,6 +1836,7 @@ class ZLinkFrameworkRuntimeHost {
1832
1836
  }
1833
1837
  actorRuntimeOptionsFactory() {
1834
1838
  return new actor_runtime_options_factory_1.ZLinkActorRuntimeOptionsFactory({
1839
+ terminateActorActivation: (actor, terminal) => this.spotNodeRuntime?.terminateActorActivation(actor, terminal) ?? terminal(),
1835
1840
  registration: this.options.registration,
1836
1841
  messageFlow: () => this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink).flow,
1837
1842
  routeTransport: this.routeTransport,
@@ -1960,11 +1965,11 @@ class ZLinkFrameworkRuntimeHost {
1960
1965
  ownerLeaseGeneration: record.source.ownerLeaseGeneration
1961
1966
  });
1962
1967
  },
1963
- meshRecordDispatcher: (meshName, owner, record) => this.dispatchMeshRecord(meshName, owner, record, this.executionState?.abortController.signal),
1968
+ meshRecordDispatcher: (meshName, owner, record) => this.dispatchMeshRecord(application_job_queue_scope_1.currentApplicationJobOrigin, meshName, owner, record, this.executionState?.abortController.signal),
1964
1969
  activationConcurrency: (meshName) => this.activationAdmission.current(meshName)
1965
1970
  };
1966
1971
  }
1967
- async dispatchMeshRecord(meshName, owner, record, signal) {
1972
+ async dispatchMeshRecord(applicationJobOrigin, meshName, owner, record, signal) {
1968
1973
  if (record.operationKind === service_runtime_contracts_1.OperationKind.ActorJoin) {
1969
1974
  if (this.spotManager === undefined) {
1970
1975
  throw new ConfigurationException_1.ZLinkConfigurationException('MeshNode Actor join dispatch requires the Spot manager.');
@@ -2022,7 +2027,7 @@ class ZLinkFrameworkRuntimeHost {
2022
2027
  nodeRid: binding.actor.nodeRid
2023
2028
  };
2024
2029
  if (sessionOwnerIsLocal) {
2025
- (0, application_job_queue_scope_1.releaseApplicationJobPermitBeforeHandler)();
2030
+ (0, application_job_queue_scope_2.releaseApplicationJobPermitBeforeHandler)();
2026
2031
  await this.streamBindingRuntime.retireRemoteBinding(actorRef, binding.sessionRid, binding.bindingGeneration, signal);
2027
2032
  }
2028
2033
  state.retireBoundSessionBinding(binding);
@@ -2108,7 +2113,7 @@ class ZLinkFrameworkRuntimeHost {
2108
2113
  if (this.spotManager === undefined) {
2109
2114
  throw new ConfigurationException_1.ZLinkConfigurationException('MeshNode Actor dispatch requires the Spot manager.');
2110
2115
  }
2111
- return this.admission.run(meshName, 'RouteMesh Actor dispatch', () => this.spotManager.dispatchMeshActor(meshName, owner, record));
2116
+ return this.admission.run(meshName, 'RouteMesh Actor dispatch', () => this.spotManager.dispatchMeshActor(applicationJobOrigin(), meshName, owner, record));
2112
2117
  case service_runtime_contracts_1.ReceiveKind.SendReady:
2113
2118
  return Promise.resolve();
2114
2119
  default:
@@ -2142,9 +2147,9 @@ class ZLinkFrameworkRuntimeHost {
2142
2147
  try {
2143
2148
  state.taskRunner.runDetached('mesh-node-local-route-dispatch', async () => {
2144
2149
  try {
2145
- const permit = await this.applicationJobQueue.acquire(state.abortController.signal);
2150
+ const permit = await this.applicationJobQueue.acquire(state.abortController.signal, 'local');
2146
2151
  permit.markApplicationQueued();
2147
- await (0, application_job_queue_scope_1.runWithApplicationJobPermit)(permit, () => channelRuntime.dispatchLocalMeshRoute(meshName, sourceNodeRid, ownedParts));
2152
+ await (0, application_job_queue_scope_2.runWithApplicationJobPermit)(permit, () => channelRuntime.dispatchLocalMeshRoute(meshName, sourceNodeRid, ownedParts));
2148
2153
  }
2149
2154
  finally {
2150
2155
  for (const part of ownedParts)
@@ -5,6 +5,7 @@ import type { ServiceSpotState } from '../foundation/service-stateful-registry';
5
5
  import type { ServiceInstanceActivationTarget, ServiceInstanceRouteFence } from '../foundation/service-stateful-wire-codec';
6
6
  import { type ServiceInstanceActivationRecoveryEnvelope } from '../foundation/service-instance-activation-recovery-codec';
7
7
  export interface ZLinkInstanceActivationAuthorityOptions {
8
+ readonly relocationPolicy?: (stableType: string) => import('../locations/internal-location-contracts').ZLinkObjectReserveRequest['actorRelocationPolicy'];
8
9
  readonly store: ZLinkObjectCreationStore & ZLinkAuthorityStore;
9
10
  readonly relocationStore?: ZLinkRelocationStore;
10
11
  readonly meshName: string;
@@ -16,7 +17,7 @@ export declare class ZLinkInstanceActivationAuthority implements ServiceAsyncIns
16
17
  private readonly options;
17
18
  private readonly pending;
18
19
  constructor(options: ZLinkInstanceActivationAuthorityOptions);
19
- read(target: ServiceInstanceActivationTarget): Promise<ServiceInstanceAuthorityRead>;
20
+ read(target: ServiceInstanceActivationTarget, instanceIntent?: true, activation?: ServiceInstanceActivationRecoveryEnvelope, acceptsLocal?: (route: ServiceInstanceRouteFence) => boolean): Promise<ServiceInstanceAuthorityRead>;
20
21
  reserve(activation: Omit<ServiceInstanceActivationRecoveryEnvelope, 'targetMeshName'>, signal?: AbortSignal): Promise<ServiceInstanceAuthorityReserve>;
21
22
  resume(target: ServiceInstanceActivationTarget, pending: ServicePendingInstanceActivation): Promise<ServiceInstanceActivationReservation>;
22
23
  commit(target: ServiceInstanceActivationTarget, reservation: ServiceInstanceActivationReservation, spot: ServiceSpotState, deadlineUnixMs?: bigint): Promise<{
@@ -17,9 +17,71 @@ class ZLinkInstanceActivationAuthority {
17
17
  constructor(options) {
18
18
  this.options = options;
19
19
  }
20
- async read(target) {
21
- const current = await this.options.store.readAuthority(authorityKey(target.targetSpotId));
22
- return current.kind === 'snapshot' ? readyRead(current, target) : { kind: 'missing' };
20
+ async read(target, instanceIntent, activation, acceptsLocal) {
21
+ const key = authorityKey(target.targetSpotId);
22
+ const current = await this.options.store.readAuthority(key);
23
+ if (current.kind !== 'snapshot')
24
+ return { kind: 'missing' };
25
+ const ready = (0, service_authority_payload_codec_1.decodeServiceInstanceAuthorityPayload)(current.payload);
26
+ const resolved = readyRead(current, target, ready);
27
+ if (ready?.state === 'ready' &&
28
+ resolved.kind === 'ready' &&
29
+ acceptsLocal?.(resolved.route) === true) {
30
+ return resolved;
31
+ }
32
+ if (activation !== undefined &&
33
+ current.allocation.objectKind === 'instance_spot' &&
34
+ (0, routing_id_1.routingIdsEqual)(current.allocation.descriptor.rid, target.targetNodeRid) &&
35
+ current.allocation.descriptorLifecycleGeneration === target.targetNodeGeneration) {
36
+ const reference = current.pendingCreation?.requestContentReference ?? ready?.activationRecovery?.reference;
37
+ if (reference !== undefined) {
38
+ const root = await this.options.relocationStore?.read((0, relocation_blob_1.relocationBlobReference)(reference));
39
+ if (root?.kind !== 'found') {
40
+ throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.DataLost, 'Stored Instance activation is missing.');
41
+ }
42
+ let stored;
43
+ try {
44
+ stored = (0, service_instance_activation_recovery_codec_1.decodeInstanceActivationRecoveryEnvelope)(root.bytes);
45
+ }
46
+ catch (error) {
47
+ if (!(error instanceof TypeError || error instanceof RangeError))
48
+ throw error;
49
+ throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.ProtocolError, 'Stored Instance activation is invalid.');
50
+ }
51
+ if (stored.operation.high === activation.operation.high &&
52
+ stored.operation.low === activation.operation.low &&
53
+ (stored.targetMeshName !== activation.targetMeshName ||
54
+ stored.target.stableType !== target.stableType ||
55
+ stored.target.descriptorVersion !== target.descriptorVersion ||
56
+ stored.deadlineUnixMs !== activation.deadlineUnixMs ||
57
+ (stored.metadataFrame === undefined) !== (activation.metadataFrame === undefined) ||
58
+ (stored.metadataFrame !== undefined &&
59
+ activation.metadataFrame !== undefined &&
60
+ Buffer.compare(stored.metadataFrame, activation.metadataFrame) !== 0))) {
61
+ throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.ProtocolError, 'Instance route does not match the stored activation.');
62
+ }
63
+ }
64
+ }
65
+ if (instanceIntent === true &&
66
+ current.allocation.state === 'active' &&
67
+ ready?.state === 'ready') {
68
+ if (current.allocation.objectKind !== 'instance_spot' ||
69
+ current.allocation.stableType !== target.stableType) {
70
+ throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotTypeMismatch, 'Instance activation type does not match the current authority.');
71
+ }
72
+ const released = await this.options.store.releaseEndedReservation?.(key, current.storeVersion.value, undefined, {
73
+ key: { kind: 'instance_spot', globalId: target.targetSpotId },
74
+ intent: { stableType: target.stableType },
75
+ actorRelocationPolicy: this.options.relocationPolicy?.(target.stableType)
76
+ });
77
+ if (released === true)
78
+ return { kind: 'missing' };
79
+ const refreshed = await this.options.store.readAuthority(key);
80
+ return refreshed.kind === 'snapshot'
81
+ ? readyRead(refreshed, target, (0, service_authority_payload_codec_1.decodeServiceInstanceAuthorityPayload)(refreshed.payload))
82
+ : { kind: 'missing' };
83
+ }
84
+ return resolved;
23
85
  }
24
86
  async reserve(activation, signal) {
25
87
  const target = activation.target;
@@ -49,6 +111,7 @@ class ZLinkInstanceActivationAuthority {
49
111
  try {
50
112
  reserved = await this.options.store.reserve({
51
113
  key: { kind: 'instance_spot', globalId: target.targetSpotId },
114
+ actorRelocationPolicy: this.options.relocationPolicy?.(target.stableType),
52
115
  intent: {
53
116
  stableType: target.stableType,
54
117
  requestContentReference: stored.reference.value,
@@ -207,7 +270,7 @@ class ZLinkInstanceActivationAuthority {
207
270
  }
208
271
  const current = await this.options.store.readAuthority(authorityKey(target.targetSpotId));
209
272
  if (current.kind === 'snapshot') {
210
- const ready = readyRead(current, target);
273
+ const ready = readyRead(current, target, (0, service_authority_payload_codec_1.decodeServiceInstanceAuthorityPayload)(current.payload));
211
274
  if (ready.kind === 'ready') {
212
275
  this.pending.delete(reservation.token);
213
276
  return { kind: 'lost', route: ready.route };
@@ -236,7 +299,7 @@ class ZLinkInstanceActivationAuthority {
236
299
  }
237
300
  const recovery = decoded.activationRecovery;
238
301
  if (recovery === undefined)
239
- return routeFromSnapshot(current);
302
+ return routeFromSnapshot(current, decoded.spotId);
240
303
  let completed = current;
241
304
  if (recovery.replayCursor < recovery.inboxSequence) {
242
305
  const cursorStored = await this.options.store.compareExchangeAuthority(key, current.storeVersion, {
@@ -338,19 +401,16 @@ class ZLinkInstanceActivationAuthority {
338
401
  }
339
402
  }
340
403
  exports.ZLinkInstanceActivationAuthority = ZLinkInstanceActivationAuthority;
341
- function readyRead(snapshot, target) {
342
- const decoded = (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(snapshot.payload) ??
343
- (0, service_authority_payload_codec_1.decodeServiceClosingSpotAuthority)(snapshot.payload);
344
- const creating = (0, service_authority_payload_codec_1.decodeServiceInstanceAuthorityPayload)(snapshot.payload);
345
- if (creating?.state === 'coldActivating' &&
404
+ function readyRead(snapshot, target, decoded) {
405
+ if (decoded?.state === 'coldActivating' &&
346
406
  snapshot.allocation.objectKind === 'instance_spot' &&
347
- creating.stableType === target.stableType &&
348
- creating.spotId === target.targetSpotId &&
349
- creating.ownerId === snapshot.ownerId &&
350
- creating.ownerLeaseGeneration === snapshot.ownerLeaseGeneration &&
351
- creating.ownerMeshName === snapshot.allocation.descriptor.meshName &&
352
- creating.ownerNodeGeneration === snapshot.allocation.descriptorLifecycleGeneration &&
353
- (0, routing_id_1.routingIdsEqual)(creating.ownerNodeRid, snapshot.allocation.descriptor.rid) &&
407
+ decoded.stableType === target.stableType &&
408
+ decoded.spotId === target.targetSpotId &&
409
+ decoded.ownerId === snapshot.ownerId &&
410
+ decoded.ownerLeaseGeneration === snapshot.ownerLeaseGeneration &&
411
+ decoded.ownerMeshName === snapshot.allocation.descriptor.meshName &&
412
+ decoded.ownerNodeGeneration === snapshot.allocation.descriptorLifecycleGeneration &&
413
+ (0, routing_id_1.routingIdsEqual)(decoded.ownerNodeRid, snapshot.allocation.descriptor.rid) &&
354
414
  (0, routing_id_1.routingIdsEqual)(target.targetNodeRid, snapshot.allocation.descriptor.rid) &&
355
415
  target.targetNodeGeneration === snapshot.allocation.descriptorLifecycleGeneration) {
356
416
  return {
@@ -360,7 +420,8 @@ function readyRead(snapshot, target) {
360
420
  authority: snapshot
361
421
  };
362
422
  }
363
- if (decoded?.kind !== 'instance_spot' ||
423
+ if (decoded === undefined ||
424
+ decoded.state === 'coldActivating' ||
364
425
  decoded.stableType !== target.stableType ||
365
426
  decoded.spotId !== target.targetSpotId ||
366
427
  snapshot.allocation.objectKind !== 'instance_spot' ||
@@ -374,7 +435,7 @@ function readyRead(snapshot, target) {
374
435
  target.targetNodeGeneration !== snapshot.allocation.descriptorLifecycleGeneration) {
375
436
  return { kind: 'missing' };
376
437
  }
377
- return { kind: 'ready', route: routeFromSnapshot(snapshot), authority: snapshot };
438
+ return { kind: 'ready', route: routeFromSnapshot(snapshot, decoded.spotId), authority: snapshot };
378
439
  }
379
440
  function requireCommitIdentity(target, reservation, creating, spot, meshName) {
380
441
  if (creating.allocation.state !== 'reserved' ||
@@ -392,16 +453,19 @@ function requireCommitIdentity(target, reservation, creating, spot, meshName) {
392
453
  throw new Error('Instance activation Ready identity does not match its exact reservation.');
393
454
  }
394
455
  }
395
- function routeFromSnapshot(snapshot) {
396
- const decoded = (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(snapshot.payload) ??
397
- (0, service_authority_payload_codec_1.decodeServiceClosingSpotAuthority)(snapshot.payload);
398
- if (decoded?.kind !== 'instance_spot') {
399
- throw new Error('Instance authority is not Ready.');
456
+ function routeFromSnapshot(snapshot, spotId) {
457
+ if (spotId === undefined) {
458
+ const decoded = (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(snapshot.payload) ??
459
+ (0, service_authority_payload_codec_1.decodeServiceClosingSpotAuthority)(snapshot.payload);
460
+ if (decoded?.kind !== 'instance_spot') {
461
+ throw new Error('Instance authority is not Ready.');
462
+ }
463
+ spotId = decoded.spotId;
400
464
  }
401
465
  return {
402
466
  targetNodeRid: String(snapshot.allocation.descriptor.rid),
403
467
  targetNodeGeneration: snapshot.allocation.descriptorLifecycleGeneration,
404
- targetSpotId: decoded.spotId,
468
+ targetSpotId: spotId,
405
469
  objectGeneration: snapshot.objectGeneration,
406
470
  ownerId: snapshot.ownerId,
407
471
  authorityOwnerGeneration: snapshot.authorityOwnerGeneration,
@@ -3227,9 +3227,9 @@ class LocalTargetPort {
3227
3227
  if (runtime === undefined) {
3228
3228
  throw new Error('Relocated Entry Spot Actor dispatch is unavailable.');
3229
3229
  }
3230
- return runtime.dispatchEntryActorPacket(hidden.actor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
3230
+ return runtime.dispatchEntryActorPacket('remote', hidden.actor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
3231
3231
  }
3232
- return this.requireSpotManager().dispatchRoutedActorPacket(state.spotId, hidden.actor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
3232
+ return this.requireSpotManager().dispatchRoutedActorPacket('remote', state.spotId, hidden.actor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
3233
3233
  });
3234
3234
  hidden.replayResults.push(...results);
3235
3235
  }
@@ -31,6 +31,7 @@ export declare class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTr
31
31
  private reportInstanceRequestError;
32
32
  private traceInstanceAddress;
33
33
  private resolveExisting;
34
+ private reactivationCall;
34
35
  private selectMissingTarget;
35
36
  private validateExisting;
36
37
  private encode;