@zlink-systems/framework 0.27.0 → 0.29.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/Actors/ZLinkActorClient.d.ts +1 -1
- package/dist/contracts/Channels/Calls.d.ts +1 -1
- package/dist/contracts/Configuration/Builders.d.ts +2 -1
- package/dist/contracts/Configuration/Configs.d.ts +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +3 -0
- package/dist/contracts/Configuration/InternalDefaults.js +4 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +9 -0
- package/dist/contracts/Configuration/RegistrationNormalizers.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationNormalizers.js +16 -0
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +3 -5
- package/dist/contracts/Configuration/RegistrationValidators.js +0 -2
- package/dist/contracts/Spots/Contracts.d.ts +1 -1
- package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
- package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +7 -10
- package/dist/runtime/actors/actor-mailbox.d.ts +2 -2
- package/dist/runtime/actors/actor-mailbox.js +2 -2
- package/dist/runtime/actors/actor-request-deadline.d.ts +1 -3
- package/dist/runtime/actors/actor-request-deadline.js +4 -29
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
- package/dist/runtime/backend/contracts/index.d.ts +1 -4
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -0
- package/dist/runtime/backend/node/node-backend-adapter-support.js +35 -4
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +10 -27
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +1 -3
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
- package/dist/runtime/channels/channel-clients.js +8 -10
- package/dist/runtime/channels/channel-envelope.d.ts +1 -1
- package/dist/runtime/channels/channel-envelope.js +4 -10
- package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
- package/dist/runtime/channels/channel-outbound-operations.js +20 -36
- package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
- package/dist/runtime/channels/channel-runtime-manager.js +8 -8
- package/dist/runtime/channels/channel-socket-options.js +0 -10
- package/dist/runtime/channels/channel-socket-registry.d.ts +1 -1
- package/dist/runtime/channels/channel-socket-registry.js +3 -14
- package/dist/runtime/channels/channel-transports.d.ts +10 -14
- package/dist/runtime/channels/channel-transports.js +11 -14
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +1 -3
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
- package/dist/runtime/channels/source-spot-router.d.ts +1 -1
- package/dist/runtime/channels/source-spot-router.js +2 -4
- package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
- package/dist/runtime/channels/spot-node-route-transport.js +2 -3
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
- package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
- package/dist/runtime/execution/serial-execution-queue.d.ts +12 -3
- package/dist/runtime/execution/serial-execution-queue.js +116 -28
- package/dist/runtime/foundation/operation-registry.d.ts +3 -2
- package/dist/runtime/foundation/operation-registry.js +5 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +17 -11
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +0 -2
- package/dist/runtime/foundation/service-authority-payload-codec.js +0 -43
- package/dist/runtime/foundation/service-stateful-registry.d.ts +4 -3
- package/dist/runtime/foundation/service-stateful-registry.js +5 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +1 -8
- package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -11
- package/dist/runtime/foundation/service-stateful-wire-codec.js +1 -23
- package/dist/runtime/foundation/service-topology-registry.d.ts +5 -0
- package/dist/runtime/foundation/service-topology-registry.js +16 -17
- package/dist/runtime/host/actor-packet-relay.d.ts +2 -2
- package/dist/runtime/host/actor-packet-relay.js +8 -10
- package/dist/runtime/host/index.js +1 -15
- package/dist/runtime/host/instance-activation-authority.d.ts +0 -1
- package/dist/runtime/host/instance-activation-authority.js +46 -97
- package/dist/runtime/host/remote-bound-session-relay.js +8 -8
- package/dist/runtime/host/spot-address-transport.d.ts +1 -9
- package/dist/runtime/host/spot-address-transport.js +47 -87
- package/dist/runtime/host/stateful-authority-route-runtime.d.ts +1 -0
- package/dist/runtime/host/stateful-authority-route-runtime.js +17 -9
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +2 -0
- package/dist/runtime/locations/in-memory-authority-store.js +22 -8
- package/dist/runtime/locations/in-memory-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-location-store.js +3 -0
- package/dist/runtime/locations/internal-store-contracts.d.ts +1 -1
- package/dist/runtime/locations/location-store-repository.d.ts +1 -0
- package/dist/runtime/locations/location-store-repository.js +98 -53
- package/dist/runtime/messaging/request-deadline.d.ts +3 -0
- package/dist/runtime/messaging/request-deadline.js +39 -0
- package/dist/runtime/messaging/submission-result.d.ts +2 -1
- package/dist/runtime/messaging/submission-result.js +11 -4
- package/dist/runtime/spots/spot-outbound.d.ts +3 -5
- package/dist/runtime/spots/spot-outbound.js +12 -15
- package/dist/runtime/spots/spot-serial-executor.js +4 -1
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
- package/dist/runtime/spots/spot-serial-turn-executor.js +5 -0
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +14 -14
- package/dist/runtime/streams/bound-session-service.js +1 -1
- package/dist/runtime/streams/index.d.ts +2 -3
- package/dist/runtime/streams/index.js +6 -5
- package/dist/runtime/streams/managed-stream.d.ts +2 -2
- package/dist/runtime/streams/managed-stream.js +3 -5
- package/dist/runtime/streams/native-fallback-bound-session.js +13 -16
- package/dist/runtime/streams/protocol.js +0 -9
- package/dist/runtime/streams/session-calls.d.ts +5 -7
- package/dist/runtime/streams/session-calls.js +6 -23
- package/dist/runtime/streams/session-context.d.ts +4 -8
- package/dist/runtime/streams/session-context.js +3 -32
- package/dist/runtime/streams/session-serial-executor.d.ts +0 -1
- package/dist/runtime/streams/session-serial-executor.js +0 -3
- package/dist/runtime/streams/stream-message-utils.d.ts +0 -1
- package/dist/runtime/streams/stream-message-utils.js +0 -20
- package/dist/runtime/streams/stream-session-runtime.d.ts +6 -3
- package/dist/runtime/streams/stream-session-runtime.js +40 -85
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
- package/src/contracts/Channels/Calls.ts +1 -1
- package/src/contracts/Configuration/Builders.ts +2 -1
- package/src/contracts/Configuration/Configs.ts +0 -1
- package/src/contracts/Configuration/InternalDefaults.ts +4 -0
- package/src/contracts/Configuration/RegistrationBuilders.ts +13 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +25 -0
- package/src/contracts/Configuration/RegistrationTypes.ts +3 -5
- package/src/contracts/Configuration/RegistrationValidators.ts +0 -4
- package/src/contracts/Spots/Contracts.ts +1 -1
- package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
- package/src/contracts/Streams/IZLinkSession.ts +2 -3
- package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
- package/src/runtime/actors/actor-client.ts +9 -15
- package/src/runtime/actors/actor-mailbox.ts +7 -2
- package/src/runtime/actors/actor-request-deadline.ts +4 -49
- package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
- package/src/runtime/backend/contracts/index.ts +1 -8
- package/src/runtime/backend/node/node-backend-adapter-support.ts +45 -5
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +15 -41
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +1 -7
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +1 -1
- package/src/runtime/channels/channel-clients.ts +9 -19
- package/src/runtime/channels/channel-envelope.ts +16 -28
- package/src/runtime/channels/channel-outbound-operations.ts +36 -38
- package/src/runtime/channels/channel-runtime-manager.ts +6 -28
- package/src/runtime/channels/channel-socket-options.ts +0 -13
- package/src/runtime/channels/channel-socket-registry.ts +3 -17
- package/src/runtime/channels/channel-transports.ts +7 -33
- package/src/runtime/channels/local-spot-route-transport.ts +1 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
- package/src/runtime/channels/source-spot-router.ts +2 -9
- package/src/runtime/channels/spot-node-route-transport.ts +2 -7
- package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
- package/src/runtime/execution/serial-execution-queue.ts +117 -29
- package/src/runtime/foundation/operation-registry.ts +16 -9
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +17 -14
- package/src/runtime/foundation/service-authority-payload-codec.ts +0 -46
- package/src/runtime/foundation/service-stateful-registry.ts +10 -5
- package/src/runtime/foundation/service-stateful-runtime.ts +103 -181
- package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -25
- package/src/runtime/foundation/service-topology-registry.ts +30 -20
- package/src/runtime/host/actor-packet-relay.ts +8 -15
- package/src/runtime/host/index.ts +2 -26
- package/src/runtime/host/instance-activation-authority.ts +58 -125
- package/src/runtime/host/remote-bound-session-relay.ts +8 -16
- package/src/runtime/host/spot-address-transport.ts +107 -166
- package/src/runtime/host/stateful-authority-route-runtime.ts +22 -9
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +42 -8
- package/src/runtime/locations/in-memory-location-store.ts +8 -0
- package/src/runtime/locations/internal-store-contracts.ts +1 -0
- package/src/runtime/locations/location-store-repository.ts +130 -68
- package/src/runtime/messaging/request-deadline.ts +58 -0
- package/src/runtime/messaging/submission-result.ts +18 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/spot-outbound.ts +14 -24
- package/src/runtime/spots/spot-serial-executor.ts +4 -1
- package/src/runtime/spots/spot-serial-turn-executor.ts +10 -0
- package/src/runtime/streams/bound-actor-relay-sender.ts +12 -26
- package/src/runtime/streams/bound-session-service.ts +1 -1
- package/src/runtime/streams/index.ts +5 -5
- package/src/runtime/streams/managed-stream.ts +3 -13
- package/src/runtime/streams/native-fallback-bound-session.ts +13 -25
- package/src/runtime/streams/protocol.ts +0 -13
- package/src/runtime/streams/session-calls.ts +8 -34
- package/src/runtime/streams/session-context.ts +6 -47
- package/src/runtime/streams/session-serial-executor.ts +0 -8
- package/src/runtime/streams/stream-message-utils.ts +1 -27
- package/src/runtime/streams/stream-session-runtime.ts +54 -97
- package/dist/runtime/streams/session-requests.d.ts +0 -25
- package/dist/runtime/streams/session-requests.js +0 -101
- package/src/runtime/streams/session-requests.ts +0 -110
|
@@ -273,11 +273,11 @@ class ZLinkActorPacketRelay {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
-
async relayActorPacket(actor, frameHeader, payload
|
|
277
|
-
if (await this.relayRemoteActorPacket(actor, frameHeader, payload
|
|
276
|
+
async relayActorPacket(actor, frameHeader, payload) {
|
|
277
|
+
if (await this.relayRemoteActorPacket(actor, frameHeader, payload)) {
|
|
278
278
|
return true;
|
|
279
279
|
}
|
|
280
|
-
return this.relayLocalActorPacket(actor, frameHeader, payload
|
|
280
|
+
return this.relayLocalActorPacket(actor, frameHeader, payload);
|
|
281
281
|
}
|
|
282
282
|
async confirmRemoteSessionBinding(actor, sessionNodeRid, sessionRid, signal, options) {
|
|
283
283
|
const target = this.targets.targetForActorRef(actor);
|
|
@@ -349,7 +349,7 @@ class ZLinkActorPacketRelay {
|
|
|
349
349
|
bindingGeneration: binding.bindingGeneration
|
|
350
350
|
});
|
|
351
351
|
}
|
|
352
|
-
async relayRemoteActorPacket(actor, frameHeader, payload
|
|
352
|
+
async relayRemoteActorPacket(actor, frameHeader, payload) {
|
|
353
353
|
const streamRuntime = this.options.streamBindingRuntime();
|
|
354
354
|
const responseTarget = await streamRuntime.captureBoundSessionResponseTarget(actor);
|
|
355
355
|
const localNode = this.options.spotNodeRuntime()?.primaryMeshNode;
|
|
@@ -419,7 +419,7 @@ class ZLinkActorPacketRelay {
|
|
|
419
419
|
if ((frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send || frameHeader.requestSeq === undefined) &&
|
|
420
420
|
remoteAddress.spotKind === contracts_1.ZLinkSpotKind.Entry &&
|
|
421
421
|
this.options.routeTransport.submit !== undefined) {
|
|
422
|
-
const result = await this.options.routeTransport.submit(remoteAddress.routerChannelId, String(remoteAddress.targetNodeRid), actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET, request
|
|
422
|
+
const result = await this.options.routeTransport.submit(remoteAddress.routerChannelId, String(remoteAddress.targetNodeRid), actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET, request);
|
|
423
423
|
if (result.status !== submission_result_1.ZLinkSubmitStatus.Submitted) {
|
|
424
424
|
throw new Error(`Actor '${actor.actorId}' remote node relay was not admitted.`);
|
|
425
425
|
}
|
|
@@ -427,8 +427,7 @@ class ZLinkActorPacketRelay {
|
|
|
427
427
|
}
|
|
428
428
|
if (frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send || frameHeader.requestSeq === undefined) {
|
|
429
429
|
await this.options.routeTransport.sendToSpot(remoteAddress, request, {
|
|
430
|
-
packetName: actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET
|
|
431
|
-
signal
|
|
430
|
+
packetName: actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET
|
|
432
431
|
});
|
|
433
432
|
return true;
|
|
434
433
|
}
|
|
@@ -438,7 +437,7 @@ class ZLinkActorPacketRelay {
|
|
|
438
437
|
throw new Error(`Remote actor packet relay reply was empty for '${actor.actorId}'.`);
|
|
439
438
|
}
|
|
440
439
|
return JSON.parse(parts[0].getString('utf8'));
|
|
441
|
-
}
|
|
440
|
+
});
|
|
442
441
|
const actorPacketTarget = this.targets.decodeFromWire(reply.actorPacketTarget);
|
|
443
442
|
const currentStoredRoute = await streamRuntime.sessionRouteFence(actor.actorId);
|
|
444
443
|
const currentAggregateRoute = aggregateOwner === undefined ? undefined : await aggregateOwner.committedRoute(actor.actorId);
|
|
@@ -526,8 +525,7 @@ class ZLinkActorPacketRelay {
|
|
|
526
525
|
}
|
|
527
526
|
return (0, actor_routed_json_request_1.requestRoutedJsonReply)(this.options.routeTransport, withDefaultSpotKind(target), request, { timeoutMs: this.options.requestTimeoutMs, signal }, unavailableMessage, decodeReply);
|
|
528
527
|
}
|
|
529
|
-
async relayLocalActorPacket(actor, frameHeader, payload
|
|
530
|
-
void signal;
|
|
528
|
+
async relayLocalActorPacket(actor, frameHeader, payload) {
|
|
531
529
|
const state = this.options.actorManager()?.getState(actor.actorId);
|
|
532
530
|
const spotId = state?.spotId;
|
|
533
531
|
const hasActiveSpot = spotId !== undefined && this.options.spotManager()?.hasActiveSpot(spotId) === true;
|
|
@@ -70,7 +70,6 @@ const user_spot_creation_coordinator_1 = require("./user-spot-creation-coordinat
|
|
|
70
70
|
const HOST_SHUTDOWN_POLL_INTERVAL_MS = 100;
|
|
71
71
|
const HANDOFF_ACCEPTANCE_POLL_INTERVAL_MS = 10;
|
|
72
72
|
const DEFAULT_HOST_CONTROL_TIMEOUT_MS = 30_000;
|
|
73
|
-
const LEGACY_MESH_SEND_TIMEOUT_MS = 1000;
|
|
74
73
|
class ZLinkFrameworkRuntimeHost {
|
|
75
74
|
options;
|
|
76
75
|
backendAdapterFactory;
|
|
@@ -168,16 +167,6 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
168
167
|
this.fanoutRuntime = new topology_runtime_projections_1.ZLinkFanoutRuntimeProjection(() => this.channelRuntime, () => this.runtimeState);
|
|
169
168
|
this.meshRouters = new mesh_router_resolver_1.MeshRouterResolver(options.registration);
|
|
170
169
|
this.spotRouterChannelIdForMesh = this.meshRouters.spotRouterChannelIdByMesh();
|
|
171
|
-
const sendTimeoutMsForSpotMesh = (meshName) => options.registration.spotNodes.get(meshName)?.router?.sendTimeoutMs ??
|
|
172
|
-
LEGACY_MESH_SEND_TIMEOUT_MS;
|
|
173
|
-
const sendTimeoutMsForSpotRouteChannel = (routeChannelId) => {
|
|
174
|
-
const routeChannel = options.registration.routeChannelOptions.get(routeChannelId);
|
|
175
|
-
if (routeChannel !== undefined) {
|
|
176
|
-
return routeChannel.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS;
|
|
177
|
-
}
|
|
178
|
-
return sendTimeoutMsForSpotMesh(routeChannelId);
|
|
179
|
-
};
|
|
180
|
-
const defaultSpotSendTimeoutMs = Math.max(LEGACY_MESH_SEND_TIMEOUT_MS, ...[...options.registration.spotNodes.values()].map((node) => node.router?.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS), ...[...options.registration.routeChannelOptions.values()].map((route) => route.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS));
|
|
181
170
|
this.routeTransport = new channels_1.ZLinkRuntimeRouteTransport(() => this.channelRuntime, (routerChannelId) => this.meshRouters.canUseRouterChannel(routerChannelId), () => this.spotNodeRuntime, { serializers: options.registration.messageSerializers }, (meshName, targetNodeRid) => this.meshRouters.classifyManualNodeTarget(meshName, targetNodeRid), (meshName, sourceNodeRid, parts) => this.submitLocalMeshRoute(meshName, sourceNodeRid, parts), this.metrics, () => this.flowCreationEnabled(), () => this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink).flow);
|
|
182
171
|
this.spotAddressTransport = new spot_address_transport_1.ZLinkHostSpotAddressTransport({
|
|
183
172
|
resolver: () => this.createLocationSpotRouteResolver(),
|
|
@@ -190,9 +179,6 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
190
179
|
completions: (meshName) => this.spotNodeRuntime?.meshCompletionTable(meshName),
|
|
191
180
|
codecs: { serializers: options.registration.messageSerializers },
|
|
192
181
|
defaultRequestTimeoutMs: options.registration.requestTimeoutMs ?? Registration_1.DEFAULT_REQUEST_TIMEOUT_MS,
|
|
193
|
-
defaultSendTimeoutMs: defaultSpotSendTimeoutMs,
|
|
194
|
-
sendTimeoutMsForMesh: sendTimeoutMsForSpotMesh,
|
|
195
|
-
sendTimeoutMsForRouteChannel: sendTimeoutMsForSpotRouteChannel,
|
|
196
182
|
dispatchErrors: this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink)
|
|
197
183
|
});
|
|
198
184
|
this.locationOwner = new location_runtime_owner_1.ZLinkLocationRuntimeOwner({
|
|
@@ -233,7 +219,7 @@ class ZLinkFrameworkRuntimeHost {
|
|
|
233
219
|
? Promise.resolve()
|
|
234
220
|
: this.boundSessionRelay.actorPackets.confirmRemoteSessionBinding(actor, sessionNode.status().routingId, sessionRid, signal, options);
|
|
235
221
|
},
|
|
236
|
-
relay: (actor, header, payload
|
|
222
|
+
relay: (actor, header, payload) => this.boundSessionRelay.actorPackets.relayActorPacket(actor, header, payload),
|
|
237
223
|
notifyDisconnected: (actor, signal) => this.boundSessionRelay.actorPackets.notifyBoundActorDisconnected(actor, signal)
|
|
238
224
|
});
|
|
239
225
|
this.actorHandoff = new actors_1.ZLinkActorHandoffCoordinator({
|
|
@@ -27,6 +27,5 @@ export declare class ZLinkInstanceActivationAuthority implements ServiceAsyncIns
|
|
|
27
27
|
abort(target: ServiceInstanceActivationTarget, reservation: ServiceInstanceActivationReservation): Promise<void>;
|
|
28
28
|
private requireOwner;
|
|
29
29
|
private deleteOrphan;
|
|
30
|
-
private awaitConcurrentActivation;
|
|
31
30
|
private requirePending;
|
|
32
31
|
}
|
|
@@ -11,7 +11,6 @@ const relocation_blob_1 = require("../locations/relocation-blob");
|
|
|
11
11
|
const service_instance_activation_recovery_codec_1 = require("../foundation/service-instance-activation-recovery-codec");
|
|
12
12
|
const CREATION_REQUEST_RETENTION_MS = 24 * 60 * 60 * 1_000;
|
|
13
13
|
const MAX_CREATION_REQUEST_BYTES = 1024 * 1024;
|
|
14
|
-
const ACTIVATION_JOIN_POLL_INTERVAL_MS = 10;
|
|
15
14
|
class ZLinkInstanceActivationAuthority {
|
|
16
15
|
options;
|
|
17
16
|
pending = new Map();
|
|
@@ -48,68 +47,64 @@ class ZLinkInstanceActivationAuthority {
|
|
|
48
47
|
}
|
|
49
48
|
let reserved;
|
|
50
49
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
50
|
+
reserved = await this.options.store.reserve({
|
|
51
|
+
key: { kind: 'instance_spot', globalId: target.targetSpotId },
|
|
52
|
+
intent: {
|
|
53
|
+
stableType: target.stableType,
|
|
54
|
+
requestContentReference: stored.reference.value,
|
|
55
|
+
requestSha256: requestHash,
|
|
56
|
+
requestEncodedSize: BigInt(requestBytes.byteLength)
|
|
57
|
+
},
|
|
58
|
+
target: {
|
|
59
|
+
meshName: this.options.meshName,
|
|
60
|
+
nodeRid: target.targetNodeRid,
|
|
61
|
+
nodeLifecycleGeneration: target.targetNodeGeneration,
|
|
62
|
+
owner
|
|
63
|
+
},
|
|
64
|
+
creatingPayload: (0, service_authority_payload_codec_1.encodeServiceInstanceAuthorityPayload)({
|
|
65
|
+
state: 'coldActivating',
|
|
66
|
+
stableType: target.stableType,
|
|
67
|
+
spotId: target.targetSpotId,
|
|
68
|
+
ownerId: owner.ownerId,
|
|
69
|
+
ownerLeaseGeneration: owner.leaseGeneration,
|
|
70
|
+
ownerMeshName: this.options.meshName,
|
|
71
|
+
ownerNodeRid: target.targetNodeRid,
|
|
72
|
+
ownerNodeGeneration: target.targetNodeGeneration
|
|
73
|
+
}),
|
|
74
|
+
capacity: {
|
|
75
|
+
actors: 0,
|
|
76
|
+
spots: 1,
|
|
77
|
+
spotType: {
|
|
78
|
+
objectKind: 'instance_spot',
|
|
68
79
|
stableType: target.stableType,
|
|
69
|
-
|
|
70
|
-
ownerId: owner.ownerId,
|
|
71
|
-
ownerLeaseGeneration: owner.leaseGeneration,
|
|
72
|
-
ownerMeshName: this.options.meshName,
|
|
73
|
-
ownerNodeRid: target.targetNodeRid,
|
|
74
|
-
ownerNodeGeneration: target.targetNodeGeneration
|
|
75
|
-
}),
|
|
76
|
-
capacity: {
|
|
77
|
-
actors: 0,
|
|
78
|
-
spots: 1,
|
|
79
|
-
spotType: {
|
|
80
|
-
objectKind: 'instance_spot',
|
|
81
|
-
stableType: target.stableType,
|
|
82
|
-
count: 1
|
|
83
|
-
}
|
|
80
|
+
count: 1
|
|
84
81
|
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
break;
|
|
88
|
-
this.options.metrics?.recordInstanceSpotClaimConflict(this.options.meshName, target.stableType, 'already_exists');
|
|
89
|
-
await this.deleteOrphan(stored.reference);
|
|
90
|
-
return readyExisting(reserved.current, target);
|
|
91
|
-
}
|
|
82
|
+
}
|
|
83
|
+
}, undefined, activation.deadlineUnixMs);
|
|
92
84
|
}
|
|
93
85
|
catch (error) {
|
|
94
86
|
await this.deleteOrphan(stored.reference);
|
|
95
87
|
throw error;
|
|
96
88
|
}
|
|
97
|
-
if (reserved.kind === 'conflict' &&
|
|
98
|
-
reserved.current.kind === 'snapshot' &&
|
|
99
|
-
reserved.current.allocation.objectKind === 'instance_spot' &&
|
|
100
|
-
reserved.current.allocation.stableType === target.stableType &&
|
|
101
|
-
reserved.current.allocation.state === 'reserved') {
|
|
102
|
-
this.options.metrics?.recordInstanceSpotClaimConflict(this.options.meshName, target.stableType, 'activation_in_progress');
|
|
103
|
-
await this.deleteOrphan(stored.reference);
|
|
104
|
-
return await this.awaitConcurrentActivation(target, activation.deadlineUnixMs);
|
|
105
|
-
}
|
|
106
89
|
if (reserved.kind !== 'reserved') {
|
|
107
|
-
|
|
90
|
+
const conflictReason = reserved.kind === 'alreadyExists'
|
|
91
|
+
? 'already_exists'
|
|
92
|
+
: reserved.kind === 'conflict' &&
|
|
93
|
+
reserved.current.kind === 'snapshot' &&
|
|
94
|
+
reserved.current.allocation.objectKind === 'instance_spot' &&
|
|
95
|
+
reserved.current.allocation.stableType === target.stableType &&
|
|
96
|
+
reserved.current.allocation.state === 'reserved'
|
|
97
|
+
? 'activation_in_progress'
|
|
98
|
+
: reserved.kind;
|
|
99
|
+
this.options.metrics?.recordInstanceSpotClaimConflict(this.options.meshName, target.stableType, conflictReason);
|
|
108
100
|
await this.deleteOrphan(stored.reference);
|
|
101
|
+
if (reserved.kind === 'typeMismatch') {
|
|
102
|
+
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotTypeMismatch, `Instance activation reservation failed: ${reserved.kind}.`);
|
|
103
|
+
}
|
|
109
104
|
if (reserved.kind === 'placementCapacityExhausted') {
|
|
110
105
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.PlacementCapacityExhausted, `Instance Spot placement capacity is exhausted for '${String(target.targetSpotId)}'.`);
|
|
111
106
|
}
|
|
112
|
-
throw new
|
|
107
|
+
throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.Unavailable, `Instance activation reservation failed: ${reserved.kind}.`);
|
|
113
108
|
}
|
|
114
109
|
const reservation = {
|
|
115
110
|
attempt: reserved.creating.objectGeneration,
|
|
@@ -334,27 +329,6 @@ class ZLinkInstanceActivationAuthority {
|
|
|
334
329
|
// best-effort deletion fails.
|
|
335
330
|
}
|
|
336
331
|
}
|
|
337
|
-
async awaitConcurrentActivation(target, deadlineUnixMs) {
|
|
338
|
-
const key = authorityKey(target.targetSpotId);
|
|
339
|
-
const deadlineMs = performance.now() + Number(deadlineUnixMs - BigInt(Date.now()));
|
|
340
|
-
while (performance.now() <= deadlineMs) {
|
|
341
|
-
const current = await this.options.store.readAuthority(key);
|
|
342
|
-
if (current.kind === 'snapshot') {
|
|
343
|
-
if (current.allocation.objectKind !== 'instance_spot' ||
|
|
344
|
-
current.allocation.stableType !== target.stableType) {
|
|
345
|
-
throw new Error('Concurrent Instance activation resolved to a different Spot type.');
|
|
346
|
-
}
|
|
347
|
-
if (current.allocation.state === 'active') {
|
|
348
|
-
return readyExisting(current, target);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
throw new Error('Concurrent Instance activation ended before the Ready barrier.');
|
|
353
|
-
}
|
|
354
|
-
await waitForActivationJoin(deadlineMs);
|
|
355
|
-
}
|
|
356
|
-
throw new Error(`Concurrent Instance activation for '${target.targetSpotId}' did not reach Ready before deadline.`);
|
|
357
|
-
}
|
|
358
332
|
requirePending(reservation) {
|
|
359
333
|
const pending = this.pending.get(reservation.token);
|
|
360
334
|
if (pending === undefined || pending.creating.objectGeneration !== reservation.attempt) {
|
|
@@ -402,31 +376,6 @@ function readyRead(snapshot, target) {
|
|
|
402
376
|
}
|
|
403
377
|
return { kind: 'ready', route: routeFromSnapshot(snapshot), authority: snapshot };
|
|
404
378
|
}
|
|
405
|
-
function readyExisting(snapshot, target) {
|
|
406
|
-
const decoded = (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(snapshot.payload) ??
|
|
407
|
-
(0, service_authority_payload_codec_1.decodeServiceClosingSpotAuthority)(snapshot.payload);
|
|
408
|
-
if (decoded?.kind !== 'instance_spot' ||
|
|
409
|
-
decoded.stableType !== target.stableType ||
|
|
410
|
-
decoded.spotId !== target.targetSpotId ||
|
|
411
|
-
snapshot.allocation.objectKind !== 'instance_spot' ||
|
|
412
|
-
snapshot.allocation.state !== 'active' ||
|
|
413
|
-
decoded.ownerId !== snapshot.ownerId ||
|
|
414
|
-
decoded.ownerLeaseGeneration !== snapshot.ownerLeaseGeneration ||
|
|
415
|
-
decoded.ownerMeshName !== snapshot.allocation.descriptor.meshName ||
|
|
416
|
-
decoded.ownerNodeGeneration !== snapshot.allocation.descriptorLifecycleGeneration ||
|
|
417
|
-
!(0, routing_id_1.routingIdsEqual)(decoded.ownerNodeRid, snapshot.allocation.descriptor.rid)) {
|
|
418
|
-
throw new Error('Existing Instance authority is not a matching Ready allocation.');
|
|
419
|
-
}
|
|
420
|
-
return { kind: 'ready', route: routeFromSnapshot(snapshot), authority: snapshot };
|
|
421
|
-
}
|
|
422
|
-
async function waitForActivationJoin(deadlineMs) {
|
|
423
|
-
const remaining = deadlineMs - performance.now();
|
|
424
|
-
if (remaining <= 0)
|
|
425
|
-
return;
|
|
426
|
-
await new Promise((resolve) => {
|
|
427
|
-
setTimeout(resolve, Math.min(ACTIVATION_JOIN_POLL_INTERVAL_MS, remaining));
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
379
|
function requireCommitIdentity(target, reservation, creating, spot, meshName) {
|
|
431
380
|
if (creating.allocation.state !== 'reserved' ||
|
|
432
381
|
creating.allocation.objectKind !== 'instance_spot' ||
|
|
@@ -420,7 +420,7 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
420
420
|
const actorRef = currentActorRef(state, fallbackActorRef);
|
|
421
421
|
const remoteTarget = fallbackBoundSessionTarget ?? state?.remoteBoundSessionTarget;
|
|
422
422
|
if (remoteTarget !== undefined) {
|
|
423
|
-
await this.sendRemoteBoundSessionResponse(remoteTarget, actor.context.actorId, packetName, requestSeq, response, replyOptions
|
|
423
|
+
await this.sendRemoteBoundSessionResponse(remoteTarget, actor.context.actorId, packetName, requestSeq, response, replyOptions);
|
|
424
424
|
return;
|
|
425
425
|
}
|
|
426
426
|
if (actorRef === undefined) {
|
|
@@ -444,7 +444,7 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
444
444
|
const actorRef = currentActorRef(state, fallbackActorRef) ?? this.options.destroyedActorRefs.get(actorId);
|
|
445
445
|
const remoteTarget = fallbackBoundSessionTarget ?? state?.remoteBoundSessionTarget;
|
|
446
446
|
if (remoteTarget !== undefined) {
|
|
447
|
-
await this.sendRemoteBoundSessionError(remoteTarget, actorId, packetName, requestSeq, error, metadata
|
|
447
|
+
await this.sendRemoteBoundSessionError(remoteTarget, actorId, packetName, requestSeq, error, metadata);
|
|
448
448
|
return;
|
|
449
449
|
}
|
|
450
450
|
if (actorRef === undefined) {
|
|
@@ -458,7 +458,7 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
458
458
|
.streamBindingRuntime()
|
|
459
459
|
.sendNativeBoundSessionError(actorSessionNode, actorRef, packetName, requestSeq, error, metadata, signal);
|
|
460
460
|
}
|
|
461
|
-
async sendRemoteBoundSessionResponse(target, actorId, packetName, requestSeq, message, replyOptions
|
|
461
|
+
async sendRemoteBoundSessionResponse(target, actorId, packetName, requestSeq, message, replyOptions) {
|
|
462
462
|
const actorPacketTarget = (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.options.actorPacketTargetForState(actorId));
|
|
463
463
|
await this.sendRemoteBoundSessionControl(target, (0, bound_session_wire_1.encodeRemoteBoundSessionResponsePayload)({
|
|
464
464
|
actorId,
|
|
@@ -468,9 +468,9 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
468
468
|
metadata: replyOptions.metadata,
|
|
469
469
|
compressPayload: replyOptions.compressPayload,
|
|
470
470
|
actorPacketTarget
|
|
471
|
-
})
|
|
471
|
+
}));
|
|
472
472
|
}
|
|
473
|
-
async sendRemoteBoundSessionError(target, actorId, packetName, requestSeq, error, metadata
|
|
473
|
+
async sendRemoteBoundSessionError(target, actorId, packetName, requestSeq, error, metadata) {
|
|
474
474
|
await this.sendRemoteBoundSessionControl(target, (0, bound_session_wire_1.encodeRemoteBoundSessionErrorPayload)({
|
|
475
475
|
actorId,
|
|
476
476
|
boundPacketName: packetName,
|
|
@@ -478,9 +478,9 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
478
478
|
error,
|
|
479
479
|
metadata,
|
|
480
480
|
actorPacketTarget: (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.options.actorPacketTargetForState(actorId))
|
|
481
|
-
})
|
|
481
|
+
}));
|
|
482
482
|
}
|
|
483
|
-
async sendRemoteBoundSessionControl(target, payload
|
|
483
|
+
async sendRemoteBoundSessionControl(target, payload) {
|
|
484
484
|
const packetName = payload.packetName;
|
|
485
485
|
if (typeof packetName !== 'string') {
|
|
486
486
|
throw new Error('Remote bound session control payload does not declare a packet name.');
|
|
@@ -489,7 +489,7 @@ class ZLinkRemoteBoundSessionRelay {
|
|
|
489
489
|
if (submit === undefined) {
|
|
490
490
|
throw new Error('Remote bound session node-direct transport is not available.');
|
|
491
491
|
}
|
|
492
|
-
const result = await submit.call(this.options.routeTransport, target.routerChannelId, String(target.targetNodeRid), packetName, payload
|
|
492
|
+
const result = await submit.call(this.options.routeTransport, target.routerChannelId, String(target.targetNodeRid), packetName, payload);
|
|
493
493
|
if (result.status !== submission_result_1.ZLinkSubmitStatus.Submitted) {
|
|
494
494
|
throw new Error(`Remote bound session control '${packetName}' was not admitted` +
|
|
495
495
|
` on '${target.routerChannelId}' for '${String(target.targetNodeRid)}'` +
|
|
@@ -15,12 +15,6 @@ export interface ZLinkHostSpotAddressTransportOptions {
|
|
|
15
15
|
readonly completions: (meshName: string) => ZLinkMeshCompletionTable | undefined;
|
|
16
16
|
readonly codecs?: ZLinkChannelEnvelopeCodecRegistry;
|
|
17
17
|
readonly defaultRequestTimeoutMs: number;
|
|
18
|
-
/** Internal one-way deadline policy; public calls do not expose this option. */
|
|
19
|
-
readonly defaultSendTimeoutMs?: number;
|
|
20
|
-
/** Resolves the send timeout for a configured Spot Mesh. */
|
|
21
|
-
readonly sendTimeoutMsForMesh?: (meshName: string) => number;
|
|
22
|
-
/** Resolves the send timeout for a resolved Spot route channel. */
|
|
23
|
-
readonly sendTimeoutMsForRouteChannel?: (routeChannelId: string) => number;
|
|
24
18
|
readonly dispatchErrors?: ZLinkDispatchErrorReporter;
|
|
25
19
|
}
|
|
26
20
|
export declare function hasObjectClientCapability(role: 'none' | 'client' | 'server' | undefined): boolean;
|
|
@@ -28,7 +22,7 @@ export declare function hasObjectClientCapability(role: 'none' | 'client' | 'ser
|
|
|
28
22
|
export declare class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport {
|
|
29
23
|
private readonly options;
|
|
30
24
|
constructor(options: ZLinkHostSpotAddressTransportOptions);
|
|
31
|
-
sendToSpotAddress(spotId: RoutingId, message: unknown, call: ZLinkSpotAddressCallOptions): Promise<ZLinkSubmitResult>;
|
|
25
|
+
sendToSpotAddress(spotId: RoutingId, message: unknown, call: Omit<ZLinkSpotAddressCallOptions, 'timeoutMs' | 'signal'>): Promise<ZLinkSubmitResult>;
|
|
32
26
|
private sendToSpotAddressScoped;
|
|
33
27
|
requestToSpotAddress<TReply = unknown>(spotId: RoutingId, request: unknown, call: ZLinkSpotAddressCallOptions): Promise<TReply>;
|
|
34
28
|
private requestToSpotAddressScoped;
|
|
@@ -38,8 +32,6 @@ export declare class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTr
|
|
|
38
32
|
private traceInstanceAddress;
|
|
39
33
|
private resolveExisting;
|
|
40
34
|
private selectMissingTarget;
|
|
41
|
-
private sendTimeoutMsForMesh;
|
|
42
|
-
private sendTimeoutMsForRouteChannel;
|
|
43
35
|
private validateExisting;
|
|
44
36
|
private encode;
|
|
45
37
|
private encodeAtDeadline;
|
|
@@ -29,79 +29,60 @@ class ZLinkHostSpotAddressTransport {
|
|
|
29
29
|
return (0, flow_context_1.runWithOutboundFlow)(this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true, () => this.sendToSpotAddressScoped(spotId, message, call));
|
|
30
30
|
}
|
|
31
31
|
async sendToSpotAddressScoped(spotId, message, call) {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
timeoutMs: deadline.requireRemaining(),
|
|
44
|
-
signal: deadline.signal,
|
|
45
|
-
metadata: call.metadata
|
|
46
|
-
}), deadline.signal);
|
|
47
|
-
if (result.status === submission_result_1.ZLinkSubmitStatus.Submitted) {
|
|
48
|
-
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Sent, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
this.traceInstanceAddress(submitResultFlowOutcome(result.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, submitResultReason(result.status));
|
|
52
|
-
}
|
|
53
|
-
if (result.status === submission_result_1.ZLinkSubmitStatus.TargetNotFound ||
|
|
54
|
-
result.status === submission_result_1.ZLinkSubmitStatus.RouteNotConnected) {
|
|
55
|
-
this.options.resolver()?.invalidate?.(spotId);
|
|
56
|
-
}
|
|
57
|
-
return result;
|
|
32
|
+
const activationDeadlineUnixMs = BigInt(Math.round(Date.now() + this.options.defaultRequestTimeoutMs));
|
|
33
|
+
const existing = await this.resolveExisting(spotId);
|
|
34
|
+
if (existing !== undefined) {
|
|
35
|
+
this.validateExisting(existing, call);
|
|
36
|
+
try {
|
|
37
|
+
const result = await this.options.routed.sendToSpot(existing, message, {
|
|
38
|
+
instanceSpot: call.instanceSpot,
|
|
39
|
+
metadata: call.metadata
|
|
40
|
+
});
|
|
41
|
+
if (result.status === submission_result_1.ZLinkSubmitStatus.Submitted) {
|
|
42
|
+
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Sent, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
|
|
58
43
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.options.resolver()?.invalidate?.(spotId);
|
|
62
|
-
}
|
|
63
|
-
const reason = addressedInstanceErrorReason(error);
|
|
64
|
-
this.traceInstanceAddress(reason === ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure
|
|
65
|
-
? ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured
|
|
66
|
-
: ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, reason);
|
|
67
|
-
throw error;
|
|
44
|
+
else {
|
|
45
|
+
this.traceInstanceAddress(submitResultFlowOutcome(result.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, submitResultReason(result.status));
|
|
68
46
|
}
|
|
47
|
+
if (result.status === submission_result_1.ZLinkSubmitStatus.TargetNotFound ||
|
|
48
|
+
result.status === submission_result_1.ZLinkSubmitStatus.RouteNotConnected) {
|
|
49
|
+
this.options.resolver()?.invalidate?.(spotId);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
69
52
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.traceInstanceAddress(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (selected.kind === 'capacity') {
|
|
79
|
-
const error = missingInstancePlacementCapacity(spotId, call.instanceSpotType);
|
|
80
|
-
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure);
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (isSpotRouteRefreshError(error)) {
|
|
55
|
+
this.options.resolver()?.invalidate?.(spotId);
|
|
56
|
+
}
|
|
57
|
+
const reason = addressedInstanceErrorReason(error);
|
|
58
|
+
this.traceInstanceAddress(reason === ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure
|
|
59
|
+
? ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured
|
|
60
|
+
: ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, reason);
|
|
81
61
|
throw error;
|
|
82
62
|
}
|
|
83
|
-
if (selected.kind === 'unavailable') {
|
|
84
|
-
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
|
|
85
|
-
return { status: submission_result_1.ZLinkSubmitStatus.RouteNotConnected };
|
|
86
|
-
}
|
|
87
|
-
deadline.setOwnerTimeout(this.sendTimeoutMsForMesh(selected.meshName));
|
|
88
|
-
const encoded = this.encode(3 /* ZLinkChannelMessageKind.Command */, selected.meshName, message);
|
|
89
|
-
const sourceSpotId = call.sourceSpot === undefined ? undefined : String(call.sourceSpot.routingId);
|
|
90
|
-
const mapped = (0, submission_result_1.classifySubmitResult)(await (0, abort_1.awaitWithAbort)(selected.node.sendToMissingInstanceSpot(selected.target, encoded, BigInt(deadline.deadlineUnixMs), sourceSpotId, call.metadata), deadline.signal), 'Instance Spot submission');
|
|
91
|
-
this.traceInstanceAddress(submitResultFlowOutcome(mapped.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, selected.meshName, selected.target.stableType, selected.target.targetNodeRid, mapped.status === submission_result_1.ZLinkSubmitStatus.Submitted
|
|
92
|
-
? undefined
|
|
93
|
-
: submitResultReason(mapped.status));
|
|
94
|
-
return mapped;
|
|
95
63
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
64
|
+
if (!call.instanceSpot) {
|
|
65
|
+
return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
|
|
66
|
+
}
|
|
67
|
+
const selected = this.selectMissingTarget(spotId, call);
|
|
68
|
+
if (selected.kind === 'unsupported') {
|
|
69
|
+
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
|
|
70
|
+
return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
|
|
71
|
+
}
|
|
72
|
+
if (selected.kind === 'capacity') {
|
|
73
|
+
const error = missingInstancePlacementCapacity(spotId, call.instanceSpotType);
|
|
74
|
+
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure);
|
|
100
75
|
throw error;
|
|
101
76
|
}
|
|
102
|
-
|
|
103
|
-
|
|
77
|
+
if (selected.kind === 'unavailable') {
|
|
78
|
+
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
|
|
79
|
+
return { status: submission_result_1.ZLinkSubmitStatus.RouteNotConnected };
|
|
104
80
|
}
|
|
81
|
+
const encoded = this.encode(3 /* ZLinkChannelMessageKind.Command */, selected.meshName, message);
|
|
82
|
+
const sourceSpotId = call.sourceSpot === undefined ? undefined : String(call.sourceSpot.routingId);
|
|
83
|
+
const mapped = (0, submission_result_1.classifySubmitResult)(await selected.node.sendToMissingInstanceSpot(selected.target, encoded, activationDeadlineUnixMs, sourceSpotId, call.metadata), 'Instance Spot submission');
|
|
84
|
+
this.traceInstanceAddress(submitResultFlowOutcome(mapped.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, selected.meshName, selected.target.stableType, selected.target.targetNodeRid, mapped.status === submission_result_1.ZLinkSubmitStatus.Submitted ? undefined : submitResultReason(mapped.status));
|
|
85
|
+
return mapped;
|
|
105
86
|
}
|
|
106
87
|
requestToSpotAddress(spotId, request, call) {
|
|
107
88
|
return (0, flow_context_1.runWithOutboundFlow)(this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true, () => this.requestToSpotAddressScoped(spotId, request, call));
|
|
@@ -273,7 +254,7 @@ class ZLinkHostSpotAddressTransport {
|
|
|
273
254
|
if (stableType === undefined) {
|
|
274
255
|
if (distinctTypes.length === 0)
|
|
275
256
|
return { kind: 'unsupported' };
|
|
276
|
-
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.
|
|
257
|
+
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.InvalidOperation, 'Instance Spot type is required when multiple types are registered.');
|
|
277
258
|
}
|
|
278
259
|
if (canInspectPlacementTypes && !distinctTypes.includes(stableType)) {
|
|
279
260
|
return { kind: 'unsupported' };
|
|
@@ -315,16 +296,6 @@ class ZLinkHostSpotAddressTransport {
|
|
|
315
296
|
return { kind: 'unsupported' };
|
|
316
297
|
return { kind: 'unavailable' };
|
|
317
298
|
}
|
|
318
|
-
sendTimeoutMsForMesh(meshName) {
|
|
319
|
-
return (this.options.sendTimeoutMsForMesh?.(meshName) ??
|
|
320
|
-
this.options.defaultSendTimeoutMs ??
|
|
321
|
-
this.options.defaultRequestTimeoutMs);
|
|
322
|
-
}
|
|
323
|
-
sendTimeoutMsForRouteChannel(routeChannelId) {
|
|
324
|
-
return (this.options.sendTimeoutMsForRouteChannel?.(routeChannelId) ??
|
|
325
|
-
this.options.defaultSendTimeoutMs ??
|
|
326
|
-
this.options.defaultRequestTimeoutMs);
|
|
327
|
-
}
|
|
328
299
|
validateExisting(target, call) {
|
|
329
300
|
if (!call.instanceSpot)
|
|
330
301
|
return;
|
|
@@ -436,17 +407,10 @@ function addressedInstanceErrorReason(error) {
|
|
|
436
407
|
}
|
|
437
408
|
return ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.HandlerException;
|
|
438
409
|
}
|
|
439
|
-
function initialSendTimeoutMs(options, call) {
|
|
440
|
-
return call.initialMeshName === undefined
|
|
441
|
-
? (options.defaultSendTimeoutMs ?? options.defaultRequestTimeoutMs)
|
|
442
|
-
: (options.sendTimeoutMsForMesh?.(call.initialMeshName) ??
|
|
443
|
-
options.defaultSendTimeoutMs ??
|
|
444
|
-
options.defaultRequestTimeoutMs);
|
|
445
|
-
}
|
|
446
410
|
function createSpotAddressDeadline(timeoutMs, parent) {
|
|
447
411
|
const startedAtMs = performance.now();
|
|
448
412
|
const startedAtUnixMs = Date.now();
|
|
449
|
-
|
|
413
|
+
const deadlineMs = startedAtMs + Math.max(0, timeoutMs);
|
|
450
414
|
const controller = new AbortController();
|
|
451
415
|
let expired = false;
|
|
452
416
|
let timeout;
|
|
@@ -475,10 +439,6 @@ function createSpotAddressDeadline(timeoutMs, parent) {
|
|
|
475
439
|
return Math.round(startedAtUnixMs + (deadlineMs - startedAtMs));
|
|
476
440
|
},
|
|
477
441
|
signal: controller.signal,
|
|
478
|
-
setOwnerTimeout(ownerTimeoutMs) {
|
|
479
|
-
deadlineMs = startedAtMs + Math.max(0, ownerTimeoutMs);
|
|
480
|
-
arm();
|
|
481
|
-
},
|
|
482
442
|
requireRemaining() {
|
|
483
443
|
const remainingMs = deadlineMs - performance.now();
|
|
484
444
|
if (remainingMs <= 0) {
|
|
@@ -28,6 +28,7 @@ export declare class ZLinkStatefulAuthorityRouteRuntime {
|
|
|
28
28
|
reconcile(signal?: AbortSignal, requireComplete?: boolean): Promise<void>;
|
|
29
29
|
private recoverInstanceActivation;
|
|
30
30
|
private recoverPendingInstanceActivation;
|
|
31
|
+
private clearRecoveryRoot;
|
|
31
32
|
private readRecoveryEnvelope;
|
|
32
33
|
private run;
|
|
33
34
|
private readCompleteSnapshot;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkStatefulAuthorityRouteRuntime = void 0;
|
|
4
|
+
const authority_key_codec_1 = require("../locations/authority-key-codec");
|
|
4
5
|
const node_crypto_1 = require("node:crypto");
|
|
5
6
|
const relocation_blob_1 = require("../locations/relocation-blob");
|
|
6
7
|
const routing_id_1 = require("../routing-id");
|
|
@@ -65,11 +66,19 @@ class ZLinkStatefulAuthorityRouteRuntime {
|
|
|
65
66
|
const previous = this.appliedByMesh.get(meshName) ?? new Map();
|
|
66
67
|
const status = sink.status();
|
|
67
68
|
for (const pending of snapshot.pending) {
|
|
68
|
-
if (pending.targetMeshName
|
|
69
|
-
|
|
69
|
+
if (pending.targetMeshName !== meshName)
|
|
70
|
+
continue;
|
|
71
|
+
if ((0, routing_id_1.routingIdsEqual)(status.routingId, pending.targetNodeRid) &&
|
|
70
72
|
status.lifecycleGeneration === pending.targetNodeGeneration) {
|
|
71
73
|
await this.recoverPendingInstanceActivation(sink, pending, signal);
|
|
72
74
|
}
|
|
75
|
+
else {
|
|
76
|
+
const release = this.options.creationStore?.releaseEndedReservation;
|
|
77
|
+
if (release === undefined)
|
|
78
|
+
throw new Error('Reservation lifecycle recovery requires a Location repository.');
|
|
79
|
+
if (await release.call(this.options.creationStore, (0, authority_key_codec_1.encodeAuthorityKey)('instance_spot', pending.spotId), pending.pending.storeVersion, signal))
|
|
80
|
+
await this.clearRecoveryRoot(pending.pending.requestReference, signal);
|
|
81
|
+
}
|
|
73
82
|
}
|
|
74
83
|
for (const [key, route] of current) {
|
|
75
84
|
if (route.meshName !== meshName)
|
|
@@ -207,19 +216,18 @@ class ZLinkStatefulAuthorityRouteRuntime {
|
|
|
207
216
|
}
|
|
208
217
|
}, signal);
|
|
209
218
|
if (aborted.kind === 'aborted' || aborted.kind === 'alreadyAborted') {
|
|
210
|
-
|
|
211
|
-
await this.options.relocationStore?.delete((0, relocation_blob_1.relocationBlobReference)(recovery.pending.requestReference));
|
|
212
|
-
}
|
|
213
|
-
catch {
|
|
214
|
-
// The authority no longer publishes this root. Retention owns a
|
|
215
|
-
// failed best-effort orphan cleanup.
|
|
216
|
-
}
|
|
219
|
+
await this.clearRecoveryRoot(recovery.pending.requestReference, signal);
|
|
217
220
|
}
|
|
218
221
|
return;
|
|
219
222
|
}
|
|
220
223
|
if ((await sink.recoverPendingInstanceActivation(envelope, recovery.pending, null)) === false)
|
|
221
224
|
return;
|
|
222
225
|
}
|
|
226
|
+
async clearRecoveryRoot(reference, signal) {
|
|
227
|
+
if (this.options.relocationStore === undefined)
|
|
228
|
+
throw new Error('Instance activation recovery requires a Relocation Store.');
|
|
229
|
+
await this.options.relocationStore.delete((0, relocation_blob_1.relocationBlobReference)(reference), signal);
|
|
230
|
+
}
|
|
223
231
|
async readRecoveryEnvelope(recovery, signal) {
|
|
224
232
|
const relocationStore = this.options.relocationStore;
|
|
225
233
|
if (relocationStore === undefined) {
|