@zlink-systems/framework 0.27.0 → 0.28.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 +0 -1
- package/dist/contracts/Configuration/Configs.d.ts +0 -1
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +0 -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-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-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/foundation/raw-service-mesh-runtime.js +17 -11
- 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/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 +46 -86
- package/dist/runtime/locations/location-store-repository.js +6 -4
- 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/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 -2
- package/dist/runtime/streams/index.js +2 -2
- 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/session-calls.d.ts +5 -7
- package/dist/runtime/streams/session-calls.js +6 -23
- package/dist/runtime/streams/session-context.d.ts +4 -4
- package/dist/runtime/streams/session-context.js +3 -6
- 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 +0 -1
- package/src/contracts/Configuration/Configs.ts +0 -1
- package/src/contracts/Configuration/RegistrationBuilders.ts +0 -3
- package/src/contracts/Configuration/RegistrationTypes.ts +0 -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-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-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/foundation/raw-service-mesh-runtime.ts +17 -14
- package/src/runtime/host/actor-packet-relay.ts +8 -15
- package/src/runtime/host/index.ts +2 -26
- package/src/runtime/host/remote-bound-session-relay.ts +8 -16
- package/src/runtime/host/spot-address-transport.ts +106 -165
- package/src/runtime/locations/location-store-repository.ts +7 -4
- package/src/runtime/messaging/request-deadline.ts +58 -0
- package/src/runtime/messaging/submission-result.ts +18 -4
- package/src/runtime/spots/spot-outbound.ts +14 -24
- 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 +2 -4
- package/src/runtime/streams/managed-stream.ts +3 -13
- package/src/runtime/streams/native-fallback-bound-session.ts +13 -25
- package/src/runtime/streams/session-calls.ts +8 -34
- package/src/runtime/streams/session-context.ts +6 -15
|
@@ -41,35 +41,34 @@ class ZLinkSpotRouteDispatchStrategy {
|
|
|
41
41
|
canRoutePacketChannel(routerChannelId) {
|
|
42
42
|
return this.targets.canRoutePacketChannel(routerChannelId);
|
|
43
43
|
}
|
|
44
|
-
routeSendToSpot(spotRouteTarget, packetName, message,
|
|
44
|
+
routeSendToSpot(spotRouteTarget, packetName, message, metadata) {
|
|
45
45
|
// Call-scoped flow (spec 27 §4): the envelope flow pair lives only for
|
|
46
46
|
// the duration of this outbound call, never in the caller's context.
|
|
47
|
-
return (0, flow_context_1.runWithOutboundFlow)(this.options.flowCreationEnabled?.() ?? true, () => this.routeSendToSpotScoped(spotRouteTarget, packetName, message,
|
|
47
|
+
return (0, flow_context_1.runWithOutboundFlow)(this.options.flowCreationEnabled?.() ?? true, () => this.routeSendToSpotScoped(spotRouteTarget, packetName, message, metadata));
|
|
48
48
|
}
|
|
49
|
-
async routeSendToSpotScoped(spotRouteTarget, packetName, message,
|
|
50
|
-
(0, abort_1.throwIfAborted)(signal);
|
|
49
|
+
async routeSendToSpotScoped(spotRouteTarget, packetName, message, metadata) {
|
|
51
50
|
const localSpotRouteNode = this.targets.localRouteNode(spotRouteTarget);
|
|
52
51
|
if (localSpotRouteNode !== undefined) {
|
|
53
|
-
await this.localTransport.send(spotRouteTarget.routerChannelId, spotRouteTarget.spotId, packetName, message,
|
|
52
|
+
await this.localTransport.send(spotRouteTarget.routerChannelId, spotRouteTarget.spotId, packetName, message, metadata);
|
|
54
53
|
return;
|
|
55
54
|
}
|
|
56
55
|
const parts = (0, channel_envelope_1.encodeChannelEnvelopeParts)(3 /* ZLinkChannelMessageKind.Command */, spotRouteTarget.routerChannelId, packetName, message, undefined, undefined, (0, channel_framework_packets_1.codecsForFrameworkPacket)(packetName, this.options.codecs), undefined, this.options.flowCreationEnabled?.() ?? true, metadata);
|
|
57
56
|
if (this.targets.hasNamedSpotNode(spotRouteTarget.routerChannelId) &&
|
|
58
|
-
(await this.spotNodeTransport.send(spotRouteTarget, parts
|
|
57
|
+
(await this.spotNodeTransport.send(spotRouteTarget, parts))) {
|
|
59
58
|
return;
|
|
60
59
|
}
|
|
61
60
|
if (this.bridgeTransport.has(spotRouteTarget.routerChannelId)) {
|
|
62
|
-
await this.bridgeTransport.send(spotRouteTarget, parts
|
|
61
|
+
await this.bridgeTransport.send(spotRouteTarget, parts);
|
|
63
62
|
return;
|
|
64
63
|
}
|
|
65
64
|
if (this.targets.hasBoundRouteRouter(spotRouteTarget.routerChannelId)) {
|
|
66
|
-
await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT
|
|
65
|
+
await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT);
|
|
67
66
|
return;
|
|
68
67
|
}
|
|
69
|
-
if (await this.spotNodeTransport.send(spotRouteTarget, parts
|
|
68
|
+
if (await this.spotNodeTransport.send(spotRouteTarget, parts)) {
|
|
70
69
|
return;
|
|
71
70
|
}
|
|
72
|
-
await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT
|
|
71
|
+
await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT);
|
|
73
72
|
}
|
|
74
73
|
routeRequestToSpot(spotRouteTarget, packetName, request, timeoutMs, signal, metadata) {
|
|
75
74
|
return (0, flow_context_1.runWithOutboundFlow)(this.options.flowCreationEnabled?.() ?? true, () => this.routeRequestToSpotScoped(spotRouteTarget, packetName, request, timeoutMs, signal, metadata));
|
|
@@ -102,8 +101,8 @@ class ZLinkSpotRouteDispatchStrategy {
|
|
|
102
101
|
routeRequestFromSpotToSpot(sourceSpot, spotRouteTarget, packetName, request, timeoutMs, signal) {
|
|
103
102
|
return this.sourceSpotRouter.request(sourceSpot, spotRouteTarget, packetName, request, timeoutMs, signal);
|
|
104
103
|
}
|
|
105
|
-
async routeSendFromSpotToSpot(sourceSpot, spotRouteTarget, packetName, message,
|
|
106
|
-
await this.sourceSpotRouter.send(sourceSpot, spotRouteTarget, packetName, message,
|
|
104
|
+
async routeSendFromSpotToSpot(sourceSpot, spotRouteTarget, packetName, message, metadata) {
|
|
105
|
+
await this.sourceSpotRouter.send(sourceSpot, spotRouteTarget, packetName, message, metadata);
|
|
107
106
|
}
|
|
108
107
|
routeRequestRawFromSpotToSpot(sourceSpot, spotRouteTarget, request, timeoutMs, signal) {
|
|
109
108
|
return this.sourceSpotRouter.requestRaw(sourceSpot, spotRouteTarget, request, timeoutMs, signal);
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RawServiceMeshRuntime = exports.RAW_MESH_RECEIVE_TIME_BUDGET_MS = void 0;
|
|
4
4
|
const node_os_1 = require("node:os");
|
|
5
5
|
const application_ingress_record_owner_1 = require("../application-jobs/application-ingress-record-owner");
|
|
6
|
+
const submission_result_1 = require("../messaging/submission-result");
|
|
6
7
|
const runtime_values_1 = require("../backend/runtime-values");
|
|
7
8
|
const service_wire_codec_generated_1 = require("../protocol/service_wire_codec.generated");
|
|
8
9
|
const operation_registry_1 = require("./operation-registry");
|
|
@@ -564,16 +565,16 @@ class RawServiceMeshRuntime {
|
|
|
564
565
|
const record = livenessCodec.decodeLivenessRecord(received.parts[0]);
|
|
565
566
|
if (record.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe) {
|
|
566
567
|
const ack = this.liveness.acknowledgeProbe(received.sourceRid, peer.connectionId, record.probeId);
|
|
567
|
-
|
|
568
|
-
(await this.send(received.sourceRid, [
|
|
569
|
-
livenessCodec.encodeLivenessRecord({
|
|
570
|
-
command: service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck,
|
|
571
|
-
probeId: record.probeId
|
|
572
|
-
})
|
|
573
|
-
]));
|
|
574
|
-
if (!sent) {
|
|
568
|
+
if (ack === undefined)
|
|
575
569
|
return 'protocolError';
|
|
576
|
-
|
|
570
|
+
const sent = await this.send(received.sourceRid, [
|
|
571
|
+
livenessCodec.encodeLivenessRecord({
|
|
572
|
+
command: service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck,
|
|
573
|
+
probeId: record.probeId
|
|
574
|
+
})
|
|
575
|
+
]);
|
|
576
|
+
if (!sent)
|
|
577
|
+
return 'dropped';
|
|
577
578
|
}
|
|
578
579
|
else {
|
|
579
580
|
this.liveness.acknowledge(received.sourceRid, peer.connectionId, record.probeId, nowMs);
|
|
@@ -962,8 +963,13 @@ class RawServiceMeshRuntime {
|
|
|
962
963
|
await this.requireStarted().send(targetNodeRoutingId, parts);
|
|
963
964
|
return true;
|
|
964
965
|
}
|
|
965
|
-
catch {
|
|
966
|
-
|
|
966
|
+
catch (error) {
|
|
967
|
+
if ((0, runtime_values_1.isZLinkBackendResultError)(error) && error.operation === 'submit') {
|
|
968
|
+
const terminal = (0, submission_result_1.submitToRequestResult)(error.result, error.phase);
|
|
969
|
+
if (terminal === runtime_values_1.RequestResult.NotConnected || terminal === runtime_values_1.RequestResult.NotFound)
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
throw error;
|
|
967
973
|
}
|
|
968
974
|
}
|
|
969
975
|
}
|
|
@@ -43,7 +43,7 @@ export declare class ZLinkActorPacketRelay {
|
|
|
43
43
|
readonly deferredResponse?: boolean;
|
|
44
44
|
readonly actorPacketTarget?: unknown;
|
|
45
45
|
}>;
|
|
46
|
-
relayActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message
|
|
46
|
+
relayActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message): Promise<boolean>;
|
|
47
47
|
confirmRemoteSessionBinding(actor: ActorRef, sessionNodeRid: RoutingId, sessionRid: RoutingId, signal?: AbortSignal, options?: ZLinkSessionBindingConfirmationOptions): Promise<void>;
|
|
48
48
|
/**
|
|
49
49
|
* Session–Actor binding §5·§6 (.NET ZLinkSessionActorCoordinator rule): a
|
|
@@ -51,7 +51,7 @@ export declare class ZLinkActorPacketRelay {
|
|
|
51
51
|
* same install a remote command 38 uses, so relocation seals and carries it.
|
|
52
52
|
*/
|
|
53
53
|
private installSameNodeSessionBinding;
|
|
54
|
-
relayRemoteActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message
|
|
54
|
+
relayRemoteActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message): Promise<boolean>;
|
|
55
55
|
notifyRemoteActorDisconnected(actorId: string, remoteTarget: ZLinkRemoteBoundSessionTarget | ZLinkRemoteActorPacketTarget, signal?: AbortSignal, bindingActorRef?: ActorRef): Promise<void>;
|
|
56
56
|
private requireCurrentRemoteBinding;
|
|
57
57
|
private requestRemoteTarget;
|
|
@@ -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({
|
|
@@ -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));
|
|
@@ -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) {
|
|
@@ -859,7 +859,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
859
859
|
this.provider.read(leaseKey, signal)
|
|
860
860
|
]);
|
|
861
861
|
const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
|
|
862
|
-
if (descriptor === undefined) {
|
|
862
|
+
if (descriptor === undefined || descriptor.state !== contracts_1.ZLinkFrameworkRuntimeState.Serving) {
|
|
863
863
|
return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
|
|
864
864
|
}
|
|
865
865
|
const [capacityRead, objectGenerationRead, authorityOwnerGenerationRead] = await Promise.all([
|
|
@@ -1042,9 +1042,11 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1042
1042
|
!sameCreationTarget(record.snapshot, request.target)) {
|
|
1043
1043
|
return { kind: 'stale' };
|
|
1044
1044
|
}
|
|
1045
|
+
const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
|
|
1045
1046
|
const leaseKey = ownerKey(request.target.owner.ownerId);
|
|
1046
1047
|
const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
|
|
1047
|
-
const [leaseRead, capacityRead] = await Promise.all([
|
|
1048
|
+
const [descriptorRead, leaseRead, capacityRead] = await Promise.all([
|
|
1049
|
+
this.provider.read(descriptorKey, signal),
|
|
1048
1050
|
this.provider.read(leaseKey, signal),
|
|
1049
1051
|
this.provider.read(capacityRowKey, signal)
|
|
1050
1052
|
]);
|
|
@@ -1054,7 +1056,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1054
1056
|
// rather than read the absence as expiry.
|
|
1055
1057
|
throw new Error('Location Store owner lease record is invalid.');
|
|
1056
1058
|
}
|
|
1057
|
-
if (
|
|
1059
|
+
if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined)
|
|
1058
1060
|
return { kind: 'stale' };
|
|
1059
1061
|
const capacity = capacityRead.kind === 'missing'
|
|
1060
1062
|
? emptyCapacityRecord()
|
|
@@ -1062,6 +1064,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1062
1064
|
const result = await this.provider.write({
|
|
1063
1065
|
conditions: [
|
|
1064
1066
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1067
|
+
versionCondition(descriptorKey, descriptorRead),
|
|
1065
1068
|
leaseValueCondition(leaseKey, {
|
|
1066
1069
|
ownerId: record.snapshot.ownerId,
|
|
1067
1070
|
leaseGeneration: record.snapshot.ownerLeaseGeneration
|
|
@@ -2843,7 +2846,6 @@ function liveTargetDescriptor(descriptorRead, leaseRead, target) {
|
|
|
2843
2846
|
descriptor.ownerId === target.owner.ownerId &&
|
|
2844
2847
|
descriptor.leaseGeneration === target.owner.leaseGeneration &&
|
|
2845
2848
|
descriptor.objectRole === contracts_1.ZLinkObjectRole.Server &&
|
|
2846
|
-
descriptor.state === contracts_1.ZLinkFrameworkRuntimeState.Serving &&
|
|
2847
2849
|
lease.ownerId === target.owner.ownerId &&
|
|
2848
2850
|
BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
|
|
2849
2851
|
leaseRead.value.expiresAt !== undefined &&
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function remainingRequestTimeout(operation: string, deadlineMs: number | undefined): number | undefined;
|
|
2
|
+
/** Bounds caller waiting across outbound admission and reply; late completions stay observed. */
|
|
3
|
+
export declare function waitRequestReply<T>(reply: Promise<T>, operation: string, deadlineMs: number | undefined, signal?: AbortSignal, endWait?: () => void, discardLateReply?: (reply: T) => void): Promise<T>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.remainingRequestTimeout = remainingRequestTimeout;
|
|
4
|
+
exports.waitRequestReply = waitRequestReply;
|
|
5
|
+
const abort_1 = require("../abort");
|
|
6
|
+
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
7
|
+
function remainingRequestTimeout(operation, deadlineMs) {
|
|
8
|
+
if (deadlineMs === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
const remaining = deadlineMs - performance.now();
|
|
11
|
+
if (remaining <= 0) {
|
|
12
|
+
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `${operation} exceeded its deadline.`);
|
|
13
|
+
}
|
|
14
|
+
return Math.max(1, Math.ceil(remaining));
|
|
15
|
+
}
|
|
16
|
+
/** Bounds caller waiting across outbound admission and reply; late completions stay observed. */
|
|
17
|
+
async function waitRequestReply(reply, operation, deadlineMs, signal, endWait, discardLateReply) {
|
|
18
|
+
let timer;
|
|
19
|
+
let waiting = reply;
|
|
20
|
+
if (deadlineMs !== undefined) {
|
|
21
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
22
|
+
const remaining = remainingRequestTimeout(operation, deadlineMs);
|
|
23
|
+
timer = setTimeout(() => reject((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `${operation} exceeded its deadline.`)), remaining);
|
|
24
|
+
});
|
|
25
|
+
waiting = Promise.race([reply, timeout]);
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return await (0, abort_1.awaitWithAbort)(waiting, signal);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
endWait?.();
|
|
32
|
+
if (discardLateReply !== undefined)
|
|
33
|
+
void reply.then(discardLateReply, () => undefined);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -10,9 +10,10 @@ export declare enum ZLinkSubmitStatus {
|
|
|
10
10
|
export interface ZLinkSubmitResult {
|
|
11
11
|
readonly status: ZLinkSubmitStatus;
|
|
12
12
|
}
|
|
13
|
-
/** Projects
|
|
13
|
+
/** Projects immediate refusal and pending admission failure from their Core phase. */
|
|
14
14
|
export declare function submitToRequestResult(result: number, phase: 'submit' | 'completion'): number;
|
|
15
15
|
export declare function classifySubmitResult(result: number, operation: string, phase?: 'submit' | 'completion'): ZLinkSubmitResult;
|
|
16
16
|
export declare function requireOneWayCompletion(result: ZLinkSubmitResult, operation: string, notFoundKind?: ZLinkFrameworkInternalErrorKind): void;
|
|
17
17
|
export declare function requirePublishCompletion(result: ZLinkSubmitResult, operation: string): void;
|
|
18
|
+
export declare function requireClassicFanoutCompletion(result: ZLinkSubmitResult, operation: string): void;
|
|
18
19
|
export declare function throwAlreadySubmitted(operation: string): never;
|