@zlink-systems/framework 0.22.0 → 0.24.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/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
- package/dist/runtime/actors/actor-context.js +4 -4
- package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
- package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
- package/dist/runtime/actors/deferred-join-accepted-journal.js +2 -6
- package/dist/runtime/backend/contracts/index.d.ts +2 -0
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +4 -0
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +24 -8
- package/dist/runtime/channels/channel-dispatch-pipeline.js +2 -2
- package/dist/runtime/channels/channel-transports.js +3 -9
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -0
- package/dist/runtime/channels/dispatch-error-reporter.js +6 -38
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +6 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
- package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
- package/dist/runtime/diagnostics/flow-context.js +2 -2
- package/dist/runtime/diagnostics/message-flow.js +11 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.js +0 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +4 -2
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +34 -9
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +1 -0
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +5 -0
- package/dist/runtime/foundation/service-stateful-runtime.js +52 -2
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
- package/dist/runtime/foundation/service-topology-registry.js +12 -4
- package/dist/runtime/host/index.js +7 -3
- package/dist/runtime/locations/in-memory-location-store.js +5 -0
- package/dist/runtime/locations/location-store-repository.js +3 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +20 -18
- package/dist/runtime/spots/index.js +9 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +6 -1
- package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
- package/dist/runtime/spots/spot-node-runtime-manager.js +5 -1
- package/dist/runtime/spots/spot-route-packet-dispatch.js +1 -1
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -1
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.js +1 -1
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
- package/dist/runtime/streams/actor-session-binding-registry.js +71 -42
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
- package/dist/runtime/streams/bound-actor-relay-sender.js +2 -1
- package/dist/runtime/streams/bound-session-response-target.js +8 -1
- package/dist/runtime/streams/bound-session-service.d.ts +1 -0
- package/dist/runtime/streams/bound-session-service.js +6 -3
- package/dist/runtime/streams/index.js +8 -1
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +20 -1
- package/dist/runtime/streams/protocol.d.ts +5 -1
- package/dist/runtime/streams/protocol.js +41 -4
- package/dist/runtime/streams/session-actor-coordinator.js +3 -4
- package/dist/runtime/streams/session-context.d.ts +9 -2
- package/dist/runtime/streams/session-context.js +20 -4
- package/dist/runtime/streams/session-local-actors.d.ts +3 -1
- package/dist/runtime/streams/session-local-actors.js +17 -2
- package/dist/runtime/streams/stream-frame-factory.d.ts +1 -1
- package/dist/runtime/streams/stream-frame-factory.js +3 -2
- package/dist/runtime/streams/stream-session-runtime.js +42 -12
- package/package.json +3 -3
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Streams/IZLinkSession.ts +2 -1
- package/src/runtime/actors/actor-context.ts +4 -4
- package/src/runtime/actors/actor-join-deferred-scope.ts +0 -32
- package/src/runtime/actors/deferred-join-accepted-journal.ts +2 -6
- package/src/runtime/backend/contracts/index.ts +5 -0
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +43 -11
- package/src/runtime/channels/channel-dispatch-pipeline.ts +4 -2
- package/src/runtime/channels/channel-transports.ts +3 -9
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -45
- package/src/runtime/diagnostics/dispatch-error-details.ts +62 -0
- package/src/runtime/diagnostics/flow-context.ts +6 -4
- package/src/runtime/diagnostics/message-flow.ts +12 -3
- package/src/runtime/foundation/actor-join-recovery-codec.ts +0 -4
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +54 -13
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -0
- package/src/runtime/foundation/service-stateful-runtime.ts +71 -5
- package/src/runtime/foundation/service-topology-registry.ts +18 -5
- package/src/runtime/host/index.ts +11 -4
- package/src/runtime/locations/in-memory-location-store.ts +7 -0
- package/src/runtime/locations/location-store-repository.ts +4 -1
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +18 -17
- package/src/runtime/spots/index.ts +22 -2
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +20 -3
- package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
- package/src/runtime/spots/spot-node-runtime-manager.ts +5 -1
- package/src/runtime/spots/spot-route-packet-dispatch.ts +2 -1
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +2 -1
- package/src/runtime/spots/spot-subscription-dispatch.ts +2 -1
- package/src/runtime/spots/spot-timer.ts +6 -1
- package/src/runtime/streams/actor-session-binding-registry.ts +150 -63
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +1 -0
- package/src/runtime/streams/bound-actor-relay-sender.ts +10 -2
- package/src/runtime/streams/bound-session-response-target.ts +10 -1
- package/src/runtime/streams/bound-session-service.ts +13 -3
- package/src/runtime/streams/index.ts +8 -1
- package/src/runtime/streams/managed-stream.ts +34 -12
- package/src/runtime/streams/protocol.ts +44 -5
- package/src/runtime/streams/session-actor-coordinator.ts +12 -4
- package/src/runtime/streams/session-context.ts +31 -4
- package/src/runtime/streams/session-local-actors.ts +19 -3
- package/src/runtime/streams/stream-frame-factory.ts +4 -2
- package/src/runtime/streams/stream-session-runtime.ts +58 -13
|
@@ -70,7 +70,8 @@ export enum ZLinkStreamHeaderFlags {
|
|
|
70
70
|
HasMetadata = 0x02,
|
|
71
71
|
PayloadCompressed = 0x04,
|
|
72
72
|
HasCorrelationId = 0x08,
|
|
73
|
-
HasFlowId = 0x10
|
|
73
|
+
HasFlowId = 0x10,
|
|
74
|
+
HasActorSlot = 0x20
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
export enum ZLinkStreamCloseReasonCode {
|
|
@@ -95,6 +96,7 @@ export interface ZLinkStreamFrameHeader {
|
|
|
95
96
|
readonly correlationId?: string;
|
|
96
97
|
readonly flowId?: string;
|
|
97
98
|
readonly flowOrigin?: ZLinkFlowOrigin;
|
|
99
|
+
readonly actorSlot?: number;
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
export type ZLinkStreamReplyMessageKind =
|
|
@@ -139,6 +141,28 @@ export function encodeStreamControlFrame(name: string): Uint8Array {
|
|
|
139
141
|
);
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
export function encodeActorBoundFrame(actorSlot: number, actorId: string): Uint8Array {
|
|
145
|
+
const actorIdBytes = utf8Encode(actorId);
|
|
146
|
+
if (actorIdBytes.length < 1 || actorIdBytes.length > 0xff) {
|
|
147
|
+
throw new Error('Actor id length is invalid for a STREAM binding control packet.');
|
|
148
|
+
}
|
|
149
|
+
const payload = new Uint8Array(4 + actorIdBytes.length);
|
|
150
|
+
payload[0] = 1;
|
|
151
|
+
payload[1] = actorSlot >>> 8;
|
|
152
|
+
payload[2] = actorSlot & 0xff;
|
|
153
|
+
payload[3] = actorIdBytes.length;
|
|
154
|
+
payload.set(actorIdBytes, 4);
|
|
155
|
+
return encodeStreamFrame(controlHeader('$zlink.actor.bound'), payload);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function encodeActorUnboundFrame(actorSlot: number): Uint8Array {
|
|
159
|
+
const payload = new Uint8Array(3);
|
|
160
|
+
payload[0] = 1;
|
|
161
|
+
payload[1] = actorSlot >>> 8;
|
|
162
|
+
payload[2] = actorSlot & 0xff;
|
|
163
|
+
return encodeStreamFrame(controlHeader('$zlink.actor.unbound'), payload);
|
|
164
|
+
}
|
|
165
|
+
|
|
142
166
|
export function encodeSessionClosingFrame(
|
|
143
167
|
diagnostic = '',
|
|
144
168
|
reason = ZLinkStreamCloseReasonCode.ServerDrain
|
|
@@ -176,9 +200,10 @@ export function encodeStreamHeader(header: ZLinkStreamFrameHeader): Uint8Array {
|
|
|
176
200
|
const hasMetadata = header.metadata.size > 0;
|
|
177
201
|
const hasCorrelation = header.correlationId !== undefined && header.correlationId.length > 0;
|
|
178
202
|
const hasFlow = header.flowId !== undefined || header.flowOrigin !== undefined;
|
|
203
|
+
const hasActorSlot = header.actorSlot !== undefined;
|
|
179
204
|
if (
|
|
180
205
|
header.kind === ZLinkStreamMessageKind.Control &&
|
|
181
|
-
(hasCorrelation || hasRequestSeq || hasMetadata || hasFlow)
|
|
206
|
+
(hasCorrelation || hasRequestSeq || hasMetadata || hasFlow || hasActorSlot)
|
|
182
207
|
) {
|
|
183
208
|
throw new Error(
|
|
184
209
|
'Control packet must not contain a request sequence, metadata, correlation id, or flow id.'
|
|
@@ -195,7 +220,8 @@ export function encodeStreamHeader(header: ZLinkStreamFrameHeader): Uint8Array {
|
|
|
195
220
|
metadata: header.metadata,
|
|
196
221
|
correlationId: header.correlationId,
|
|
197
222
|
flowId: header.flowId,
|
|
198
|
-
flowOrigin: encodeFlowOrigin(header.flowOrigin)
|
|
223
|
+
flowOrigin: encodeFlowOrigin(header.flowOrigin),
|
|
224
|
+
actorSlot: header.actorSlot
|
|
199
225
|
});
|
|
200
226
|
}
|
|
201
227
|
|
|
@@ -207,9 +233,10 @@ export function decodeStreamHeader(header: Uint8Array, flowEnabled = true): ZLin
|
|
|
207
233
|
const hasMetadata = (flags & ZLinkStreamHeaderFlags.HasMetadata) !== 0;
|
|
208
234
|
const hasCorrelation = (flags & ZLinkStreamHeaderFlags.HasCorrelationId) !== 0;
|
|
209
235
|
const hasFlow = (flags & ZLinkStreamHeaderFlags.HasFlowId) !== 0;
|
|
236
|
+
const hasActorSlot = (flags & ZLinkStreamHeaderFlags.HasActorSlot) !== 0;
|
|
210
237
|
if (
|
|
211
238
|
kind === ZLinkStreamMessageKind.Control &&
|
|
212
|
-
(hasCorrelation || hasRequestSeq || hasMetadata || hasFlow)
|
|
239
|
+
(hasCorrelation || hasRequestSeq || hasMetadata || hasFlow || hasActorSlot)
|
|
213
240
|
) {
|
|
214
241
|
throw new Error(
|
|
215
242
|
'Control packet must not contain a request sequence, metadata, correlation id, or flow id.'
|
|
@@ -227,7 +254,8 @@ export function decodeStreamHeader(header: Uint8Array, flowEnabled = true): ZLin
|
|
|
227
254
|
metadata,
|
|
228
255
|
correlationId: decoded.correlationId,
|
|
229
256
|
flowId: decoded.flowId,
|
|
230
|
-
flowOrigin: decodeFlowOrigin(decoded.flowOrigin)
|
|
257
|
+
flowOrigin: decodeFlowOrigin(decoded.flowOrigin),
|
|
258
|
+
actorSlot: decoded.actorSlot
|
|
231
259
|
};
|
|
232
260
|
}
|
|
233
261
|
|
|
@@ -275,10 +303,21 @@ export function createStreamReplyHeader(
|
|
|
275
303
|
// observation-only and is not copied into the reply when tracing is Off
|
|
276
304
|
// (spec 27 §4, §7).
|
|
277
305
|
correlationId: requestHeader.correlationId,
|
|
306
|
+
actorSlot: requestHeader.actorSlot,
|
|
278
307
|
...(includeFlow ? { flowId: requestHeader.flowId, flowOrigin: requestHeader.flowOrigin } : {})
|
|
279
308
|
};
|
|
280
309
|
}
|
|
281
310
|
|
|
311
|
+
function controlHeader(name: string): ZLinkStreamFrameHeader {
|
|
312
|
+
return {
|
|
313
|
+
kind: ZLinkStreamMessageKind.Control,
|
|
314
|
+
codec: ZLinkStreamCodec.Raw,
|
|
315
|
+
flags: ZLinkStreamHeaderFlags.None,
|
|
316
|
+
name,
|
|
317
|
+
metadata: EMPTY_STREAM_METADATA
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
282
321
|
function encodeFlowOrigin(origin: ZLinkFlowOrigin | undefined): number | undefined {
|
|
283
322
|
return origin === undefined
|
|
284
323
|
? undefined
|
|
@@ -133,7 +133,6 @@ export class ZLinkSessionActorCoordinator {
|
|
|
133
133
|
reuseActor ??
|
|
134
134
|
new DefaultZLinkSessionActor(this.sessionActorRuntime, boundActorRef, bindingToken);
|
|
135
135
|
const sessionIdentity = String(this.actorBindingRoutingId(context));
|
|
136
|
-
sessionActor.updateRef(boundActorRef);
|
|
137
136
|
if (previous === undefined) {
|
|
138
137
|
if (releaseSeal !== undefined) {
|
|
139
138
|
throw createInternalFrameworkException(
|
|
@@ -142,7 +141,14 @@ export class ZLinkSessionActorCoordinator {
|
|
|
142
141
|
true
|
|
143
142
|
);
|
|
144
143
|
}
|
|
145
|
-
await this.routes.bind(
|
|
144
|
+
await this.routes.bind(
|
|
145
|
+
context,
|
|
146
|
+
sessionActor,
|
|
147
|
+
bindingToken,
|
|
148
|
+
authorityFence,
|
|
149
|
+
sessionIdentity,
|
|
150
|
+
() => sessionActor.updateRef(boundActorRef)
|
|
151
|
+
);
|
|
146
152
|
} else if (releaseSeal !== undefined) {
|
|
147
153
|
await this.routes.replaceAndReleaseSeal(
|
|
148
154
|
previous,
|
|
@@ -151,7 +157,8 @@ export class ZLinkSessionActorCoordinator {
|
|
|
151
157
|
bindingToken,
|
|
152
158
|
releaseSeal.sealId,
|
|
153
159
|
authorityFence,
|
|
154
|
-
sessionIdentity
|
|
160
|
+
sessionIdentity,
|
|
161
|
+
() => sessionActor.updateRef(boundActorRef)
|
|
155
162
|
);
|
|
156
163
|
} else {
|
|
157
164
|
await this.routes.replace(
|
|
@@ -160,7 +167,8 @@ export class ZLinkSessionActorCoordinator {
|
|
|
160
167
|
sessionActor,
|
|
161
168
|
bindingToken,
|
|
162
169
|
authorityFence,
|
|
163
|
-
sessionIdentity
|
|
170
|
+
sessionIdentity,
|
|
171
|
+
() => sessionActor.updateRef(boundActorRef)
|
|
164
172
|
);
|
|
165
173
|
}
|
|
166
174
|
if (
|
|
@@ -45,6 +45,8 @@ import { releaseApplicationJobPermitBeforeHandler } from '../application-jobs/ap
|
|
|
45
45
|
export interface ZLinkSessionContextStream extends ZLinkStream {
|
|
46
46
|
writeRaw(payload: Message, flags?: number): boolean;
|
|
47
47
|
submitRaw(payload: Message, signal?: AbortSignal, timeoutMs?: number): Promise<ZLinkSubmitResult>;
|
|
48
|
+
enqueueActorBound?(actorSlot: number, actorId: string): Promise<void>;
|
|
49
|
+
enqueueActorUnbound?(actorSlot: number): Promise<void>;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
interface ZLinkSessionContextRuntime {
|
|
@@ -344,8 +346,31 @@ export class DefaultZLinkSessionContext implements ZLinkSessionContext {
|
|
|
344
346
|
return this.localActors.find(actorId);
|
|
345
347
|
}
|
|
346
348
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
+
actorForSlot(actorSlot: number | undefined): DefaultZLinkSessionActor | undefined {
|
|
350
|
+
if (actorSlot === undefined) return undefined;
|
|
351
|
+
return this.localActors.findBySlot(actorSlot);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
get actorSlotControls():
|
|
355
|
+
| {
|
|
356
|
+
enqueueBound(actorSlot: number, actorId: string): Promise<void>;
|
|
357
|
+
enqueueUnbound(actorSlot: number): Promise<void>;
|
|
358
|
+
}
|
|
359
|
+
| undefined {
|
|
360
|
+
if (
|
|
361
|
+
this.stream.enqueueActorBound === undefined ||
|
|
362
|
+
this.stream.enqueueActorUnbound === undefined
|
|
363
|
+
) {
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
enqueueBound: (actorSlot, actorId) => this.stream.enqueueActorBound!(actorSlot, actorId),
|
|
368
|
+
enqueueUnbound: (actorSlot) => this.stream.enqueueActorUnbound!(actorSlot)
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
bindLocal(actor: DefaultZLinkSessionActor, token: string, actorSlot?: number): void {
|
|
373
|
+
this.localActors.bind(actor, token, actorSlot);
|
|
349
374
|
}
|
|
350
375
|
|
|
351
376
|
unbindLocal(actorId: string, token: string): void {
|
|
@@ -547,12 +572,14 @@ export class DefaultZLinkSessionActor implements ZLinkSessionActor {
|
|
|
547
572
|
const SESSION_DISPATCH_HEADERS = new WeakMap<ZLinkSessionDispatchContext, ZLinkStreamFrameHeader>();
|
|
548
573
|
|
|
549
574
|
export function createSessionDispatchContext(
|
|
550
|
-
header: ZLinkStreamFrameHeader
|
|
575
|
+
header: ZLinkStreamFrameHeader,
|
|
576
|
+
actor?: DefaultZLinkSessionActor
|
|
551
577
|
): ZLinkSessionDispatchContext {
|
|
552
578
|
const dispatch: ZLinkSessionDispatchContext = {
|
|
553
579
|
packetName: header.name,
|
|
554
580
|
metadata: header.metadata,
|
|
555
|
-
canReply: header.requestSeq !== undefined
|
|
581
|
+
canReply: header.requestSeq !== undefined,
|
|
582
|
+
...(actor === undefined ? {} : { actor })
|
|
556
583
|
};
|
|
557
584
|
SESSION_DISPATCH_HEADERS.set(dispatch, header);
|
|
558
585
|
return dispatch;
|
|
@@ -3,7 +3,8 @@ export interface ZLinkSessionLocalActor {
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
export class ZLinkSessionLocalActorBindings<TActor extends ZLinkSessionLocalActor> {
|
|
6
|
-
private readonly actors = new Map<string, { actor: TActor; token: string }>();
|
|
6
|
+
private readonly actors = new Map<string, { actor: TActor; token: string; actorSlot?: number }>();
|
|
7
|
+
private readonly actorIdsBySlot = new Map<number, string>();
|
|
7
8
|
|
|
8
9
|
snapshot(): readonly TActor[] {
|
|
9
10
|
const snapshot: TActor[] = [];
|
|
@@ -17,14 +18,29 @@ export class ZLinkSessionLocalActorBindings<TActor extends ZLinkSessionLocalActo
|
|
|
17
18
|
return this.actors.get(actorId)?.actor;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
this.
|
|
21
|
+
findBySlot(actorSlot: number): TActor | undefined {
|
|
22
|
+
const actorId = this.actorIdsBySlot.get(actorSlot);
|
|
23
|
+
return actorId === undefined ? undefined : this.actors.get(actorId)?.actor;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
bind(actor: TActor, token: string, actorSlot?: number): void {
|
|
27
|
+
const previous = this.actors.get(actor.actorId);
|
|
28
|
+
if (previous?.actorSlot !== undefined && previous.actorSlot !== actorSlot) {
|
|
29
|
+
this.actorIdsBySlot.delete(previous.actorSlot);
|
|
30
|
+
}
|
|
31
|
+
this.actors.set(actor.actorId, { actor, token, actorSlot });
|
|
32
|
+
if (actorSlot !== undefined) {
|
|
33
|
+
this.actorIdsBySlot.set(actorSlot, actor.actorId);
|
|
34
|
+
}
|
|
22
35
|
}
|
|
23
36
|
|
|
24
37
|
unbind(actorId: string, token: string): void {
|
|
25
38
|
const current = this.actors.get(actorId);
|
|
26
39
|
if (current?.token === token) {
|
|
27
40
|
this.actors.delete(actorId);
|
|
41
|
+
if (current.actorSlot !== undefined) {
|
|
42
|
+
this.actorIdsBySlot.delete(current.actorSlot);
|
|
43
|
+
}
|
|
28
44
|
}
|
|
29
45
|
}
|
|
30
46
|
}
|
|
@@ -74,7 +74,8 @@ export class ZLinkStreamFrameMessageFactory {
|
|
|
74
74
|
compressed: boolean,
|
|
75
75
|
requestSeq: bigint | undefined,
|
|
76
76
|
payload: unknown,
|
|
77
|
-
correlationId?: string
|
|
77
|
+
correlationId?: string,
|
|
78
|
+
actorSlot?: number
|
|
78
79
|
): Message {
|
|
79
80
|
const flow =
|
|
80
81
|
(this.options.flowCreationEnabled?.() ?? true)
|
|
@@ -97,7 +98,8 @@ export class ZLinkStreamFrameMessageFactory {
|
|
|
97
98
|
metadata,
|
|
98
99
|
correlationId,
|
|
99
100
|
flowId: flow?.flowId,
|
|
100
|
-
flowOrigin: flow?.flowOrigin
|
|
101
|
+
flowOrigin: flow?.flowOrigin,
|
|
102
|
+
actorSlot
|
|
101
103
|
})
|
|
102
104
|
);
|
|
103
105
|
}
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
} from '../framework-errors-internal';
|
|
5
5
|
import type { ZLinkMessageSerializer, RoutingId, ZLinkSession } from '../../contracts';
|
|
6
6
|
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
7
|
-
import { ZLinkFrameworkErrorKind, ZLinkFrameworkException } from '../../contracts';
|
|
8
7
|
import { ZLinkSocketNativeEventType } from '../diagnostics/internal-event-contracts';
|
|
9
8
|
import {
|
|
10
9
|
ZLinkRuntimeMessageFlowOutcome as ZLinkMessageFlowOutcome,
|
|
@@ -16,6 +15,7 @@ import {
|
|
|
16
15
|
import type { Message } from '../../contracts/Common/Message';
|
|
17
16
|
import { throwIfAborted } from '../abort';
|
|
18
17
|
import { ZLinkDispatchErrorReporter, ZLinkRouteDisconnectedError } from '../channels';
|
|
18
|
+
import { boundSessionErrorPayload } from './bound-session-response-target';
|
|
19
19
|
import { flowIfEnabled } from '../diagnostics';
|
|
20
20
|
import type { ZLinkRuntimeMetrics } from '../diagnostics';
|
|
21
21
|
import { wrapFrameworkPayloadMessage } from '../messaging/payload-codec';
|
|
@@ -477,6 +477,55 @@ export class ZLinkStreamSessionRuntime {
|
|
|
477
477
|
if (this.context.tryCompleteResponse(decodedHeader, dispatchPayload)) {
|
|
478
478
|
return;
|
|
479
479
|
}
|
|
480
|
+
const dispatchActor = this.context.actorForSlot(decodedHeader.actorSlot);
|
|
481
|
+
if (decodedHeader.actorSlot !== undefined && dispatchActor === undefined) {
|
|
482
|
+
const staleFlowEnabled = this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true;
|
|
483
|
+
await runWithFlow(
|
|
484
|
+
createInboundFlow(
|
|
485
|
+
decodedHeader.flowId,
|
|
486
|
+
decodedHeader.flowOrigin,
|
|
487
|
+
staleFlowEnabled,
|
|
488
|
+
staleFlowEnabled ? this.stream.sessionId : undefined
|
|
489
|
+
),
|
|
490
|
+
async () => {
|
|
491
|
+
if (decodedHeader.kind === ZLinkStreamMessageKind.Request) {
|
|
492
|
+
const error = createInternalFrameworkException(
|
|
493
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
494
|
+
'Actor slot is not a current binding.'
|
|
495
|
+
);
|
|
496
|
+
this.options.dispatchErrors?.report({
|
|
497
|
+
surface: ZLinkDispatchErrorSurface.StreamSession,
|
|
498
|
+
messageKind: ZLinkDispatchMessageKind.Request,
|
|
499
|
+
reason: ZLinkDispatchErrorReason.StaleTarget,
|
|
500
|
+
action: ZLinkDispatchErrorAction.ReplyError,
|
|
501
|
+
packetName: decodedHeader.name,
|
|
502
|
+
sourceRid:
|
|
503
|
+
this.context.routingId === undefined ? undefined : String(this.context.routingId),
|
|
504
|
+
correlationId: decodedHeader.correlationId,
|
|
505
|
+
flowId: decodedHeader.flowId,
|
|
506
|
+
flowOrigin: decodedHeader.flowOrigin,
|
|
507
|
+
error
|
|
508
|
+
});
|
|
509
|
+
await this.replyDispatchError(decodedHeader, error);
|
|
510
|
+
} else {
|
|
511
|
+
flowIfEnabled(
|
|
512
|
+
this.options.dispatchErrors?.flow,
|
|
513
|
+
ZLinkMessageFlowOutcome.Dropped
|
|
514
|
+
)?.trace({
|
|
515
|
+
outcome: ZLinkMessageFlowOutcome.Dropped,
|
|
516
|
+
surface: ZLinkDispatchErrorSurface.StreamSession,
|
|
517
|
+
messageKind: ZLinkDispatchMessageKind.Send,
|
|
518
|
+
packetName: decodedHeader.name,
|
|
519
|
+
correlationId: decodedHeader.correlationId,
|
|
520
|
+
sourceRid:
|
|
521
|
+
this.context.routingId === undefined ? undefined : String(this.context.routingId),
|
|
522
|
+
errorReason: ZLinkDispatchErrorReason.StaleTarget
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
480
529
|
this.context.enterDispatch(decodedHeader);
|
|
481
530
|
enteredDispatch = true;
|
|
482
531
|
const session = await this.requireSession();
|
|
@@ -486,11 +535,13 @@ export class ZLinkStreamSessionRuntime {
|
|
|
486
535
|
: ZLinkDispatchMessageKind.Send;
|
|
487
536
|
const streamCorr = decodedHeader.correlationId;
|
|
488
537
|
const inboundHeader = decodedHeader;
|
|
538
|
+
const flowEnabled = this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true;
|
|
489
539
|
await runWithFlow(
|
|
490
540
|
createInboundFlow(
|
|
491
541
|
inboundHeader.flowId,
|
|
492
542
|
inboundHeader.flowOrigin,
|
|
493
|
-
|
|
543
|
+
flowEnabled,
|
|
544
|
+
flowEnabled ? this.stream.sessionId : undefined
|
|
494
545
|
),
|
|
495
546
|
async () => {
|
|
496
547
|
flowIfEnabled(this.options.dispatchErrors?.flow, ZLinkMessageFlowOutcome.Received)?.trace(
|
|
@@ -529,7 +580,7 @@ export class ZLinkStreamSessionRuntime {
|
|
|
529
580
|
this.context.routingId === undefined ? undefined : String(this.context.routingId)
|
|
530
581
|
});
|
|
531
582
|
await session.onDispatch?.(
|
|
532
|
-
createSessionDispatchContext(inboundHeader),
|
|
583
|
+
createSessionDispatchContext(inboundHeader, dispatchActor),
|
|
533
584
|
wrapFrameworkPayloadMessage(
|
|
534
585
|
dispatchPayload,
|
|
535
586
|
this.options.messageSerializers,
|
|
@@ -694,15 +745,7 @@ export class ZLinkStreamSessionRuntime {
|
|
|
694
745
|
ZLinkStreamMessageKind.Error,
|
|
695
746
|
new Map(),
|
|
696
747
|
false,
|
|
697
|
-
|
|
698
|
-
code:
|
|
699
|
-
error instanceof ZLinkFrameworkException
|
|
700
|
-
? ZLinkFrameworkErrorKind[error.kind]
|
|
701
|
-
: error instanceof Error
|
|
702
|
-
? error.constructor.name
|
|
703
|
-
: 'RemoteError',
|
|
704
|
-
message: error instanceof Error ? error.message : String(error)
|
|
705
|
-
}
|
|
748
|
+
boundSessionErrorPayload(error)
|
|
706
749
|
);
|
|
707
750
|
try {
|
|
708
751
|
if (!this.context.stream.writeRaw(message, ZLINK_SEND_DONT_WAIT)) {
|
|
@@ -740,7 +783,8 @@ export class ZLinkStreamSessionRuntime {
|
|
|
740
783
|
: ZLinkDispatchMessageKind.Send,
|
|
741
784
|
packetName: packetName.length === 0 ? undefined : packetName,
|
|
742
785
|
correlationId,
|
|
743
|
-
sourceRid: this.context.routingId === undefined ? undefined : String(this.context.routingId)
|
|
786
|
+
sourceRid: this.context.routingId === undefined ? undefined : String(this.context.routingId),
|
|
787
|
+
streamSessionId: this.stream.sessionId
|
|
744
788
|
});
|
|
745
789
|
}
|
|
746
790
|
|
|
@@ -874,6 +918,7 @@ export class ZLinkStreamSessionRuntime {
|
|
|
874
918
|
packetName: header.name === '' ? undefined : header.name,
|
|
875
919
|
correlationId: header.correlationId,
|
|
876
920
|
sourceRid: this.context.routingId === undefined ? undefined : String(this.context.routingId),
|
|
921
|
+
streamSessionId: this.stream.sessionId,
|
|
877
922
|
flowId: flowEnabled ? header.flowId : undefined,
|
|
878
923
|
flowOrigin: flowEnabled ? header.flowOrigin : undefined,
|
|
879
924
|
errorReason: ZLinkDispatchErrorReason.Shutdown
|