@zlink-systems/framework 0.30.0 → 0.30.1
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/LICENSE +150 -68
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
- package/dist/contracts/Channels/Calls.d.ts +2 -1
- package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
- package/dist/contracts/Handlers/Attributes.d.ts +5 -13
- package/dist/contracts/Handlers/Attributes.js +7 -11
- package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
- package/dist/contracts/Handlers/JsonContract.js +4 -153
- package/dist/contracts/Spots/Contracts.d.ts +2 -1
- package/dist/nest-integration.d.ts +1 -1
- package/dist/nest-integration.js +2 -1
- package/dist/runtime/actors/actor-client.d.ts +1 -1
- package/dist/runtime/actors/actor-client.js +14 -12
- package/dist/runtime/actors/actor-handoff.d.ts +1 -1
- package/dist/runtime/actors/actor-handoff.js +7 -4
- package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
- package/dist/runtime/actors/actor-local-native-join.js +9 -12
- package/dist/runtime/actors/actor-remote-wire.js +15 -0
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
- package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
- package/dist/runtime/actors/index.d.ts +2 -1
- package/dist/runtime/actors/index.js +18 -6
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
- package/dist/runtime/admission.d.ts +1 -1
- package/dist/runtime/admission.js +15 -5
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +2 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +37 -22
- package/dist/runtime/application-jobs/contracts.d.ts +10 -1
- package/dist/runtime/backend/contracts/index.d.ts +18 -9
- package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
- package/dist/runtime/backend/mesh-completion-table.js +149 -49
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
- package/dist/runtime/backend/mesh-dispatch-pump.js +32 -11
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
- 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 +5 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +42 -22
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +13 -5
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +69 -51
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +6 -6
- package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
- package/dist/runtime/backend/runtime-message.d.ts +1 -0
- package/dist/runtime/backend/runtime-message.js +5 -0
- package/dist/runtime/backend/runtime-values.d.ts +1 -0
- package/dist/runtime/backend/runtime-values.js +2 -1
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +58 -21
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
- package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
- package/dist/runtime/channels/channel-dispatch-services.js +45 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
- package/dist/runtime/channels/channel-dispatchers.js +27 -26
- package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
- package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +83 -8
- package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
- package/dist/runtime/channels/channel-runtime-manager.js +12 -12
- package/dist/runtime/channels/channel-transports.d.ts +18 -15
- package/dist/runtime/channels/channel-transports.js +48 -31
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +2 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
- package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
- package/dist/runtime/channels/source-spot-router.d.ts +2 -2
- package/dist/runtime/channels/source-spot-router.js +4 -4
- package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-node-route-transport.js +4 -4
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
- package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
- package/dist/runtime/execution/serial-execution-queue.js +1 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
- package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
- package/dist/runtime/foundation/durable-service-request.js +98 -0
- package/dist/runtime/foundation/operation-identity.d.ts +1 -0
- package/dist/runtime/foundation/operation-identity.js +5 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +22 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +356 -232
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
- package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
- package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -4
- package/dist/runtime/foundation/service-stateful-runtime.js +44 -103
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -5
- package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
- package/dist/runtime/foundation/service-topology-registry.js +61 -27
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
- package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
- package/dist/runtime/handlers/handler-instance-scope.js +54 -11
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
- package/dist/runtime/host/application-job-queue.d.ts +19 -7
- package/dist/runtime/host/application-job-queue.js +150 -42
- package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
- package/dist/runtime/host/entry-actor-runtime.js +3 -0
- package/dist/runtime/host/index.d.ts +7 -1
- package/dist/runtime/host/index.js +142 -118
- package/dist/runtime/host/remote-bound-session-relay.js +2 -18
- package/dist/runtime/host/route-mesh-runtime.js +1 -1
- package/dist/runtime/host/service-relocation-control.d.ts +1 -0
- package/dist/runtime/host/service-relocation-control.js +10 -4
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
- package/dist/runtime/host/service-relocation-host-runtime.js +213 -241
- package/dist/runtime/host/spot-address-transport.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.js +1 -0
- package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
- package/dist/runtime/locations/actor-location-claims.js +34 -19
- package/dist/runtime/locations/lifecycle.d.ts +1 -2
- package/dist/runtime/locations/lifecycle.js +2 -5
- package/dist/runtime/locations/runtime.d.ts +1 -1
- package/dist/runtime/locations/runtime.js +24 -23
- package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
- package/dist/runtime/messaging/framework-json-v1.js +38 -294
- package/dist/runtime/messaging/packet-name.d.ts +1 -1
- package/dist/runtime/messaging/packet-name.js +8 -24
- package/dist/runtime/messaging/request-result.d.ts +2 -0
- package/dist/runtime/messaging/request-result.js +54 -0
- package/dist/runtime/messaging/submission-result.d.ts +1 -0
- package/dist/runtime/messaging/submission-result.js +5 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
- package/dist/runtime/spots/index.d.ts +3 -0
- package/dist/runtime/spots/index.js +9 -2
- package/dist/runtime/spots/spot-activation.d.ts +1 -0
- package/dist/runtime/spots/spot-activation.js +17 -8
- package/dist/runtime/spots/spot-entry-activation.js +6 -2
- package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
- package/dist/runtime/spots/spot-handler-registry.js +18 -8
- package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
- package/dist/runtime/spots/spot-outbound.d.ts +3 -0
- package/dist/runtime/spots/spot-outbound.js +24 -15
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -0
- package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
- package/dist/runtime/spots/spot-timer.js +1 -0
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
- package/dist/runtime/streams/stream-session-runtime.js +13 -27
- package/package.json +2 -2
- package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
- package/src/contracts/Channels/Calls.ts +2 -1
- package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
- package/src/contracts/Handlers/Attributes.ts +14 -21
- package/src/contracts/Handlers/JsonContract.ts +8 -216
- package/src/contracts/Spots/Contracts.ts +2 -1
- package/src/nest-integration.ts +1 -0
- package/src/runtime/actors/actor-client.ts +40 -16
- package/src/runtime/actors/actor-handoff.ts +9 -4
- package/src/runtime/actors/actor-join-relocation.ts +1 -0
- package/src/runtime/actors/actor-local-native-join.ts +17 -26
- package/src/runtime/actors/actor-remote-wire.ts +17 -0
- package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
- package/src/runtime/actors/actor-routed-json-request.ts +10 -2
- package/src/runtime/actors/index.ts +19 -5
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
- package/src/runtime/admission.ts +18 -5
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
- package/src/runtime/application-jobs/application-job-queue-scope.ts +51 -22
- package/src/runtime/application-jobs/contracts.ts +14 -1
- package/src/runtime/backend/contracts/index.ts +53 -14
- package/src/runtime/backend/mesh-completion-table.ts +156 -57
- package/src/runtime/backend/mesh-dispatch-pump.ts +40 -10
- package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +57 -30
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +128 -65
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +21 -6
- package/src/runtime/backend/raw-binding-port.ts +7 -2
- package/src/runtime/backend/runtime-message.ts +6 -0
- package/src/runtime/backend/runtime-values.ts +1 -0
- package/src/runtime/channels/channel-clients.ts +90 -41
- package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
- package/src/runtime/channels/channel-dispatch-services.ts +69 -1
- package/src/runtime/channels/channel-dispatchers.ts +29 -27
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
- package/src/runtime/channels/channel-envelope.ts +133 -8
- package/src/runtime/channels/channel-outbound-operations.ts +22 -8
- package/src/runtime/channels/channel-runtime-manager.ts +29 -12
- package/src/runtime/channels/channel-transports.ts +128 -60
- package/src/runtime/channels/local-spot-route-transport.ts +3 -1
- package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
- package/src/runtime/channels/source-spot-router.ts +8 -4
- package/src/runtime/channels/spot-node-route-transport.ts +8 -4
- package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
- package/src/runtime/execution/serial-execution-queue.ts +2 -0
- package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
- package/src/runtime/foundation/durable-service-request.ts +137 -0
- package/src/runtime/foundation/operation-identity.ts +5 -1
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +484 -293
- package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
- package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
- package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
- package/src/runtime/foundation/service-stateful-runtime.ts +67 -125
- package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -5
- package/src/runtime/foundation/service-topology-registry.ts +91 -36
- package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
- package/src/runtime/handlers/handler-instance-scope.ts +67 -16
- package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
- package/src/runtime/host/application-job-queue.ts +175 -41
- package/src/runtime/host/entry-actor-runtime.ts +4 -0
- package/src/runtime/host/index.ts +201 -156
- package/src/runtime/host/remote-bound-session-relay.ts +2 -23
- package/src/runtime/host/route-mesh-runtime.ts +1 -1
- package/src/runtime/host/service-relocation-control.ts +11 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +315 -291
- package/src/runtime/host/spot-address-transport.ts +4 -2
- package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
- package/src/runtime/locations/actor-location-claims.ts +52 -30
- package/src/runtime/locations/lifecycle.ts +8 -26
- package/src/runtime/locations/runtime.ts +28 -24
- package/src/runtime/messaging/framework-json-v1.ts +5 -325
- package/src/runtime/messaging/packet-name.ts +5 -25
- package/src/runtime/messaging/request-result.ts +58 -0
- package/src/runtime/messaging/submission-result.ts +5 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +43 -23
- package/src/runtime/spots/index.ts +14 -2
- package/src/runtime/spots/spot-activation.ts +28 -10
- package/src/runtime/spots/spot-entry-activation.ts +9 -2
- package/src/runtime/spots/spot-handler-registry.ts +41 -8
- package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
- package/src/runtime/spots/spot-outbound.ts +36 -16
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
- package/src/runtime/spots/spot-runtime-ports.ts +1 -0
- package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
- package/src/runtime/spots/spot-timer.ts +5 -1
- package/src/runtime/streams/stream-session-runtime.ts +12 -29
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_REQUEST_TIMEOUT_MS } from '../../contracts/Configuration/Registration';
|
|
2
|
+
import { createZLinkRequest } from '../messaging/request-result';
|
|
3
|
+
import type { ZLinkRequest } from '../../contracts/Handlers/Attributes';
|
|
2
4
|
import type {
|
|
3
5
|
ZLinkChannelClient,
|
|
4
6
|
ZLinkChannelRequestCall,
|
|
@@ -23,6 +25,7 @@ import {
|
|
|
23
25
|
requireClassicFanoutCompletion,
|
|
24
26
|
throwAlreadySubmitted,
|
|
25
27
|
ZLinkSubmitStatus,
|
|
28
|
+
submittedResult,
|
|
26
29
|
type ZLinkSubmitResult
|
|
27
30
|
} from '../messaging/submission-result';
|
|
28
31
|
import type {
|
|
@@ -165,7 +168,17 @@ export class DefaultZLinkFanoutClient implements ZLinkFanoutClient {
|
|
|
165
168
|
}
|
|
166
169
|
}
|
|
167
170
|
|
|
171
|
+
interface PreparedNodeSend {
|
|
172
|
+
readonly validate: () => void;
|
|
173
|
+
readonly submit: (
|
|
174
|
+
packetName: string | undefined,
|
|
175
|
+
metadata: ReadonlyMap<string, string>,
|
|
176
|
+
message?: unknown
|
|
177
|
+
) => ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
|
|
178
|
+
}
|
|
179
|
+
|
|
168
180
|
export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
181
|
+
private readonly nodeSends = new Map<string, Map<string, PreparedNodeSend>>();
|
|
169
182
|
constructor(
|
|
170
183
|
private readonly registration: ZLinkFrameworkRegistration,
|
|
171
184
|
private readonly transport?: ZLinkRouteClientTransport,
|
|
@@ -175,25 +188,28 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
175
188
|
) {}
|
|
176
189
|
|
|
177
190
|
sendToNode(meshName: string, targetNodeRid: string, message: unknown): ZLinkSendCall {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
191
|
+
let targets = this.nodeSends.get(meshName);
|
|
192
|
+
if (targets === undefined) this.nodeSends.set(meshName, (targets = new Map()));
|
|
193
|
+
let prepared = targets.get(targetNodeRid);
|
|
194
|
+
if (prepared === undefined) {
|
|
195
|
+
prepared = {
|
|
196
|
+
validate: () => {
|
|
197
|
+
this.requireMesh(meshName);
|
|
198
|
+
},
|
|
199
|
+
submit: (packetName, metadata, payload) =>
|
|
200
|
+
normalizeSubmitResult(
|
|
201
|
+
this.requireTransport().submit(meshName, targetNodeRid, packetName, payload, metadata)
|
|
188
202
|
)
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
};
|
|
204
|
+
targets.set(targetNodeRid, prepared);
|
|
205
|
+
}
|
|
206
|
+
return new DefaultZLinkSendCall(prepared.validate, prepared.submit, message);
|
|
191
207
|
}
|
|
192
208
|
|
|
193
209
|
requestToNode(meshName: string, targetNodeRid: string, request: unknown): ZLinkRequestCall {
|
|
194
210
|
return new DefaultZLinkRequestCall(
|
|
195
211
|
() => this.requireMesh(meshName),
|
|
196
|
-
(packetName, timeoutMs, metadata, signal) =>
|
|
212
|
+
(packetName, timeoutMs, metadata, signal, onAdmitted) =>
|
|
197
213
|
this.requireTransport().request(
|
|
198
214
|
meshName,
|
|
199
215
|
targetNodeRid,
|
|
@@ -201,7 +217,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
201
217
|
request,
|
|
202
218
|
timeoutMs,
|
|
203
219
|
signal,
|
|
204
|
-
metadata
|
|
220
|
+
metadata,
|
|
221
|
+
onAdmitted
|
|
205
222
|
),
|
|
206
223
|
this.defaultRequestTimeout(meshName)
|
|
207
224
|
);
|
|
@@ -233,7 +250,7 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
233
250
|
requestToChannel(channelName: string, request: unknown): ZLinkChannelRequestCall {
|
|
234
251
|
return new DefaultZLinkRequestCall(
|
|
235
252
|
() => this.requireChannelRoute(channelName),
|
|
236
|
-
(packetName, timeoutMs, metadata, signal) => {
|
|
253
|
+
(packetName, timeoutMs, metadata, signal, onAdmitted) => {
|
|
237
254
|
const route = this.requireChannelRoute(channelName);
|
|
238
255
|
if (route.kind === 'route-mesh') {
|
|
239
256
|
return this.requireTransport().requestToChannel(
|
|
@@ -243,7 +260,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
243
260
|
request,
|
|
244
261
|
timeoutMs,
|
|
245
262
|
signal,
|
|
246
|
-
metadata
|
|
263
|
+
metadata,
|
|
264
|
+
onAdmitted
|
|
247
265
|
);
|
|
248
266
|
}
|
|
249
267
|
return this.requireChannelTransport().request(
|
|
@@ -252,7 +270,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
252
270
|
request,
|
|
253
271
|
timeoutMs,
|
|
254
272
|
signal,
|
|
255
|
-
metadata
|
|
273
|
+
metadata,
|
|
274
|
+
onAdmitted
|
|
256
275
|
);
|
|
257
276
|
},
|
|
258
277
|
this.defaultRequestTimeoutForChannel(channelName)
|
|
@@ -279,11 +298,12 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
|
|
|
279
298
|
() => {
|
|
280
299
|
this.requireSpotTransport();
|
|
281
300
|
},
|
|
282
|
-
(_packetName, timeoutMs, metadata, signal) =>
|
|
301
|
+
(_packetName, timeoutMs, metadata, signal, onAdmitted) =>
|
|
283
302
|
requestToSpotHandle(this.requireSpotTransport(), spot, request, {
|
|
284
303
|
timeoutMs,
|
|
285
304
|
signal,
|
|
286
305
|
metadata,
|
|
306
|
+
onAdmitted,
|
|
287
307
|
spotRouterChannelIdForMesh: this.spotRouterChannelIdForMesh
|
|
288
308
|
}),
|
|
289
309
|
this.registration.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS
|
|
@@ -416,21 +436,24 @@ export class DefaultZLinkSpotPublisherClient implements ZLinkSpotPublisherClient
|
|
|
416
436
|
}
|
|
417
437
|
|
|
418
438
|
class DefaultZLinkSendCall implements ZLinkSendCall {
|
|
419
|
-
private
|
|
439
|
+
private selectedMetadata?: Map<string, string>;
|
|
420
440
|
private executed = false;
|
|
421
441
|
|
|
422
442
|
constructor(
|
|
423
443
|
private readonly validate: () => void,
|
|
424
444
|
private readonly submitter: (
|
|
425
445
|
packetName: string | undefined,
|
|
426
|
-
metadata: ReadonlyMap<string, string
|
|
427
|
-
|
|
446
|
+
metadata: ReadonlyMap<string, string>,
|
|
447
|
+
message?: unknown
|
|
448
|
+
) => ZLinkSubmitResult | Promise<ZLinkSubmitResult>,
|
|
449
|
+
private readonly message?: unknown
|
|
428
450
|
) {}
|
|
429
451
|
|
|
430
452
|
metadata(key: string, value: string): this;
|
|
431
453
|
metadata(metadata: ZLinkMessageMetadata): this;
|
|
432
454
|
metadata(keyOrMetadata: string | ZLinkMessageMetadata, value?: string): this {
|
|
433
455
|
ensureNotExecuted(this.executed);
|
|
456
|
+
this.selectedMetadata ??= new Map<string, string>();
|
|
434
457
|
if (typeof keyOrMetadata === 'string') {
|
|
435
458
|
this.selectedMetadata.set(keyOrMetadata, value!);
|
|
436
459
|
} else {
|
|
@@ -441,12 +464,22 @@ class DefaultZLinkSendCall implements ZLinkSendCall {
|
|
|
441
464
|
return this;
|
|
442
465
|
}
|
|
443
466
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
467
|
+
submit(): Promise<void> {
|
|
468
|
+
try {
|
|
469
|
+
ensureNotExecuted(this.executed);
|
|
470
|
+
this.validate();
|
|
471
|
+
this.executed = true;
|
|
472
|
+
const result = this.submitter(
|
|
473
|
+
undefined,
|
|
474
|
+
this.selectedMetadata ?? EMPTY_CALL_METADATA,
|
|
475
|
+
this.message
|
|
476
|
+
);
|
|
477
|
+
if (result instanceof Promise) return result.then(completeOneWaySend);
|
|
478
|
+
completeOneWaySend(result);
|
|
479
|
+
return completedOneWaySend;
|
|
480
|
+
} catch (error) {
|
|
481
|
+
return Promise.reject(error);
|
|
482
|
+
}
|
|
450
483
|
}
|
|
451
484
|
}
|
|
452
485
|
|
|
@@ -456,13 +489,24 @@ function ensureNotExecuted(executed: boolean): void {
|
|
|
456
489
|
}
|
|
457
490
|
}
|
|
458
491
|
|
|
459
|
-
|
|
460
|
-
|
|
492
|
+
const EMPTY_CALL_METADATA: ReadonlyMap<string, string> = new Map();
|
|
493
|
+
const completedOneWaySend = Promise.resolve();
|
|
494
|
+
|
|
495
|
+
function completeOneWaySend(result: ZLinkSubmitResult): void {
|
|
496
|
+
requireOneWayCompletion(result, 'One-way send');
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function normalizeSubmitResult(
|
|
500
|
+
result: void | ZLinkSubmitResult | Promise<void | ZLinkSubmitResult>
|
|
501
|
+
): ZLinkSubmitResult | Promise<ZLinkSubmitResult> {
|
|
502
|
+
return result instanceof Promise
|
|
503
|
+
? result.then((value) => value ?? submittedResult)
|
|
504
|
+
: (result ?? submittedResult);
|
|
461
505
|
}
|
|
462
506
|
|
|
463
507
|
class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
|
|
464
508
|
private timeoutMs?: number;
|
|
465
|
-
private
|
|
509
|
+
private selectedMetadata?: Map<string, string>;
|
|
466
510
|
private readonly turn: ZLinkSpotSerialTurn | undefined = captureZLinkSpotSerialTurn();
|
|
467
511
|
|
|
468
512
|
constructor(
|
|
@@ -471,7 +515,8 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
|
|
|
471
515
|
packetName: string | undefined,
|
|
472
516
|
timeoutMs: number | undefined,
|
|
473
517
|
metadata: ReadonlyMap<string, string>,
|
|
474
|
-
signal?: AbortSignal
|
|
518
|
+
signal?: AbortSignal,
|
|
519
|
+
onAdmitted?: () => void
|
|
475
520
|
) => Promise<TReply>,
|
|
476
521
|
private readonly defaultRequestTimeoutMs?: number
|
|
477
522
|
) {}
|
|
@@ -479,6 +524,7 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
|
|
|
479
524
|
metadata(key: string, value: string): this;
|
|
480
525
|
metadata(metadata: ZLinkMessageMetadata): this;
|
|
481
526
|
metadata(keyOrMetadata: string | ZLinkMessageMetadata, value?: string): this {
|
|
527
|
+
this.selectedMetadata ??= new Map<string, string>();
|
|
482
528
|
if (typeof keyOrMetadata === 'string') {
|
|
483
529
|
this.selectedMetadata.set(keyOrMetadata, value!);
|
|
484
530
|
} else {
|
|
@@ -494,15 +540,18 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
|
|
|
494
540
|
return this;
|
|
495
541
|
}
|
|
496
542
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
543
|
+
submit<TReply>(signal?: AbortSignal): ZLinkRequest<TReply> {
|
|
544
|
+
return createZLinkRequest((onAdmitted) => {
|
|
545
|
+
throwIfAborted(signal);
|
|
546
|
+
this.validate();
|
|
547
|
+
return this.submitter<TReply>(
|
|
548
|
+
undefined,
|
|
549
|
+
this.timeoutMs ?? this.defaultRequestTimeoutMs,
|
|
550
|
+
this.selectedMetadata === undefined ? EMPTY_CALL_METADATA : new Map(this.selectedMetadata),
|
|
551
|
+
signal,
|
|
552
|
+
onAdmitted
|
|
553
|
+
);
|
|
554
|
+
});
|
|
506
555
|
}
|
|
507
556
|
|
|
508
557
|
async yield<TReply>(signal?: AbortSignal): Promise<TReply> {
|
|
@@ -512,7 +561,7 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
|
|
|
512
561
|
const pending = this.submitter<TReply>(
|
|
513
562
|
undefined,
|
|
514
563
|
this.timeoutMs ?? this.defaultRequestTimeoutMs,
|
|
515
|
-
new Map(this.selectedMetadata),
|
|
564
|
+
this.selectedMetadata === undefined ? EMPTY_CALL_METADATA : new Map(this.selectedMetadata),
|
|
516
565
|
signal
|
|
517
566
|
);
|
|
518
567
|
return turn.yieldPromise(pending);
|
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
import { invokeZLinkHandlerFilters } from '../handlers';
|
|
27
27
|
import {
|
|
28
28
|
decodeChannelPayload,
|
|
29
|
-
ZLinkChannelMessageKind,
|
|
30
29
|
type ZLinkChannelEnvelope,
|
|
31
30
|
type ZLinkChannelEnvelopeCodecRegistry
|
|
32
31
|
} from './channel-envelope';
|
|
@@ -74,8 +73,8 @@ interface ZLinkRequestDispatch<TContext extends ZLinkMessageContext> {
|
|
|
74
73
|
readonly context: TContext;
|
|
75
74
|
readonly signal?: AbortSignal;
|
|
76
75
|
readonly missingHandlerMessage: string;
|
|
77
|
-
readonly writeReply: (reply: unknown) => Promise<void>;
|
|
78
|
-
readonly writeError: (error: unknown) => Promise<void>;
|
|
76
|
+
readonly writeReply: (reply: unknown) => void | Promise<void>;
|
|
77
|
+
readonly writeError: (error: unknown) => void | Promise<void>;
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
export class ZLinkChannelDispatchPipeline {
|
|
@@ -113,17 +112,27 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
113
112
|
this.options.dispatchErrors.flow.flowCreationEnabled(),
|
|
114
113
|
undefined
|
|
115
114
|
);
|
|
116
|
-
const invocation = await
|
|
117
|
-
this.invoke(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
const invocation = await (flow === undefined
|
|
116
|
+
? this.invoke(
|
|
117
|
+
dispatch.envelope,
|
|
118
|
+
dispatch.codecs,
|
|
119
|
+
dispatch.handler,
|
|
120
|
+
dispatch.context,
|
|
121
|
+
dispatch.fields,
|
|
122
|
+
dispatch.signal
|
|
123
|
+
)
|
|
124
|
+
: runWithFlow(flow, () =>
|
|
125
|
+
this.invoke(
|
|
126
|
+
dispatch.envelope,
|
|
127
|
+
dispatch.codecs,
|
|
128
|
+
dispatch.handler!,
|
|
129
|
+
dispatch.context,
|
|
130
|
+
dispatch.fields,
|
|
131
|
+
dispatch.signal
|
|
132
|
+
)
|
|
133
|
+
));
|
|
134
|
+
|
|
135
|
+
if (invocation !== HANDLER_FILTER_REJECTED) {
|
|
127
136
|
this.trace(ZLinkMessageFlowOutcome.Completed, dispatch.fields);
|
|
128
137
|
}
|
|
129
138
|
} catch (error) {
|
|
@@ -165,23 +174,33 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
165
174
|
this.options.dispatchErrors.flow.flowCreationEnabled(),
|
|
166
175
|
undefined
|
|
167
176
|
);
|
|
168
|
-
const invocation = await
|
|
169
|
-
this.invoke(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
const invocation = await (flow === undefined
|
|
178
|
+
? this.invoke(
|
|
179
|
+
dispatch.envelope,
|
|
180
|
+
dispatch.codecs,
|
|
181
|
+
dispatch.handler,
|
|
182
|
+
dispatch.context,
|
|
183
|
+
dispatch.fields,
|
|
184
|
+
dispatch.signal
|
|
185
|
+
)
|
|
186
|
+
: runWithFlow(flow, () =>
|
|
187
|
+
this.invoke(
|
|
188
|
+
dispatch.envelope,
|
|
189
|
+
dispatch.codecs,
|
|
190
|
+
dispatch.handler!,
|
|
191
|
+
dispatch.context,
|
|
192
|
+
dispatch.fields,
|
|
193
|
+
dispatch.signal
|
|
194
|
+
)
|
|
195
|
+
));
|
|
196
|
+
|
|
197
|
+
if (invocation === HANDLER_FILTER_REJECTED) {
|
|
179
198
|
throw createInternalFrameworkException(
|
|
180
199
|
ZLinkFrameworkInternalErrorKind.RequestRejected,
|
|
181
200
|
`A handler filter rejected '${this.options.channelName}:${dispatch.fields.packetName}'.`
|
|
182
201
|
);
|
|
183
202
|
}
|
|
184
|
-
reply = invocation
|
|
203
|
+
reply = invocation;
|
|
185
204
|
} catch (error) {
|
|
186
205
|
try {
|
|
187
206
|
await dispatch.writeError(error);
|
|
@@ -206,7 +225,8 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
206
225
|
}
|
|
207
226
|
|
|
208
227
|
try {
|
|
209
|
-
|
|
228
|
+
const written = dispatch.writeReply(reply);
|
|
229
|
+
if (written !== undefined) await written;
|
|
210
230
|
this.trace(ZLinkMessageFlowOutcome.Replied, dispatch.fields);
|
|
211
231
|
} catch (error) {
|
|
212
232
|
// Spec 26 §3.1: a failed reply write means the reply delivery path is
|
|
@@ -240,9 +260,7 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
240
260
|
readonly writeProtocolError?: (error: ZLinkFrameworkException) => Promise<void>;
|
|
241
261
|
}): Promise<void> {
|
|
242
262
|
const { info } = input;
|
|
243
|
-
const isRequest =
|
|
244
|
-
info.kind === ZLinkChannelMessageKind.Request ||
|
|
245
|
-
(info.kind === undefined && input.transportRequest);
|
|
263
|
+
const isRequest = input.transportRequest;
|
|
246
264
|
let replied = false;
|
|
247
265
|
if (isRequest && input.writeProtocolError !== undefined && info.correlationId !== undefined) {
|
|
248
266
|
const protocolError = new ZLinkFrameworkException(
|
|
@@ -271,22 +289,37 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
271
289
|
});
|
|
272
290
|
}
|
|
273
291
|
|
|
274
|
-
private
|
|
292
|
+
private invoke<TContext extends ZLinkMessageContext, TResult>(
|
|
275
293
|
envelope: ZLinkChannelEnvelope,
|
|
276
294
|
codecs: ZLinkChannelEnvelopeCodecRegistry | undefined,
|
|
277
295
|
handler: ZLinkChannelDispatchHandler<TContext, TResult>,
|
|
278
296
|
context: TContext,
|
|
279
297
|
fields: ZLinkChannelDispatchFields,
|
|
280
298
|
signal?: AbortSignal
|
|
281
|
-
):
|
|
299
|
+
):
|
|
300
|
+
| TResult
|
|
301
|
+
| undefined
|
|
302
|
+
| typeof HANDLER_FILTER_REJECTED
|
|
303
|
+
| Promise<TResult | undefined | typeof HANDLER_FILTER_REJECTED> {
|
|
282
304
|
releaseApplicationJobPermitBeforeHandler();
|
|
283
305
|
if (this.filters.length === 0) {
|
|
284
306
|
// Fast path for the dominant unfiltered dispatch: skip the filter
|
|
285
307
|
// context object and chain machinery entirely.
|
|
286
308
|
const payload = decodeChannelPayload(envelope, codecs);
|
|
287
309
|
this.trace(ZLinkMessageFlowOutcome.Dispatched, fields);
|
|
288
|
-
return
|
|
310
|
+
return handler.handle(payload, context);
|
|
289
311
|
}
|
|
312
|
+
return this.invokeFiltered(envelope, codecs, handler, context, fields, signal);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private async invokeFiltered<TContext extends ZLinkMessageContext, TResult>(
|
|
316
|
+
envelope: ZLinkChannelEnvelope,
|
|
317
|
+
codecs: ZLinkChannelEnvelopeCodecRegistry | undefined,
|
|
318
|
+
handler: ZLinkChannelDispatchHandler<TContext, TResult>,
|
|
319
|
+
context: TContext,
|
|
320
|
+
fields: ZLinkChannelDispatchFields,
|
|
321
|
+
signal?: AbortSignal
|
|
322
|
+
): Promise<TResult | undefined | typeof HANDLER_FILTER_REJECTED> {
|
|
290
323
|
let value: TResult | undefined;
|
|
291
324
|
const handlerInvoked = await invokeZLinkHandlerFilters(
|
|
292
325
|
this.filters,
|
|
@@ -300,7 +333,7 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
300
333
|
},
|
|
301
334
|
signal
|
|
302
335
|
);
|
|
303
|
-
return
|
|
336
|
+
return handlerInvoked ? value : HANDLER_FILTER_REJECTED;
|
|
304
337
|
}
|
|
305
338
|
|
|
306
339
|
private createFilterContext(
|
|
@@ -401,6 +434,8 @@ export class ZLinkChannelDispatchPipeline {
|
|
|
401
434
|
}
|
|
402
435
|
}
|
|
403
436
|
|
|
437
|
+
const HANDLER_FILTER_REJECTED = Symbol('handler-filter-rejected');
|
|
438
|
+
|
|
404
439
|
const DEFAULT_UNHANDLED_DISPATCH: ZLinkUnhandledDispatchOptions = {
|
|
405
440
|
request: ZLinkUnhandledDispatchAction.ReplyError,
|
|
406
441
|
send: ZLinkUnhandledDispatchAction.LogAndDrop,
|
|
@@ -26,7 +26,11 @@ import {
|
|
|
26
26
|
import type { ZLinkRuntimeTaskErrorSink } from '../execution';
|
|
27
27
|
import { ZLinkDispatchErrorReporter } from './dispatch-error-reporter';
|
|
28
28
|
import { invokeZLinkHandlerFilters } from '../handlers';
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
runInHandlerInstanceScope,
|
|
31
|
+
prepareHandlerInstance,
|
|
32
|
+
handlerInstanceCleanup
|
|
33
|
+
} from '../handlers/handler-instance-scope';
|
|
30
34
|
import { handlerFilterScope } from './handler-filter-scope';
|
|
31
35
|
import type {
|
|
32
36
|
ZLinkChannelRequestHandler,
|
|
@@ -109,6 +113,17 @@ export class ZLinkChannelDispatchServices {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
channelRequestHandler(handlerType: Type): ZLinkChannelRequestHandler {
|
|
116
|
+
const activate =
|
|
117
|
+
this.registration.filterTypes.length === 0
|
|
118
|
+
? prepareHandlerInstance(
|
|
119
|
+
this.providerResolver,
|
|
120
|
+
handlerType as Type<ZLinkChannelRequestHandler>
|
|
121
|
+
)
|
|
122
|
+
: undefined;
|
|
123
|
+
if (activate !== undefined)
|
|
124
|
+
return {
|
|
125
|
+
handle: (payload, context) => this.invokeScopeFreeHandler(activate, payload, context)
|
|
126
|
+
};
|
|
112
127
|
return {
|
|
113
128
|
handle: (payload, context) =>
|
|
114
129
|
this.withHandlerScope(context, async (scope) => {
|
|
@@ -119,6 +134,17 @@ export class ZLinkChannelDispatchServices {
|
|
|
119
134
|
}
|
|
120
135
|
|
|
121
136
|
channelSendHandler(handlerType: Type): ZLinkChannelSendHandler {
|
|
137
|
+
const activate =
|
|
138
|
+
this.registration.filterTypes.length === 0
|
|
139
|
+
? prepareHandlerInstance(
|
|
140
|
+
this.providerResolver,
|
|
141
|
+
handlerType as Type<ZLinkChannelSendHandler>
|
|
142
|
+
)
|
|
143
|
+
: undefined;
|
|
144
|
+
if (activate !== undefined)
|
|
145
|
+
return {
|
|
146
|
+
handle: (payload, context) => this.invokeScopeFreeHandler(activate, payload, context)
|
|
147
|
+
};
|
|
122
148
|
return {
|
|
123
149
|
handle: (payload, context) =>
|
|
124
150
|
this.withHandlerScope(context, async (scope) => {
|
|
@@ -129,6 +155,17 @@ export class ZLinkChannelDispatchServices {
|
|
|
129
155
|
}
|
|
130
156
|
|
|
131
157
|
routeRequestHandler(handlerType: Type): ZLinkRouteRuntimeRequestHandler {
|
|
158
|
+
const activate =
|
|
159
|
+
this.registration.filterTypes.length === 0
|
|
160
|
+
? prepareHandlerInstance(
|
|
161
|
+
this.providerResolver,
|
|
162
|
+
handlerType as Type<ZLinkRouteRuntimeRequestHandler>
|
|
163
|
+
)
|
|
164
|
+
: undefined;
|
|
165
|
+
if (activate !== undefined)
|
|
166
|
+
return {
|
|
167
|
+
handle: (payload, context) => this.invokeScopeFreeHandler(activate, payload, context)
|
|
168
|
+
};
|
|
132
169
|
return {
|
|
133
170
|
handle: (payload, context) =>
|
|
134
171
|
this.withHandlerScope(context, async (scope) => {
|
|
@@ -139,6 +176,17 @@ export class ZLinkChannelDispatchServices {
|
|
|
139
176
|
}
|
|
140
177
|
|
|
141
178
|
routeSendHandler(handlerType: Type): ZLinkRouteRuntimeSendHandler {
|
|
179
|
+
const activate =
|
|
180
|
+
this.registration.filterTypes.length === 0
|
|
181
|
+
? prepareHandlerInstance(
|
|
182
|
+
this.providerResolver,
|
|
183
|
+
handlerType as Type<ZLinkRouteRuntimeSendHandler>
|
|
184
|
+
)
|
|
185
|
+
: undefined;
|
|
186
|
+
if (activate !== undefined)
|
|
187
|
+
return {
|
|
188
|
+
handle: (payload, context) => this.invokeScopeFreeHandler(activate, payload, context)
|
|
189
|
+
};
|
|
142
190
|
return {
|
|
143
191
|
handle: (payload, context) =>
|
|
144
192
|
this.withHandlerScope(context, async (scope) => {
|
|
@@ -148,6 +196,26 @@ export class ZLinkChannelDispatchServices {
|
|
|
148
196
|
};
|
|
149
197
|
}
|
|
150
198
|
|
|
199
|
+
private invokeScopeFreeHandler<TContext extends ZLinkMessageContext, TResult>(
|
|
200
|
+
activate: () => { handle(payload: unknown, context: TContext): TResult | Promise<TResult> },
|
|
201
|
+
payload: unknown,
|
|
202
|
+
context: TContext
|
|
203
|
+
): TResult | Promise<TResult> {
|
|
204
|
+
const handler = activate();
|
|
205
|
+
const cleanup = handlerInstanceCleanup(handler);
|
|
206
|
+
if (cleanup === undefined) return handler.handle(payload, context);
|
|
207
|
+
let result: TResult | Promise<TResult>;
|
|
208
|
+
try {
|
|
209
|
+
result = handler.handle(payload, context);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
const disposed = cleanup.call(handler);
|
|
212
|
+
return Promise.resolve(disposed).then(() => {
|
|
213
|
+
throw error;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return Promise.resolve(result).finally(() => cleanup.call(handler));
|
|
217
|
+
}
|
|
218
|
+
|
|
151
219
|
private async invokeHandlerFilters(
|
|
152
220
|
context: ZLinkHandlerFilterContext,
|
|
153
221
|
next: () => Promise<void>,
|