@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
|
@@ -17,9 +17,14 @@ export class ZLinkActorSerialExecutor {
|
|
|
17
17
|
constructor(
|
|
18
18
|
private readonly actorId: string,
|
|
19
19
|
private readonly sourceSpotId: unknown,
|
|
20
|
-
options?: ZLinkSerialSchedulerOptions
|
|
20
|
+
options?: ZLinkSerialSchedulerOptions,
|
|
21
|
+
sharedOwner?: ZLinkSerialExecutionQueue
|
|
21
22
|
) {
|
|
22
|
-
this.scheduler = new ZLinkSerialExecutionQueue(
|
|
23
|
+
this.scheduler = new ZLinkSerialExecutionQueue(
|
|
24
|
+
(record) => this.runRecord(record),
|
|
25
|
+
options,
|
|
26
|
+
sharedOwner
|
|
27
|
+
);
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
execute<T>(operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T> {
|
|
@@ -1,49 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '../framework-errors-internal';
|
|
6
|
-
|
|
7
|
-
export function remainingActorRequestTimeout(
|
|
8
|
-
actorId: string,
|
|
9
|
-
deadlineMs: number | undefined
|
|
10
|
-
): number | undefined {
|
|
11
|
-
if (deadlineMs === undefined) return undefined;
|
|
12
|
-
const remaining = deadlineMs - performance.now();
|
|
13
|
-
if (remaining <= 0) {
|
|
14
|
-
throw createInternalFrameworkException(
|
|
15
|
-
ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
|
|
16
|
-
`Actor request '${actorId}' exceeded its deadline.`
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
return Math.max(1, Math.ceil(remaining));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Only actual Store, delivery-gate, and handoff waits acquire a deadline handle. */
|
|
23
|
-
export async function waitActorReply<T>(
|
|
24
|
-
reply: Promise<T>,
|
|
25
|
-
actorId: string,
|
|
26
|
-
deadlineMs: number | undefined,
|
|
27
|
-
signal?: AbortSignal
|
|
28
|
-
): Promise<T> {
|
|
29
|
-
if (deadlineMs === undefined) return await awaitWithAbort(reply, signal);
|
|
30
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
31
|
-
const timeout = new Promise<never>((_resolve, reject) => {
|
|
32
|
-
const remaining = remainingActorRequestTimeout(actorId, deadlineMs);
|
|
33
|
-
timer = setTimeout(
|
|
34
|
-
() =>
|
|
35
|
-
reject(
|
|
36
|
-
createInternalFrameworkException(
|
|
37
|
-
ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
|
|
38
|
-
`Actor request '${actorId}' exceeded its deadline.`
|
|
39
|
-
)
|
|
40
|
-
),
|
|
41
|
-
remaining
|
|
42
|
-
);
|
|
43
|
-
});
|
|
44
|
-
try {
|
|
45
|
-
return await awaitWithAbort(Promise.race([reply, timeout]), signal);
|
|
46
|
-
} finally {
|
|
47
|
-
clearTimeout(timer);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
1
|
+
export {
|
|
2
|
+
remainingRequestTimeout as remainingActorRequestTimeout,
|
|
3
|
+
waitRequestReply as waitActorReply
|
|
4
|
+
} from '../messaging/request-deadline';
|
|
@@ -18,20 +18,18 @@ export interface ZLinkActorRoutedJoinTransport {
|
|
|
18
18
|
routerChannelId: string,
|
|
19
19
|
targetNodeRid: string,
|
|
20
20
|
packetName: string | undefined,
|
|
21
|
-
message: unknown
|
|
22
|
-
signal?: AbortSignal
|
|
21
|
+
message: unknown
|
|
23
22
|
): Promise<ZLinkSubmitResult>;
|
|
24
23
|
submitInfrastructure?(
|
|
25
24
|
routerChannelId: string,
|
|
26
25
|
targetNodeRid: string,
|
|
27
26
|
packetName: string | undefined,
|
|
28
|
-
message: unknown
|
|
29
|
-
signal?: AbortSignal
|
|
27
|
+
message: unknown
|
|
30
28
|
): Promise<ZLinkSubmitResult>;
|
|
31
29
|
sendToSpot(
|
|
32
30
|
spotRouteTarget: ZLinkSpotRouteTarget,
|
|
33
31
|
message: unknown,
|
|
34
|
-
options: { readonly packetName?: string
|
|
32
|
+
options: { readonly packetName?: string }
|
|
35
33
|
): Promise<ZLinkSubmitResult>;
|
|
36
34
|
requestRawToSpot?(
|
|
37
35
|
spotRouteTarget: ZLinkSpotRouteTarget,
|
|
@@ -492,7 +492,6 @@ export interface ZLinkBackendDealerSocket extends ZLinkBackendConnectableSocket
|
|
|
492
492
|
sendHighWaterMark: number;
|
|
493
493
|
receiveHighWaterMark: number;
|
|
494
494
|
receiveTimeoutMs: number;
|
|
495
|
-
sendTimeoutMs: number;
|
|
496
495
|
maxMessageSize: number;
|
|
497
496
|
send(message: Message | readonly Message[]): Promise<void>;
|
|
498
497
|
request(message: Message | readonly Message[], timeoutMs?: number): Promise<readonly Message[]>;
|
|
@@ -523,7 +522,6 @@ export interface ZLinkBackendRouterSocket extends ZLinkBackendConnectableSocket
|
|
|
523
522
|
sendHighWaterMark: number;
|
|
524
523
|
receiveHighWaterMark: number;
|
|
525
524
|
receiveTimeoutMs: number;
|
|
526
|
-
sendTimeoutMs: number;
|
|
527
525
|
maxMessageSize: number;
|
|
528
526
|
setRoutingId(routingId: RoutingId): void;
|
|
529
527
|
recv(flags?: ZLinkBackendRecvFlags): Received | undefined;
|
|
@@ -577,7 +575,6 @@ export interface ZLinkBackendStreamPacket {
|
|
|
577
575
|
}
|
|
578
576
|
|
|
579
577
|
export interface ZLinkBackendStreamSocket extends ZLinkBackendSocket {
|
|
580
|
-
readonly sendTimeoutMs: number;
|
|
581
578
|
readonly sendHighWaterMark: number;
|
|
582
579
|
/** Framework stream ingress uses this bound for packet payload validation. */
|
|
583
580
|
maxMessageSize: number;
|
|
@@ -588,11 +585,7 @@ export interface ZLinkBackendStreamSocket extends ZLinkBackendSocket {
|
|
|
588
585
|
payload: Message | readonly Message[],
|
|
589
586
|
flags: ZLinkBackendSendFlags
|
|
590
587
|
): boolean;
|
|
591
|
-
submit(
|
|
592
|
-
routingId: RoutingId,
|
|
593
|
-
payload: Message | readonly Message[],
|
|
594
|
-
timeoutMs?: number
|
|
595
|
-
): Promise<void>;
|
|
588
|
+
submit(routingId: RoutingId, payload: Message | readonly Message[]): Promise<void>;
|
|
596
589
|
disconnectPeer(routingId: RoutingId): void;
|
|
597
590
|
bindActor(
|
|
598
591
|
sessionRid: RoutingId,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { constants as osConstants } from 'node:os';
|
|
2
|
-
import {
|
|
2
|
+
import { waitRequestReply } from '../../messaging/request-deadline';
|
|
3
|
+
import {
|
|
4
|
+
requireClassicFanoutCompletion,
|
|
5
|
+
ZLinkSubmitStatus
|
|
6
|
+
} from '../../messaging/submission-result';
|
|
3
7
|
import { loadBinding } from '../node-backend-adapter';
|
|
4
8
|
import { SubmitResult, ZLinkBackendResultError } from '../runtime-values';
|
|
5
9
|
const nativeErrnoValues = osConstants.errno;
|
|
@@ -92,7 +96,7 @@ export function submitBindingPublish(
|
|
|
92
96
|
(translated.result === SubmitResult.Backpressured ||
|
|
93
97
|
translated.result === SubmitResult.NotAdmitted)
|
|
94
98
|
) {
|
|
95
|
-
|
|
99
|
+
requireClassicFanoutCompletion(
|
|
96
100
|
{ status: ZLinkSubmitStatus.Backpressured },
|
|
97
101
|
'Classic fanout publish'
|
|
98
102
|
);
|
|
@@ -119,6 +123,7 @@ export async function submitBindingAsyncSend(
|
|
|
119
123
|
operation: ZLinkBindingAsyncSendOperation,
|
|
120
124
|
payload: unknown
|
|
121
125
|
): Promise<void> {
|
|
126
|
+
let submission: import('@zlink-systems/zlink').SendSubmission;
|
|
122
127
|
try {
|
|
123
128
|
let current: ZLinkBindingAsyncSendSubmitOperation | undefined;
|
|
124
129
|
const parts = Array.isArray(payload) ? payload : [payload];
|
|
@@ -127,9 +132,16 @@ export async function submitBindingAsyncSend(
|
|
|
127
132
|
current = current === undefined ? operation.message(nativePart) : current.message(nativePart);
|
|
128
133
|
}
|
|
129
134
|
current ??= operation.message(Buffer.alloc(0));
|
|
130
|
-
|
|
135
|
+
submission = current.submit();
|
|
131
136
|
} catch (error) {
|
|
132
|
-
throw translateBindingResultError(error);
|
|
137
|
+
throw translateBindingResultError(error, 'submit');
|
|
138
|
+
}
|
|
139
|
+
if (submission.result === SubmitResult.Backpressured) {
|
|
140
|
+
try {
|
|
141
|
+
await submission.admitted;
|
|
142
|
+
} catch (error) {
|
|
143
|
+
throw translateBindingResultError(error, 'completion');
|
|
144
|
+
}
|
|
133
145
|
}
|
|
134
146
|
}
|
|
135
147
|
|
|
@@ -156,6 +168,7 @@ export async function submitBindingRequest(
|
|
|
156
168
|
payload: unknown,
|
|
157
169
|
timeoutMs: number | undefined
|
|
158
170
|
): Promise<readonly unknown[]> {
|
|
171
|
+
const deadlineMs = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
|
|
159
172
|
try {
|
|
160
173
|
let current: ZLinkBindingRequestSubmitOperation | undefined;
|
|
161
174
|
if (Array.isArray(payload)) {
|
|
@@ -171,12 +184,39 @@ export async function submitBindingRequest(
|
|
|
171
184
|
if (timeoutMs !== undefined) {
|
|
172
185
|
current = current.timeout(timeoutMs);
|
|
173
186
|
}
|
|
174
|
-
return await current.submit()
|
|
187
|
+
return await bindingRequestReply(current.submit(), deadlineMs);
|
|
175
188
|
} catch (error) {
|
|
176
189
|
throw translateBindingResultError(error);
|
|
177
190
|
}
|
|
178
191
|
}
|
|
179
192
|
|
|
193
|
+
export async function bindingRequestReply(
|
|
194
|
+
submission: import('@zlink-systems/zlink').RequestSubmission,
|
|
195
|
+
deadlineMs: number | undefined
|
|
196
|
+
): Promise<import('@zlink-systems/zlink').Message[]> {
|
|
197
|
+
const reply = submission.reply;
|
|
198
|
+
if (submission.result === SubmitResult.Backpressured) {
|
|
199
|
+
try {
|
|
200
|
+
const [, replies] = await waitRequestReply(
|
|
201
|
+
Promise.all([submission.admitted, reply]),
|
|
202
|
+
'Request',
|
|
203
|
+
deadlineMs
|
|
204
|
+
);
|
|
205
|
+
return replies;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
void reply.then(closeBindingReply, () => undefined);
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return reply;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function closeBindingReply(
|
|
215
|
+
replies: readonly import('@zlink-systems/zlink').Message[]
|
|
216
|
+
): void {
|
|
217
|
+
for (const reply of replies) reply.close();
|
|
218
|
+
}
|
|
219
|
+
|
|
180
220
|
/**
|
|
181
221
|
* Closes a binding handle once. An already closed or terminated handle counts as
|
|
182
222
|
* closed. A busy close propagates to the caller.
|
|
@@ -24,10 +24,8 @@ export class ZLinkDealerChannelClientTransport implements ZLinkChannelClientTran
|
|
|
24
24
|
channelName: string,
|
|
25
25
|
packetName: string | undefined,
|
|
26
26
|
message: Message,
|
|
27
|
-
signal?: AbortSignal,
|
|
28
27
|
metadata: ReadonlyMap<string, string> = EMPTY_METADATA
|
|
29
28
|
): Promise<ZLinkSubmitResult> {
|
|
30
|
-
throwIfAborted(signal);
|
|
31
29
|
// Call-scoped flow (spec 27 §4): the envelope flow pair does not outlive
|
|
32
30
|
// this outbound call.
|
|
33
31
|
await runWithOutboundFlow(
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
createDealerSocket,
|
|
8
8
|
createRouterSocket,
|
|
9
9
|
ReceiveFlowState,
|
|
10
|
-
SubmitResult,
|
|
11
10
|
type Context,
|
|
12
11
|
type DealerSocket,
|
|
13
12
|
type MonitorEvent,
|
|
@@ -18,11 +17,13 @@ import {
|
|
|
18
17
|
type RequestOperation,
|
|
19
18
|
type RequestSubmitOperation,
|
|
20
19
|
type RouterSocket,
|
|
21
|
-
type SendOperation,
|
|
22
|
-
type SendSubmitOperation,
|
|
23
20
|
type Socket
|
|
24
21
|
} from '@zlink-systems/zlink';
|
|
25
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
translateBindingResultError,
|
|
24
|
+
bindingRequestReply,
|
|
25
|
+
submitBindingAsyncSend
|
|
26
|
+
} from './node-backend-adapter-support';
|
|
26
27
|
import { isEndpointCloseIgnorableError } from './node-socket-backend-adapter';
|
|
27
28
|
import { ZLinkNodeEventLoopPoller } from './node-event-loop-poller';
|
|
28
29
|
import type {
|
|
@@ -266,15 +267,10 @@ class NodeRawRouterPort extends NodeRawSocketPort<RouterSocket> implements ZLink
|
|
|
266
267
|
this.connect(endpoint);
|
|
267
268
|
}
|
|
268
269
|
|
|
269
|
-
|
|
270
|
+
send(targetRid: string, parts: readonly Uint8Array[]): Promise<void> {
|
|
270
271
|
this.requireOpen();
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
parts
|
|
274
|
-
).submit();
|
|
275
|
-
if (submission.result === SubmitResult.Backpressured) {
|
|
276
|
-
await submission.admitted;
|
|
277
|
-
}
|
|
272
|
+
requireParts(parts);
|
|
273
|
+
return submitBindingAsyncSend(this.socket.send(bindingRoutingId(targetRid)), parts);
|
|
278
274
|
}
|
|
279
275
|
|
|
280
276
|
async request(
|
|
@@ -283,6 +279,7 @@ class NodeRawRouterPort extends NodeRawSocketPort<RouterSocket> implements ZLink
|
|
|
283
279
|
timeoutMs: number
|
|
284
280
|
): Promise<readonly Buffer[]> {
|
|
285
281
|
this.requireOpen();
|
|
282
|
+
const deadlineMs = performance.now() + timeoutMs;
|
|
286
283
|
let submission: ReturnType<RequestSubmitOperation['submit']>;
|
|
287
284
|
try {
|
|
288
285
|
submission = appendRequestParts(this.socket.request(bindingRoutingId(targetRid)), parts)
|
|
@@ -292,7 +289,7 @@ class NodeRawRouterPort extends NodeRawSocketPort<RouterSocket> implements ZLink
|
|
|
292
289
|
throw translateBindingResultError(error, 'submit');
|
|
293
290
|
}
|
|
294
291
|
try {
|
|
295
|
-
const replies = await
|
|
292
|
+
const replies = await bindingRequestReply(submission, deadlineMs);
|
|
296
293
|
return copyAndClose(replies);
|
|
297
294
|
} catch (error) {
|
|
298
295
|
throw translateBindingResultError(error, 'completion');
|
|
@@ -338,16 +335,15 @@ class NodeRawDealerPort extends NodeRawSocketPort<DealerSocket> implements ZLink
|
|
|
338
335
|
this.socket.setRoutingId(bindingRoutingId(routingId));
|
|
339
336
|
}
|
|
340
337
|
|
|
341
|
-
|
|
338
|
+
send(parts: readonly Uint8Array[]): Promise<void> {
|
|
342
339
|
this.requireOpen();
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
await submission.admitted;
|
|
346
|
-
}
|
|
340
|
+
requireParts(parts);
|
|
341
|
+
return submitBindingAsyncSend(this.socket.send(), parts);
|
|
347
342
|
}
|
|
348
343
|
|
|
349
344
|
async request(parts: readonly Uint8Array[], timeoutMs: number): Promise<readonly Buffer[]> {
|
|
350
345
|
this.requireOpen();
|
|
346
|
+
const deadlineMs = performance.now() + timeoutMs;
|
|
351
347
|
let submission: ReturnType<RequestSubmitOperation['submit']>;
|
|
352
348
|
try {
|
|
353
349
|
submission = appendRequestParts(this.socket.request(), parts).timeout(timeoutMs).submit();
|
|
@@ -355,7 +351,7 @@ class NodeRawDealerPort extends NodeRawSocketPort<DealerSocket> implements ZLink
|
|
|
355
351
|
throw translateBindingResultError(error, 'submit');
|
|
356
352
|
}
|
|
357
353
|
try {
|
|
358
|
-
const replies = await
|
|
354
|
+
const replies = await bindingRequestReply(submission, deadlineMs);
|
|
359
355
|
return copyAndClose(replies);
|
|
360
356
|
} catch (error) {
|
|
361
357
|
throw translateBindingResultError(error, 'completion');
|
|
@@ -368,16 +364,6 @@ class NodeRawDealerPort extends NodeRawSocketPort<DealerSocket> implements ZLink
|
|
|
368
364
|
}
|
|
369
365
|
}
|
|
370
366
|
|
|
371
|
-
async function requestReply(
|
|
372
|
-
submission: ReturnType<RequestSubmitOperation['submit']>
|
|
373
|
-
): Promise<Message[]> {
|
|
374
|
-
if (submission.result === SubmitResult.Backpressured) {
|
|
375
|
-
const [, replies] = await Promise.all([submission.admitted, submission.reply]);
|
|
376
|
-
return replies;
|
|
377
|
-
}
|
|
378
|
-
return submission.reply;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
367
|
class NodeRawMonitorPort implements ZLinkRawMonitorPort {
|
|
382
368
|
private closed = false;
|
|
383
369
|
|
|
@@ -410,18 +396,6 @@ class NodeRawMonitorPort implements ZLinkRawMonitorPort {
|
|
|
410
396
|
}
|
|
411
397
|
}
|
|
412
398
|
|
|
413
|
-
function appendSendParts(
|
|
414
|
-
operation: SendOperation,
|
|
415
|
-
parts: readonly Uint8Array[]
|
|
416
|
-
): SendSubmitOperation {
|
|
417
|
-
requireParts(parts);
|
|
418
|
-
let next = operation.message(parts[0]);
|
|
419
|
-
for (let index = 1; index < parts.length; index += 1) {
|
|
420
|
-
next = next.message(parts[index]);
|
|
421
|
-
}
|
|
422
|
-
return next;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
399
|
function appendRequestParts(
|
|
426
400
|
operation: RequestOperation,
|
|
427
401
|
parts: readonly Uint8Array[]
|
|
@@ -297,19 +297,13 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
297
297
|
selectObjectPlacement(stableType: string): ZLinkBackendObjectPlacement {
|
|
298
298
|
const runtime = this.requireRuntime();
|
|
299
299
|
const localNodeRid = runtime.topology.localDescriptor().nodeRoutingId;
|
|
300
|
-
const status = runtime.topology.
|
|
300
|
+
const { status, descriptor } = runtime.topology.selectObjectPlacementWithStatus(
|
|
301
301
|
stableType,
|
|
302
302
|
(candidate) =>
|
|
303
303
|
candidate.nodeRoutingId === localNodeRid ||
|
|
304
304
|
runtime.isPeerRouteReady(candidate.nodeRoutingId)
|
|
305
305
|
);
|
|
306
306
|
if (status !== 'available') return { kind: status };
|
|
307
|
-
const descriptor = runtime.topology.selectObjectPlacement(
|
|
308
|
-
stableType,
|
|
309
|
-
(candidate) =>
|
|
310
|
-
candidate.nodeRoutingId === localNodeRid ||
|
|
311
|
-
runtime.isPeerRouteReady(candidate.nodeRoutingId)
|
|
312
|
-
);
|
|
313
307
|
return descriptor === undefined
|
|
314
308
|
? { kind: 'unavailable' }
|
|
315
309
|
: {
|
|
@@ -194,7 +194,7 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
194
194
|
}
|
|
195
195
|
return submitBindingAsyncSend(operation, payload);
|
|
196
196
|
},
|
|
197
|
-
submit(routingId: unknown, payload: unknown
|
|
197
|
+
submit(routingId: unknown, payload: unknown): Promise<void> {
|
|
198
198
|
if (!hasStream) throw new TypeError('Async stream send requires a STREAM socket.');
|
|
199
199
|
return submitBindingAsyncSend(
|
|
200
200
|
(nativeInstance as T & { send(routingId: unknown): ZLinkBindingAsyncSendOperation }).send(
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import {
|
|
21
21
|
requireOneWayCompletion,
|
|
22
22
|
requirePublishCompletion,
|
|
23
|
+
requireClassicFanoutCompletion,
|
|
23
24
|
throwAlreadySubmitted,
|
|
24
25
|
ZLinkSubmitStatus,
|
|
25
26
|
type ZLinkSubmitResult
|
|
@@ -176,14 +177,13 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
176
177
|
sendToNode(meshName: string, targetNodeRid: string, message: unknown): ZLinkSendCall {
|
|
177
178
|
return new DefaultZLinkSendCall(
|
|
178
179
|
() => this.requireMesh(meshName),
|
|
179
|
-
async (packetName, metadata
|
|
180
|
+
async (packetName, metadata) =>
|
|
180
181
|
normalizeSubmitResult(
|
|
181
182
|
await this.requireTransport().submit(
|
|
182
183
|
meshName,
|
|
183
184
|
targetNodeRid,
|
|
184
185
|
packetName,
|
|
185
186
|
message,
|
|
186
|
-
signal,
|
|
187
187
|
metadata
|
|
188
188
|
)
|
|
189
189
|
)
|
|
@@ -210,7 +210,7 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
210
210
|
sendToChannel(channelName: string, message: unknown): ZLinkSendCall {
|
|
211
211
|
return new DefaultZLinkSendCall(
|
|
212
212
|
() => this.requireChannelRoute(channelName),
|
|
213
|
-
async (packetName, metadata
|
|
213
|
+
async (packetName, metadata) => {
|
|
214
214
|
const route = this.requireChannelRoute(channelName);
|
|
215
215
|
if (route.kind === 'route-mesh') {
|
|
216
216
|
return normalizeSubmitResult(
|
|
@@ -219,19 +219,12 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
219
219
|
channelName,
|
|
220
220
|
packetName,
|
|
221
221
|
message,
|
|
222
|
-
signal,
|
|
223
222
|
metadata
|
|
224
223
|
)
|
|
225
224
|
);
|
|
226
225
|
}
|
|
227
226
|
return normalizeSubmitResult(
|
|
228
|
-
await this.requireChannelTransport().send(
|
|
229
|
-
channelName,
|
|
230
|
-
packetName,
|
|
231
|
-
message,
|
|
232
|
-
signal,
|
|
233
|
-
metadata
|
|
234
|
-
)
|
|
227
|
+
await this.requireChannelTransport().send(channelName, packetName, message, metadata)
|
|
235
228
|
);
|
|
236
229
|
}
|
|
237
230
|
);
|
|
@@ -271,9 +264,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
271
264
|
() => {
|
|
272
265
|
this.requireSpotTransport();
|
|
273
266
|
},
|
|
274
|
-
async (_packetName, metadata
|
|
267
|
+
async (_packetName, metadata) => {
|
|
275
268
|
await sendToSpotHandle(this.requireSpotTransport(), spot, message, {
|
|
276
|
-
signal,
|
|
277
269
|
metadata,
|
|
278
270
|
spotRouterChannelIdForMesh: this.spotRouterChannelIdForMesh
|
|
279
271
|
});
|
|
@@ -431,8 +423,7 @@ class DefaultZLinkSendCall implements ZLinkSendCall {
|
|
|
431
423
|
private readonly validate: () => void,
|
|
432
424
|
private readonly submitter: (
|
|
433
425
|
packetName: string | undefined,
|
|
434
|
-
metadata: ReadonlyMap<string, string
|
|
435
|
-
signal?: AbortSignal
|
|
426
|
+
metadata: ReadonlyMap<string, string>
|
|
436
427
|
) => Promise<ZLinkSubmitResult>
|
|
437
428
|
) {}
|
|
438
429
|
|
|
@@ -450,12 +441,11 @@ class DefaultZLinkSendCall implements ZLinkSendCall {
|
|
|
450
441
|
return this;
|
|
451
442
|
}
|
|
452
443
|
|
|
453
|
-
async submit(
|
|
444
|
+
async submit(): Promise<void> {
|
|
454
445
|
ensureNotExecuted(this.executed);
|
|
455
446
|
this.validate();
|
|
456
447
|
this.executed = true;
|
|
457
|
-
|
|
458
|
-
const result = await this.submitter(undefined, new Map(this.selectedMetadata), signal);
|
|
448
|
+
const result = await this.submitter(undefined, new Map(this.selectedMetadata));
|
|
459
449
|
requireOneWayCompletion(result, 'One-way send');
|
|
460
450
|
}
|
|
461
451
|
}
|
|
@@ -580,6 +570,6 @@ class DefaultZLinkFanoutPublishCall implements ZLinkFanoutPublishCall {
|
|
|
580
570
|
this.executed = true;
|
|
581
571
|
throwIfAborted(signal);
|
|
582
572
|
const result = await this.submitter(signal);
|
|
583
|
-
|
|
573
|
+
requireClassicFanoutCompletion(result, 'Classic fanout publish');
|
|
584
574
|
}
|
|
585
575
|
}
|
|
@@ -86,33 +86,18 @@ export function encodeChannelEnvelopeParts(
|
|
|
86
86
|
createFlow = true,
|
|
87
87
|
metadata: ReadonlyMap<string, string> = EMPTY_OUTBOUND_METADATA
|
|
88
88
|
): readonly MessageLike[] {
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
return encodeChannelEnvelopePartsAtDeadline(
|
|
90
|
+
kind,
|
|
91
|
+
channelName,
|
|
92
|
+
packetName,
|
|
91
93
|
payload,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
timeoutMs === undefined ? undefined : Date.now() + timeoutMs,
|
|
95
|
+
topic,
|
|
96
|
+
codecs,
|
|
97
|
+
correlationId,
|
|
98
|
+
createFlow,
|
|
99
|
+
metadata
|
|
95
100
|
);
|
|
96
|
-
const flow = createFlow ? currentOrCreateFlow('Application') : undefined;
|
|
97
|
-
const envelopeCorrelationId = correlationIdForOutboundKind(kind, correlationId);
|
|
98
|
-
return [
|
|
99
|
-
encodeChannelHeader(
|
|
100
|
-
kind,
|
|
101
|
-
channelName,
|
|
102
|
-
messageName,
|
|
103
|
-
encoded.contentType,
|
|
104
|
-
envelopeCorrelationId,
|
|
105
|
-
timeoutMs === undefined ? null : new Date(Date.now() + timeoutMs).toISOString(),
|
|
106
|
-
topic ?? null,
|
|
107
|
-
null,
|
|
108
|
-
null,
|
|
109
|
-
undefined,
|
|
110
|
-
applicationMetadataRecord(metadata),
|
|
111
|
-
flow?.flowId,
|
|
112
|
-
flow?.flowOrigin
|
|
113
|
-
),
|
|
114
|
-
encoded.message
|
|
115
|
-
];
|
|
116
101
|
}
|
|
117
102
|
|
|
118
103
|
/**
|
|
@@ -126,14 +111,17 @@ export function encodeChannelEnvelopePartsAtDeadline(
|
|
|
126
111
|
channelName: string,
|
|
127
112
|
packetName: string | undefined,
|
|
128
113
|
payload: unknown,
|
|
129
|
-
deadlineUnixMs: number,
|
|
114
|
+
deadlineUnixMs: number | undefined,
|
|
130
115
|
topic?: string,
|
|
131
116
|
codecs?: ZLinkChannelEnvelopeCodecRegistry,
|
|
132
117
|
correlationId?: string,
|
|
133
118
|
createFlow = true,
|
|
134
119
|
metadata: ReadonlyMap<string, string> = EMPTY_OUTBOUND_METADATA
|
|
135
120
|
): readonly MessageLike[] {
|
|
136
|
-
if (
|
|
121
|
+
if (
|
|
122
|
+
deadlineUnixMs !== undefined &&
|
|
123
|
+
(!Number.isSafeInteger(deadlineUnixMs) || deadlineUnixMs <= 0)
|
|
124
|
+
) {
|
|
137
125
|
throw new RangeError('deadlineUnixMs must be a positive safe integer.');
|
|
138
126
|
}
|
|
139
127
|
const messageName = resolveFrameworkPacketName(payload, packetName, 'Channel');
|
|
@@ -152,7 +140,7 @@ export function encodeChannelEnvelopePartsAtDeadline(
|
|
|
152
140
|
messageName,
|
|
153
141
|
encoded.contentType,
|
|
154
142
|
envelopeCorrelationId,
|
|
155
|
-
new Date(deadlineUnixMs).toISOString(),
|
|
143
|
+
deadlineUnixMs === undefined ? null : new Date(deadlineUnixMs).toISOString(),
|
|
156
144
|
topic ?? null,
|
|
157
145
|
null,
|
|
158
146
|
null,
|