@zlink-systems/framework 0.29.1 → 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/Configuration/Builders.d.ts +1 -2
- package/dist/contracts/Configuration/Configs.d.ts +0 -5
- package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
- package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
- package/dist/contracts/Configuration/index.d.ts +1 -1
- 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/internal.d.ts +1 -0
- package/dist/internal.js +3 -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 +3 -2
- package/dist/runtime/actors/actor-handoff.js +15 -7
- 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 +9 -9
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
- package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
- package/dist/runtime/application-jobs/contracts.d.ts +15 -2
- package/dist/runtime/backend/contracts/index.d.ts +27 -27
- package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
- package/dist/runtime/backend/mesh-completion-table.js +160 -50
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
- package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
- 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-mesh-backend-adapter.d.ts +1 -9
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
- package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
- 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-receive-loops.js +3 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
- 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-socket-registry.d.ts +10 -3
- package/dist/runtime/channels/channel-socket-registry.js +59 -82
- 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/diagnostics/message-flow.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow.js +3 -3
- 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 +37 -6
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
- package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
- package/dist/runtime/foundation/service-liveness-registry.js +57 -44
- package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
- package/dist/runtime/foundation/service-mailbox.js +2 -1
- 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 +10 -9
- package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
- package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
- package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
- package/dist/runtime/foundation/service-topology-registry.js +69 -30
- 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-packet-relay.js +7 -7
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
- package/dist/runtime/host/application-job-queue.d.ts +28 -9
- package/dist/runtime/host/application-job-queue.js +214 -50
- package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
- package/dist/runtime/host/entry-actor-runtime.js +4 -1
- package/dist/runtime/host/index.d.ts +7 -1
- package/dist/runtime/host/index.js +154 -126
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
- package/dist/runtime/host/instance-activation-authority.js +89 -25
- 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 +215 -243
- package/dist/runtime/host/spot-address-transport.d.ts +1 -0
- package/dist/runtime/host/spot-address-transport.js +28 -14
- package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
- package/dist/runtime/host/user-spot-creation-coordinator.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/domain-store-contract.d.ts +2 -2
- package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
- package/dist/runtime/locations/in-memory-authority-store.js +80 -8
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +19 -3
- package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
- package/dist/runtime/locations/lifecycle.d.ts +1 -2
- package/dist/runtime/locations/lifecycle.js +2 -5
- package/dist/runtime/locations/location-store-repository.d.ts +3 -2
- package/dist/runtime/locations/location-store-repository.js +165 -22
- package/dist/runtime/locations/resolvers.d.ts +2 -1
- package/dist/runtime/locations/resolvers.js +10 -1
- 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 +2 -1
- package/dist/runtime/messaging/submission-result.js +7 -4
- 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 +9 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
- package/dist/runtime/spots/index.d.ts +7 -3
- package/dist/runtime/spots/index.js +23 -16
- package/dist/runtime/spots/spot-activation.d.ts +3 -1
- package/dist/runtime/spots/spot-activation.js +21 -12
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
- package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
- package/dist/runtime/spots/spot-entry-activation.js +9 -3
- 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-node-runtime-manager.d.ts +2 -1
- package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
- 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-routing-internal.d.ts +6 -0
- package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
- 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 +14 -28
- package/package.json +3 -3
- 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/Configuration/Builders.ts +1 -2
- package/src/contracts/Configuration/Configs.ts +0 -6
- package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
- package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
- package/src/contracts/Configuration/index.ts +1 -6
- 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/internal.ts +1 -0
- package/src/nest-integration.ts +1 -0
- package/src/runtime/actors/actor-client.ts +40 -16
- package/src/runtime/actors/actor-handoff.ts +22 -8
- 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 +53 -27
- package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
- package/src/runtime/application-jobs/contracts.ts +28 -2
- package/src/runtime/backend/contracts/index.ts +63 -32
- package/src/runtime/backend/mesh-completion-table.ts +175 -59
- package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
- package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
- package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
- package/src/runtime/backend/raw-binding-port.ts +18 -3
- 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-receive-loops.ts +3 -3
- package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
- package/src/runtime/channels/channel-runtime-manager.ts +29 -12
- package/src/runtime/channels/channel-socket-registry.ts +84 -130
- 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/diagnostics/message-flow.ts +1 -1
- 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 +642 -253
- package/src/runtime/foundation/service-liveness-registry.ts +68 -59
- package/src/runtime/foundation/service-mailbox.ts +7 -1
- 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 +128 -160
- package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
- package/src/runtime/foundation/service-topology-registry.ts +103 -42
- 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-packet-relay.ts +7 -0
- package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
- package/src/runtime/host/application-job-queue.ts +249 -48
- package/src/runtime/host/entry-actor-runtime.ts +5 -0
- package/src/runtime/host/index.ts +224 -160
- package/src/runtime/host/instance-activation-authority.ts +132 -27
- 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 +317 -291
- package/src/runtime/host/spot-address-transport.ts +49 -24
- package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
- package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
- package/src/runtime/locations/actor-location-claims.ts +52 -30
- package/src/runtime/locations/domain-store-contract.ts +6 -2
- package/src/runtime/locations/in-memory-authority-store.ts +113 -9
- package/src/runtime/locations/in-memory-location-store.ts +25 -3
- package/src/runtime/locations/internal-location-contracts.ts +4 -0
- package/src/runtime/locations/lifecycle.ts +8 -26
- package/src/runtime/locations/location-store-repository.ts +220 -15
- package/src/runtime/locations/resolvers.ts +25 -2
- 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 +7 -3
- 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 +45 -23
- package/src/runtime/spots/index.ts +30 -2
- package/src/runtime/spots/spot-activation.ts +33 -10
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
- package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
- package/src/runtime/spots/spot-entry-activation.ts +12 -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-node-runtime-manager.ts +7 -12
- 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-routing-internal.ts +14 -0
- package/src/runtime/spots/spot-runtime-ports.ts +3 -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 +13 -30
|
@@ -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>,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from '../../contracts/Dispatch/ZLinkDispatchOptions';
|
|
14
14
|
import type { Message } from '../../contracts/Common/Message';
|
|
15
15
|
import { SubmitResult } from '../backend/runtime-values';
|
|
16
|
-
import type
|
|
16
|
+
import { ReceiveKind, type ReceiveRecord } from '../foundation/service-runtime-contracts';
|
|
17
17
|
import { ZLinkConfigurationException, type ZLinkRouteChannelOptions } from '../configuration';
|
|
18
18
|
import type { ZLinkBackendSpotRouteBridge } from '../backend/contracts';
|
|
19
19
|
import type { ZLinkRuntimeMetrics } from '../diagnostics';
|
|
@@ -59,6 +59,8 @@ export interface ZLinkChannelRequestDispatcherOptions {
|
|
|
59
59
|
readonly unhandled?: ZLinkUnhandledDispatchOptions;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
const completedChannelReply = Promise.resolve();
|
|
63
|
+
|
|
62
64
|
export interface ZLinkChannelRequestHandler {
|
|
63
65
|
handle(payload: unknown, context: ZLinkMessageContext): Promise<unknown> | unknown;
|
|
64
66
|
}
|
|
@@ -134,7 +136,7 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
134
136
|
await this.pipeline.dispatchMalformed({
|
|
135
137
|
info,
|
|
136
138
|
error,
|
|
137
|
-
transportRequest: replyToken
|
|
139
|
+
transportRequest: replyToken != null,
|
|
138
140
|
writeProtocolError:
|
|
139
141
|
replyToken === null
|
|
140
142
|
? undefined
|
|
@@ -236,19 +238,19 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
236
238
|
});
|
|
237
239
|
}
|
|
238
240
|
|
|
239
|
-
|
|
241
|
+
dispatchMesh(record: ReceiveRecord, signal?: AbortSignal): Promise<void> {
|
|
240
242
|
if (record.parts.length === 0 || record.parts[0].data().length === 0) {
|
|
241
|
-
return;
|
|
243
|
+
return completedChannelReply;
|
|
242
244
|
}
|
|
243
245
|
let envelope: ReturnType<typeof decodeChannelEnvelope>;
|
|
244
246
|
try {
|
|
245
247
|
envelope = decodeChannelEnvelope(record.parts, undefined, this.flowEnabled());
|
|
246
248
|
} catch (error) {
|
|
247
249
|
const info = inspectMalformedChannelHeader(record.parts, this.flowEnabled());
|
|
248
|
-
|
|
250
|
+
return this.pipeline.dispatchMalformed({
|
|
249
251
|
info,
|
|
250
252
|
error,
|
|
251
|
-
transportRequest:
|
|
253
|
+
transportRequest: isMeshRequest(record),
|
|
252
254
|
sourceRid: record.sourceNodeRid == null ? undefined : String(record.sourceNodeRid),
|
|
253
255
|
writeProtocolError: async (protocolError) => {
|
|
254
256
|
requireMeshReplyAccepted(
|
|
@@ -261,7 +263,6 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
261
263
|
);
|
|
262
264
|
}
|
|
263
265
|
});
|
|
264
|
-
return;
|
|
265
266
|
}
|
|
266
267
|
const packetName = envelope.packetName;
|
|
267
268
|
if (packetName === undefined) {
|
|
@@ -269,7 +270,7 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
269
270
|
}
|
|
270
271
|
const correlationId = envelope.header.correlationId ?? undefined;
|
|
271
272
|
if (envelope.header.kind === ZLinkChannelMessageKind.Command) {
|
|
272
|
-
|
|
273
|
+
return this.pipeline.dispatchOneWay({
|
|
273
274
|
fields: {
|
|
274
275
|
messageKind: ZLinkDispatchMessageKind.Send,
|
|
275
276
|
packetName,
|
|
@@ -283,10 +284,9 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
283
284
|
context: this.createMeshContext(envelope, record.sourceNodeRid),
|
|
284
285
|
signal
|
|
285
286
|
});
|
|
286
|
-
return;
|
|
287
287
|
}
|
|
288
288
|
if (envelope.header.kind !== ZLinkChannelMessageKind.Request) {
|
|
289
|
-
return;
|
|
289
|
+
return completedChannelReply;
|
|
290
290
|
}
|
|
291
291
|
const fields: ZLinkChannelDispatchFields = {
|
|
292
292
|
messageKind: ZLinkDispatchMessageKind.Request,
|
|
@@ -295,7 +295,7 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
295
295
|
flowId: envelope.header.flowId,
|
|
296
296
|
flowOrigin: envelope.header.flowOrigin
|
|
297
297
|
};
|
|
298
|
-
|
|
298
|
+
return this.pipeline.dispatchRequest({
|
|
299
299
|
fields,
|
|
300
300
|
envelope,
|
|
301
301
|
codecs: this.options.codecs,
|
|
@@ -303,12 +303,12 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
303
303
|
context: this.createMeshContext(envelope, record.sourceNodeRid),
|
|
304
304
|
signal,
|
|
305
305
|
missingHandlerMessage: `No channel request handler is registered for '${this.options.channelName}:${packetName}'.`,
|
|
306
|
-
writeReply:
|
|
306
|
+
writeReply: (reply) => {
|
|
307
307
|
requireMeshReplyAccepted(
|
|
308
308
|
record.reply(encodeChannelReplyParts(envelope.header, reply, this.options.codecs))
|
|
309
309
|
);
|
|
310
310
|
},
|
|
311
|
-
writeError:
|
|
311
|
+
writeError: (error) => {
|
|
312
312
|
requireMeshReplyAccepted(
|
|
313
313
|
record.reply(encodeChannelErrorReplyParts(envelope.header, error))
|
|
314
314
|
);
|
|
@@ -324,7 +324,7 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
324
324
|
if (operation.submit() === false) {
|
|
325
325
|
throw new ZLinkConfigurationException('Channel reply was not accepted by Core.');
|
|
326
326
|
}
|
|
327
|
-
return
|
|
327
|
+
return completedChannelReply;
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
private createMeshContext(
|
|
@@ -587,7 +587,7 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
587
587
|
await this.pipeline.dispatchMalformed({
|
|
588
588
|
info,
|
|
589
589
|
error,
|
|
590
|
-
transportRequest: replyToken
|
|
590
|
+
transportRequest: replyToken != null,
|
|
591
591
|
sourceRid: String(received.routingId),
|
|
592
592
|
writeProtocolError:
|
|
593
593
|
replyToken === null
|
|
@@ -685,19 +685,19 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
685
685
|
});
|
|
686
686
|
}
|
|
687
687
|
|
|
688
|
-
|
|
688
|
+
dispatchMesh(record: ReceiveRecord, signal?: AbortSignal): Promise<void> {
|
|
689
689
|
if (record.parts.length === 0 || record.parts[0].data().length === 0) {
|
|
690
|
-
return;
|
|
690
|
+
return completedChannelReply;
|
|
691
691
|
}
|
|
692
692
|
let envelope: ReturnType<typeof decodeChannelEnvelope>;
|
|
693
693
|
try {
|
|
694
694
|
envelope = decodeChannelEnvelope(record.parts, undefined, this.flowEnabled());
|
|
695
695
|
} catch (error) {
|
|
696
696
|
const info = inspectMalformedChannelHeader(record.parts, this.flowEnabled());
|
|
697
|
-
|
|
697
|
+
return this.pipeline.dispatchMalformed({
|
|
698
698
|
info,
|
|
699
699
|
error,
|
|
700
|
-
transportRequest:
|
|
700
|
+
transportRequest: isMeshRequest(record),
|
|
701
701
|
sourceRid: record.sourceNodeRid == null ? undefined : String(record.sourceNodeRid),
|
|
702
702
|
writeProtocolError: async (protocolError) => {
|
|
703
703
|
requireMeshReplyAccepted(
|
|
@@ -710,7 +710,6 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
710
710
|
);
|
|
711
711
|
}
|
|
712
712
|
});
|
|
713
|
-
return;
|
|
714
713
|
}
|
|
715
714
|
const packetName = envelope.packetName;
|
|
716
715
|
if (packetName === undefined) {
|
|
@@ -719,17 +718,16 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
719
718
|
const sourceNodeRid = String(record.sourceNodeRid ?? '');
|
|
720
719
|
const correlationId = envelope.header.correlationId ?? undefined;
|
|
721
720
|
if (envelope.header.kind === ZLinkChannelMessageKind.Command) {
|
|
722
|
-
|
|
721
|
+
return this.dispatchMeshCommand(
|
|
723
722
|
envelope,
|
|
724
723
|
packetName,
|
|
725
724
|
sourceNodeRid,
|
|
726
725
|
record.sourceNodeRid,
|
|
727
726
|
signal
|
|
728
727
|
);
|
|
729
|
-
return;
|
|
730
728
|
}
|
|
731
729
|
if (envelope.header.kind !== ZLinkChannelMessageKind.Request) {
|
|
732
|
-
return;
|
|
730
|
+
return completedChannelReply;
|
|
733
731
|
}
|
|
734
732
|
const fields: ZLinkChannelDispatchFields = {
|
|
735
733
|
messageKind: ZLinkDispatchMessageKind.Request,
|
|
@@ -740,7 +738,7 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
740
738
|
flowOrigin: envelope.header.flowOrigin
|
|
741
739
|
};
|
|
742
740
|
const codecs = codecsForFrameworkPacket(packetName, this.codecs);
|
|
743
|
-
|
|
741
|
+
return this.pipeline.dispatchRequest({
|
|
744
742
|
fields,
|
|
745
743
|
envelope,
|
|
746
744
|
codecs,
|
|
@@ -748,12 +746,12 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
748
746
|
context: this.createRouteContext(envelope, record.sourceNodeRid),
|
|
749
747
|
signal,
|
|
750
748
|
missingHandlerMessage: `No routed request handler is registered for '${this.routerChannelId}:${packetName}'.`,
|
|
751
|
-
writeReply:
|
|
749
|
+
writeReply: (reply) => {
|
|
752
750
|
requireMeshReplyAccepted(
|
|
753
751
|
record.reply(encodeChannelReplyParts(envelope.header, reply, codecs))
|
|
754
752
|
);
|
|
755
753
|
},
|
|
756
|
-
writeError:
|
|
754
|
+
writeError: (error) => {
|
|
757
755
|
requireMeshReplyAccepted(
|
|
758
756
|
record.reply(encodeChannelErrorReplyParts(envelope.header, error))
|
|
759
757
|
);
|
|
@@ -826,7 +824,7 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
826
824
|
if (operation.submit() === false) {
|
|
827
825
|
throw new ZLinkConfigurationException('Route reply was not accepted by Core.');
|
|
828
826
|
}
|
|
829
|
-
return
|
|
827
|
+
return completedChannelReply;
|
|
830
828
|
}
|
|
831
829
|
|
|
832
830
|
private createRouteContext(
|
|
@@ -844,3 +842,7 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
844
842
|
};
|
|
845
843
|
}
|
|
846
844
|
}
|
|
845
|
+
|
|
846
|
+
function isMeshRequest(record: ReceiveRecord): boolean {
|
|
847
|
+
return record.kind === ReceiveKind.NodeRequest || record.kind === ReceiveKind.ChannelRequest;
|
|
848
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { Message } from '../../contracts/Common/Message';
|
|
|
3
3
|
import type { ZLinkFlowOrigin } from '../../contracts';
|
|
4
4
|
import {
|
|
5
5
|
decodeChannelHeader,
|
|
6
|
+
isValidChannelCorrelationId,
|
|
6
7
|
ZLINK_CHANNEL_FORMAT_MARKER,
|
|
7
8
|
ZLinkChannelMessageKind,
|
|
8
9
|
type ZLinkChannelEnvelopeHeader
|
|
@@ -29,7 +30,6 @@ export function tryDecodeChannelHeader(
|
|
|
29
30
|
* present only when it is individually well-formed.
|
|
30
31
|
*/
|
|
31
32
|
export interface ZLinkMalformedChannelHeaderInfo {
|
|
32
|
-
readonly kind?: ZLinkChannelMessageKind;
|
|
33
33
|
readonly channelName?: string;
|
|
34
34
|
readonly messageName?: string;
|
|
35
35
|
readonly correlationId?: string;
|
|
@@ -50,7 +50,6 @@ export function inspectMalformedChannelHeader(
|
|
|
50
50
|
} catch {
|
|
51
51
|
return {};
|
|
52
52
|
}
|
|
53
|
-
if (header.formatMarker !== ZLINK_CHANNEL_FORMAT_MARKER) return {};
|
|
54
53
|
const flowId =
|
|
55
54
|
typeof header.flowId === 'string' && CHANNEL_FLOW_ID_PATTERN.test(header.flowId)
|
|
56
55
|
? header.flowId
|
|
@@ -58,7 +57,6 @@ export function inspectMalformedChannelHeader(
|
|
|
58
57
|
const flowOrigin = salvageFlowOrigin(header.flowOrigin);
|
|
59
58
|
const flowPairValid = flowEnabled && flowId !== undefined && flowOrigin !== undefined;
|
|
60
59
|
return {
|
|
61
|
-
kind: salvageChannelKind(header.kind),
|
|
62
60
|
channelName: salvageString(header.channelName),
|
|
63
61
|
messageName: salvageString(header.messageName),
|
|
64
62
|
correlationId: salvageCorrelationId(header.correlationId),
|
|
@@ -94,24 +92,12 @@ export function malformedProtocolErrorRequestHeader(
|
|
|
94
92
|
const CHANNEL_FLOW_ID_PATTERN =
|
|
95
93
|
/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
96
94
|
|
|
97
|
-
function salvageChannelKind(value: unknown): ZLinkChannelMessageKind | undefined {
|
|
98
|
-
return value === ZLinkChannelMessageKind.Request ||
|
|
99
|
-
value === ZLinkChannelMessageKind.Response ||
|
|
100
|
-
value === ZLinkChannelMessageKind.Command ||
|
|
101
|
-
value === ZLinkChannelMessageKind.Publish ||
|
|
102
|
-
value === ZLinkChannelMessageKind.Error
|
|
103
|
-
? value
|
|
104
|
-
: undefined;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
95
|
function salvageString(value: unknown): string | undefined {
|
|
108
96
|
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
109
97
|
}
|
|
110
98
|
|
|
111
99
|
function salvageCorrelationId(value: unknown): string | undefined {
|
|
112
|
-
|
|
113
|
-
const byteLength = Buffer.byteLength(value, 'utf8');
|
|
114
|
-
return byteLength >= 1 && byteLength <= 64 && /^[\x00-\x7f]*$/.test(value) ? value : undefined;
|
|
100
|
+
return typeof value === 'string' && isValidChannelCorrelationId(value) ? value : undefined;
|
|
115
101
|
}
|
|
116
102
|
|
|
117
103
|
function salvageFlowOrigin(value: unknown): ZLinkFlowOrigin | undefined {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Message } from '../../contracts/Common/Message';
|
|
2
|
+
import { ZLinkBufferMessage } from '../backend/runtime-message';
|
|
2
3
|
import type { ZLinkBackendMessageLike as MessageLike } from '../backend/runtime-values';
|
|
3
4
|
import { randomUUID } from 'node:crypto';
|
|
4
5
|
import { isUtf8 } from 'node:buffer';
|
|
@@ -70,6 +71,24 @@ export interface ZLinkChannelEnvelopeCodecRegistry {
|
|
|
70
71
|
readonly serializers: ReadonlyMap<string, ZLinkMessageSerializer>;
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
interface PreparedChannelHeader {
|
|
75
|
+
readonly bytes: Buffer;
|
|
76
|
+
readonly correlationOffset: number;
|
|
77
|
+
readonly deadlineOffset: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
type PreparedHeaderVariants = Map<ZLinkChannelMessageKind, Map<boolean, PreparedChannelHeader>>;
|
|
81
|
+
const preparedChannelHeaders = new WeakMap<
|
|
82
|
+
ReadonlyMap<string, ZLinkMessageSerializer>,
|
|
83
|
+
Map<string, Map<string, Map<string, PreparedHeaderVariants>>>
|
|
84
|
+
>();
|
|
85
|
+
const CHANNEL_CORRELATION_FIELD = ',"correlationId":';
|
|
86
|
+
const CHANNEL_DEADLINE_FIELD = ',"deadline":';
|
|
87
|
+
const CHANNEL_CORRELATION_TEXT_LENGTH = 32;
|
|
88
|
+
const PREPARED_CHANNEL_CORRELATION = '0'.repeat(CHANNEL_CORRELATION_TEXT_LENGTH);
|
|
89
|
+
const PREPARED_CHANNEL_DEADLINE = '2000-01-01T00:00:00.000Z';
|
|
90
|
+
const CHANNEL_CORRELATION_TEXT = /^[0-9a-f]{32}$/;
|
|
91
|
+
|
|
73
92
|
export function newChannelCorrelationId(): string {
|
|
74
93
|
return randomUUID().replaceAll('-', '');
|
|
75
94
|
}
|
|
@@ -147,7 +166,8 @@ export function encodeChannelEnvelopePartsAtDeadline(
|
|
|
147
166
|
undefined,
|
|
148
167
|
applicationMetadataRecord(metadata),
|
|
149
168
|
flow?.flowId,
|
|
150
|
-
flow?.flowOrigin
|
|
169
|
+
flow?.flowOrigin,
|
|
170
|
+
codecs
|
|
151
171
|
),
|
|
152
172
|
encoded.message
|
|
153
173
|
];
|
|
@@ -215,7 +235,8 @@ export function encodeChannelReplyParts(
|
|
|
215
235
|
undefined,
|
|
216
236
|
EMPTY_APPLICATION_METADATA,
|
|
217
237
|
request.flowId,
|
|
218
|
-
request.flowOrigin
|
|
238
|
+
request.flowOrigin,
|
|
239
|
+
codecs
|
|
219
240
|
),
|
|
220
241
|
encoded.message
|
|
221
242
|
];
|
|
@@ -325,7 +346,7 @@ export function decodeChannelReply<TReply>(
|
|
|
325
346
|
return undefined as TReply;
|
|
326
347
|
}
|
|
327
348
|
if (header.contentType === BINARY_CONTENT_TYPE) {
|
|
328
|
-
return
|
|
349
|
+
return ZLinkBufferMessage.retainPayload(parts[1]) as TReply;
|
|
329
350
|
}
|
|
330
351
|
if (serializer !== undefined) {
|
|
331
352
|
return serializer.deserialize<TReply>(
|
|
@@ -517,8 +538,47 @@ function encodeChannelHeader(
|
|
|
517
538
|
source: string | null | undefined,
|
|
518
539
|
metadata: Readonly<Record<string, string>>,
|
|
519
540
|
flowId: string | undefined,
|
|
520
|
-
flowOrigin: ZLinkFlowOrigin | undefined
|
|
541
|
+
flowOrigin: ZLinkFlowOrigin | undefined,
|
|
542
|
+
codecs?: ZLinkChannelEnvelopeCodecRegistry
|
|
521
543
|
): Buffer {
|
|
544
|
+
if (
|
|
545
|
+
codecs !== undefined &&
|
|
546
|
+
metadata === EMPTY_APPLICATION_METADATA &&
|
|
547
|
+
flowId === undefined &&
|
|
548
|
+
flowOrigin === undefined &&
|
|
549
|
+
topic === null &&
|
|
550
|
+
source === undefined &&
|
|
551
|
+
((kind === ZLinkChannelMessageKind.Command &&
|
|
552
|
+
correlationId === null &&
|
|
553
|
+
deadline === null &&
|
|
554
|
+
errorCode === null &&
|
|
555
|
+
errorMessage === null) ||
|
|
556
|
+
(kind === ZLinkChannelMessageKind.Request &&
|
|
557
|
+
correlationId !== null &&
|
|
558
|
+
CHANNEL_CORRELATION_TEXT.test(correlationId) &&
|
|
559
|
+
deadline !== null &&
|
|
560
|
+
deadline.length === PREPARED_CHANNEL_DEADLINE.length &&
|
|
561
|
+
errorCode === null &&
|
|
562
|
+
errorMessage === null) ||
|
|
563
|
+
(kind === ZLinkChannelMessageKind.Response &&
|
|
564
|
+
correlationId !== null &&
|
|
565
|
+
CHANNEL_CORRELATION_TEXT.test(correlationId) &&
|
|
566
|
+
deadline === null &&
|
|
567
|
+
errorCode === undefined &&
|
|
568
|
+
errorMessage === undefined))
|
|
569
|
+
) {
|
|
570
|
+
return preparedChannelHeader(
|
|
571
|
+
codecs,
|
|
572
|
+
kind,
|
|
573
|
+
channelName,
|
|
574
|
+
messageName,
|
|
575
|
+
contentType,
|
|
576
|
+
correlationId,
|
|
577
|
+
deadline,
|
|
578
|
+
errorCode,
|
|
579
|
+
errorMessage
|
|
580
|
+
);
|
|
581
|
+
}
|
|
522
582
|
// The wire has a fixed field order. Measure escaped UTF-8 first, then write
|
|
523
583
|
// each field once into the only header Buffer: no header object, whole JSON
|
|
524
584
|
// string, or post-encode byte copy exists on the outbound path.
|
|
@@ -560,6 +620,63 @@ function encodeChannelHeader(
|
|
|
560
620
|
return result;
|
|
561
621
|
}
|
|
562
622
|
|
|
623
|
+
function preparedChannelHeader(
|
|
624
|
+
codecs: ZLinkChannelEnvelopeCodecRegistry,
|
|
625
|
+
kind: ZLinkChannelMessageKind,
|
|
626
|
+
channelName: string,
|
|
627
|
+
messageName: string,
|
|
628
|
+
contentType: string,
|
|
629
|
+
correlationId: string | null,
|
|
630
|
+
deadline: string | null,
|
|
631
|
+
errorCode: string | null | undefined,
|
|
632
|
+
errorMessage: string | null | undefined
|
|
633
|
+
): Buffer {
|
|
634
|
+
let channels = preparedChannelHeaders.get(codecs.serializers);
|
|
635
|
+
if (channels === undefined)
|
|
636
|
+
preparedChannelHeaders.set(codecs.serializers, (channels = new Map()));
|
|
637
|
+
let packets = channels.get(channelName);
|
|
638
|
+
if (packets === undefined) channels.set(channelName, (packets = new Map()));
|
|
639
|
+
let contentTypes = packets.get(messageName);
|
|
640
|
+
if (contentTypes === undefined) packets.set(messageName, (contentTypes = new Map()));
|
|
641
|
+
let kinds = contentTypes.get(contentType);
|
|
642
|
+
if (kinds === undefined) contentTypes.set(contentType, (kinds = new Map()));
|
|
643
|
+
let deadlines = kinds.get(kind);
|
|
644
|
+
if (deadlines === undefined) kinds.set(kind, (deadlines = new Map()));
|
|
645
|
+
const hasDeadline = deadline !== null;
|
|
646
|
+
let prepared = deadlines.get(hasDeadline);
|
|
647
|
+
if (prepared === undefined) {
|
|
648
|
+
const bytes = encodeChannelHeader(
|
|
649
|
+
kind,
|
|
650
|
+
channelName,
|
|
651
|
+
messageName,
|
|
652
|
+
contentType,
|
|
653
|
+
correlationId === null ? null : PREPARED_CHANNEL_CORRELATION,
|
|
654
|
+
hasDeadline ? PREPARED_CHANNEL_DEADLINE : null,
|
|
655
|
+
null,
|
|
656
|
+
errorCode,
|
|
657
|
+
errorMessage,
|
|
658
|
+
undefined,
|
|
659
|
+
EMPTY_APPLICATION_METADATA,
|
|
660
|
+
undefined,
|
|
661
|
+
undefined
|
|
662
|
+
);
|
|
663
|
+
prepared = {
|
|
664
|
+
bytes,
|
|
665
|
+
correlationOffset:
|
|
666
|
+
bytes.indexOf(CHANNEL_CORRELATION_FIELD) + CHANNEL_CORRELATION_FIELD.length + 1,
|
|
667
|
+
deadlineOffset: bytes.indexOf(CHANNEL_DEADLINE_FIELD) + CHANNEL_DEADLINE_FIELD.length + 1
|
|
668
|
+
};
|
|
669
|
+
deadlines.set(hasDeadline, prepared);
|
|
670
|
+
}
|
|
671
|
+
if (correlationId === null) return prepared.bytes;
|
|
672
|
+
const bytes = Buffer.alloc(prepared.bytes.byteLength);
|
|
673
|
+
prepared.bytes.copy(bytes);
|
|
674
|
+
bytes.write(correlationId, prepared.correlationOffset, CHANNEL_CORRELATION_TEXT_LENGTH, 'ascii');
|
|
675
|
+
if (deadline !== null)
|
|
676
|
+
bytes.write(deadline, prepared.deadlineOffset, PREPARED_CHANNEL_DEADLINE.length, 'ascii');
|
|
677
|
+
return bytes;
|
|
678
|
+
}
|
|
679
|
+
|
|
563
680
|
function writeChannelHeader(
|
|
564
681
|
writer: ChannelHeaderWriter,
|
|
565
682
|
kind: ZLinkChannelMessageKind,
|
|
@@ -586,9 +703,9 @@ function writeChannelHeader(
|
|
|
586
703
|
writer.string(messageName);
|
|
587
704
|
writer.append(',"contentType":');
|
|
588
705
|
writer.string(contentType);
|
|
589
|
-
writer.append(
|
|
706
|
+
writer.append(CHANNEL_CORRELATION_FIELD);
|
|
590
707
|
writer.nullableString(correlationId);
|
|
591
|
-
writer.append(
|
|
708
|
+
writer.append(CHANNEL_DEADLINE_FIELD);
|
|
592
709
|
writer.nullableString(deadline);
|
|
593
710
|
writer.append(',"topic":');
|
|
594
711
|
writer.nullableString(topic);
|
|
@@ -994,9 +1111,17 @@ function validateCorrelationForKind(
|
|
|
994
1111
|
}
|
|
995
1112
|
}
|
|
996
1113
|
|
|
1114
|
+
const MAXIMUM_CORRELATION_ID_BYTES = 64;
|
|
1115
|
+
|
|
1116
|
+
export function isValidChannelCorrelationId(value: string): boolean {
|
|
1117
|
+
const byteLength = Buffer.byteLength(value, 'utf8');
|
|
1118
|
+
return (
|
|
1119
|
+
byteLength >= 1 && byteLength <= MAXIMUM_CORRELATION_ID_BYTES && /^[\x00-\x7f]*$/.test(value)
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
997
1123
|
function validateCorrelationValue(correlationId: string): void {
|
|
998
|
-
|
|
999
|
-
if (byteLength < 1 || byteLength > 64 || !/^[\x00-\x7f]*$/.test(correlationId)) {
|
|
1124
|
+
if (!isValidChannelCorrelationId(correlationId)) {
|
|
1000
1125
|
throw new ZLinkConfigurationException(
|
|
1001
1126
|
'Channel envelope correlationId must be a non-empty ASCII value of at most 64 bytes.'
|
|
1002
1127
|
);
|
|
@@ -128,11 +128,20 @@ export class ZLinkChannelOutboundOperations {
|
|
|
128
128
|
request: unknown,
|
|
129
129
|
timeoutMs: number | undefined,
|
|
130
130
|
signal?: AbortSignal,
|
|
131
|
-
metadata?: ReadonlyMap<string, string
|
|
131
|
+
metadata?: ReadonlyMap<string, string>,
|
|
132
|
+
onAdmitted?: () => void
|
|
132
133
|
): Promise<TReply> {
|
|
133
134
|
return keepChannelRequestAlive(
|
|
134
135
|
runWithOutboundFlow(this.dispatchServices.flowCreationEnabled(), () =>
|
|
135
|
-
this.requestScoped<TReply>(
|
|
136
|
+
this.requestScoped<TReply>(
|
|
137
|
+
channelName,
|
|
138
|
+
packetName,
|
|
139
|
+
request,
|
|
140
|
+
timeoutMs,
|
|
141
|
+
signal,
|
|
142
|
+
metadata,
|
|
143
|
+
onAdmitted
|
|
144
|
+
)
|
|
136
145
|
)
|
|
137
146
|
);
|
|
138
147
|
}
|
|
@@ -143,7 +152,8 @@ export class ZLinkChannelOutboundOperations {
|
|
|
143
152
|
request: unknown,
|
|
144
153
|
timeoutMs: number | undefined,
|
|
145
154
|
signal?: AbortSignal,
|
|
146
|
-
metadata?: ReadonlyMap<string, string
|
|
155
|
+
metadata?: ReadonlyMap<string, string>,
|
|
156
|
+
onAdmitted?: () => void
|
|
147
157
|
): Promise<TReply> {
|
|
148
158
|
const deadlineMs = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
|
|
149
159
|
const deadlineUnixMs = timeoutMs === undefined ? undefined : Date.now() + timeoutMs;
|
|
@@ -213,7 +223,8 @@ export class ZLinkChannelOutboundOperations {
|
|
|
213
223
|
replyParts = await awaitWithAbort(
|
|
214
224
|
dealer.request(
|
|
215
225
|
parts,
|
|
216
|
-
remainingRequestTimeout(`Channel request '${channelName}'`, deadlineMs)
|
|
226
|
+
remainingRequestTimeout(`Channel request '${channelName}'`, deadlineMs),
|
|
227
|
+
onAdmitted
|
|
217
228
|
),
|
|
218
229
|
signal
|
|
219
230
|
);
|
|
@@ -397,7 +408,8 @@ export class ZLinkChannelOutboundOperations {
|
|
|
397
408
|
request: unknown,
|
|
398
409
|
timeoutMs: number | undefined,
|
|
399
410
|
signal?: AbortSignal,
|
|
400
|
-
metadata?: ReadonlyMap<string, string
|
|
411
|
+
metadata?: ReadonlyMap<string, string>,
|
|
412
|
+
onAdmitted?: () => void
|
|
401
413
|
): Promise<TReply> {
|
|
402
414
|
return runWithOutboundFlow(this.dispatchServices.flowCreationEnabled(), () =>
|
|
403
415
|
this.routeRequestScoped<TReply>(
|
|
@@ -407,7 +419,8 @@ export class ZLinkChannelOutboundOperations {
|
|
|
407
419
|
request,
|
|
408
420
|
timeoutMs,
|
|
409
421
|
signal,
|
|
410
|
-
metadata
|
|
422
|
+
metadata,
|
|
423
|
+
onAdmitted
|
|
411
424
|
)
|
|
412
425
|
);
|
|
413
426
|
}
|
|
@@ -419,7 +432,8 @@ export class ZLinkChannelOutboundOperations {
|
|
|
419
432
|
request: unknown,
|
|
420
433
|
timeoutMs: number | undefined,
|
|
421
434
|
signal?: AbortSignal,
|
|
422
|
-
metadata?: ReadonlyMap<string, string
|
|
435
|
+
metadata?: ReadonlyMap<string, string>,
|
|
436
|
+
onAdmitted?: () => void
|
|
423
437
|
): Promise<TReply> {
|
|
424
438
|
let correlationId: string | undefined;
|
|
425
439
|
let router: ReturnType<ZLinkChannelSocketRegistry['routeRouter']> | undefined;
|
|
@@ -471,7 +485,7 @@ export class ZLinkChannelOutboundOperations {
|
|
|
471
485
|
});
|
|
472
486
|
const reply = await this.measureRequest(routerChannelId, async () => {
|
|
473
487
|
const replyParts = await awaitWithAbort(
|
|
474
|
-
router!.request(targetNodeRid, parts, timeoutMs),
|
|
488
|
+
router!.request(targetNodeRid, parts, timeoutMs, onAdmitted),
|
|
475
489
|
signal
|
|
476
490
|
);
|
|
477
491
|
try {
|
|
@@ -359,7 +359,7 @@ export class ZLinkChannelReceiveLoop {
|
|
|
359
359
|
|
|
360
360
|
private async acquirePermit(signal: AbortSignal): Promise<ApplicationJobQueuePermit | undefined> {
|
|
361
361
|
try {
|
|
362
|
-
return await this.applicationJobQueue.acquire(signal);
|
|
362
|
+
return await this.applicationJobQueue.acquire(signal, 'remote');
|
|
363
363
|
} catch (error) {
|
|
364
364
|
if (this.isStopped() || signal.aborted) return undefined;
|
|
365
365
|
throw error;
|
|
@@ -585,7 +585,7 @@ export class ZLinkSubscriberReceiveLoop {
|
|
|
585
585
|
|
|
586
586
|
private async acquirePermit(signal: AbortSignal): Promise<ApplicationJobQueuePermit | undefined> {
|
|
587
587
|
try {
|
|
588
|
-
return await this.applicationJobQueue.acquire(signal);
|
|
588
|
+
return await this.applicationJobQueue.acquire(signal, 'remote');
|
|
589
589
|
} catch (error) {
|
|
590
590
|
if (this.isStopped() || signal.aborted) return undefined;
|
|
591
591
|
throw error;
|
|
@@ -795,7 +795,7 @@ export class ZLinkRouteReceiveLoop {
|
|
|
795
795
|
|
|
796
796
|
private async acquirePermit(signal: AbortSignal): Promise<ApplicationJobQueuePermit | undefined> {
|
|
797
797
|
try {
|
|
798
|
-
return await this.applicationJobQueue.acquire(signal);
|
|
798
|
+
return await this.applicationJobQueue.acquire(signal, 'remote');
|
|
799
799
|
} catch (error) {
|
|
800
800
|
if (this.isStopped() || signal.aborted) return undefined;
|
|
801
801
|
throw error;
|