@zlink-systems/framework 0.31.0 → 0.32.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/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActor.d.ts +2 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.d.ts +6 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.js +2 -0
- package/dist/contracts/Actors/index.d.ts +1 -0
- package/dist/contracts/Actors/index.js +1 -0
- package/dist/contracts/Common/payload-slab.d.ts +4 -0
- package/dist/contracts/Common/payload-slab.js +30 -0
- package/dist/contracts/Handlers/Contexts.d.ts +1 -0
- package/dist/internal.d.ts +9 -0
- package/dist/internal.js +23 -1
- package/dist/runtime/actors/actor-client.d.ts +1 -1
- package/dist/runtime/actors/actor-client.js +32 -23
- package/dist/runtime/actors/actor-context.js +1 -1
- package/dist/runtime/actors/actor-creation.js +1 -1
- package/dist/runtime/actors/actor-mailbox.d.ts +1 -1
- package/dist/runtime/actors/actor-runtime-state.d.ts +3 -2
- package/dist/runtime/actors/actor-runtime-state.js +24 -8
- package/dist/runtime/actors/index.d.ts +3 -3
- package/dist/runtime/actors/index.js +19 -32
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +4 -2
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -1
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +1 -0
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +3 -0
- package/dist/runtime/backend/contracts/index.d.ts +2 -0
- package/dist/runtime/backend/mesh-completion-table.d.ts +1 -0
- package/dist/runtime/backend/mesh-completion-table.js +1 -0
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +5 -1
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +7 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +17 -11
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +2 -2
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +15 -8
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +7 -6
- package/dist/runtime/channels/channel-dispatch-pipeline.js +1 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +7 -3
- package/dist/runtime/channels/channel-dispatchers.js +27 -19
- package/dist/runtime/channels/channel-envelope.js +543 -23
- package/dist/runtime/channels/channel-receive-loops.d.ts +9 -6
- package/dist/runtime/channels/channel-receive-loops.js +59 -18
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +22 -3
- package/dist/runtime/channels/channel-socket-registry.d.ts +22 -4
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +1 -1
- package/dist/runtime/diagnostics/runtime-metrics.js +2 -1
- package/dist/runtime/execution/serial-execution-queue.d.ts +26 -13
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +27 -11
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +29 -25
- package/dist/runtime/foundation/service-liveness-registry.d.ts +1 -1
- package/dist/runtime/foundation/service-mailbox.d.ts +3 -1
- package/dist/runtime/foundation/service-mailbox.js +4 -1
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +3 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +28 -12
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +51 -19
- package/dist/runtime/foundation/service-stateful-runtime.js +54 -5
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -0
- package/dist/runtime/foundation/service-stateful-wire-codec.js +15 -0
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +12 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +17 -7
- package/dist/runtime/host/actor-placement-coordinator.d.ts +1 -1
- package/dist/runtime/host/actor-transfer-runtime.d.ts +3 -3
- package/dist/runtime/host/application-job-queue.d.ts +1 -1
- package/dist/runtime/host/index.d.ts +89 -36
- package/dist/runtime/host/index.js +101 -7
- package/dist/runtime/host/location-runtime-owner.d.ts +2 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +181 -44
- package/dist/runtime/host/service-relocation-host-runtime.js +47 -13
- package/dist/runtime/host/spot-address-transport.js +50 -42
- package/dist/runtime/locations/actor-location-claims.js +9 -10
- package/dist/runtime/locations/auto-connect-loop.d.ts +0 -1
- package/dist/runtime/locations/auto-connect-loop.js +25 -19
- package/dist/runtime/locations/auto-connect-planner.js +2 -5
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +1 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +35 -23
- package/dist/runtime/locations/in-memory-location-store.d.ts +0 -2
- package/dist/runtime/locations/in-memory-location-store.js +1 -38
- package/dist/runtime/locations/location-store-repository.d.ts +0 -1
- package/dist/runtime/locations/location-store-repository.js +13 -115
- package/dist/runtime/locations/runtime.d.ts +3 -3
- package/dist/runtime/locations/runtime.js +12 -16
- package/dist/runtime/messaging/creation-payload-codec.js +2 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +4 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +17 -7
- package/dist/runtime/spots/index.d.ts +20 -5
- package/dist/runtime/spots/index.js +14 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +3 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +13 -7
- package/dist/runtime/spots/spot-actor-packet-drain.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -5
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -1
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +8 -6
- package/dist/runtime/spots/spot-node-runtime-manager.js +2 -0
- package/dist/runtime/spots/spot-route-packet-dispatch.js +7 -4
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +3 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +2 -1
- package/dist/runtime/spots/spot-subscription-dispatch.js +3 -1
- package/dist/runtime/spots/spot-timer.d.ts +1 -1
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +9 -3
- package/dist/runtime/streams/actor-session-binding-registry.js +17 -0
- package/dist/runtime/streams/index.d.ts +3 -3
- package/dist/runtime/streams/index.js +22 -2
- package/dist/runtime/streams/managed-stream.js +2 -1
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +3 -9
- package/dist/runtime/streams/session-context.d.ts +2 -2
- package/dist/runtime/streams/session-context.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -0
- package/dist/runtime/streams/stream-session-runtime.js +37 -12
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActor.ts +6 -0
- package/src/contracts/Actors/ZLinkSessionBindingIdentity.ts +7 -0
- package/src/contracts/Actors/index.ts +1 -0
- package/src/contracts/Common/payload-slab.ts +29 -0
- package/src/contracts/Handlers/Contexts.ts +1 -0
- package/src/internal.ts +17 -0
- package/src/runtime/actors/actor-client.ts +48 -23
- package/src/runtime/actors/actor-context.ts +1 -1
- package/src/runtime/actors/actor-creation.ts +1 -1
- package/src/runtime/actors/actor-mailbox.ts +1 -1
- package/src/runtime/actors/actor-runtime-state.ts +28 -10
- package/src/runtime/actors/index.ts +30 -35
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -3
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +4 -0
- package/src/runtime/backend/contracts/index.ts +2 -0
- package/src/runtime/backend/mesh-completion-table.ts +2 -0
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +5 -1
- package/src/runtime/backend/node/node-raw-binding-port.ts +20 -7
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +18 -10
- package/src/runtime/channels/channel-dispatch-pipeline.ts +6 -5
- package/src/runtime/channels/channel-dispatchers.ts +39 -19
- package/src/runtime/channels/channel-envelope.ts +547 -20
- package/src/runtime/channels/channel-receive-loops.ts +93 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +2 -2
- package/src/runtime/channels/channel-socket-registry.ts +3 -3
- package/src/runtime/diagnostics/runtime-metrics.ts +3 -1
- package/src/runtime/execution/serial-execution-queue.ts +13 -13
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +40 -39
- package/src/runtime/foundation/service-liveness-registry.ts +1 -1
- package/src/runtime/foundation/service-mailbox.ts +6 -1
- package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
- package/src/runtime/foundation/service-stateful-registry.ts +39 -14
- package/src/runtime/foundation/service-stateful-runtime.ts +87 -21
- package/src/runtime/foundation/service-stateful-wire-codec.ts +18 -0
- package/src/runtime/foundation/service-wire-constants.generated.ts +10 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -7
- package/src/runtime/host/actor-placement-coordinator.ts +1 -1
- package/src/runtime/host/actor-transfer-runtime.ts +3 -3
- package/src/runtime/host/application-job-queue.ts +1 -1
- package/src/runtime/host/index.ts +183 -44
- package/src/runtime/host/location-runtime-owner.ts +2 -2
- package/src/runtime/host/service-relocation-host-runtime.ts +101 -65
- package/src/runtime/host/spot-address-transport.ts +67 -61
- package/src/runtime/locations/actor-location-claims.ts +14 -14
- package/src/runtime/locations/auto-connect-loop.ts +24 -16
- package/src/runtime/locations/auto-connect-planner.ts +2 -5
- package/src/runtime/locations/auto-connect-reconciler.ts +37 -24
- package/src/runtime/locations/in-memory-location-store.ts +1 -74
- package/src/runtime/locations/location-store-repository.ts +32 -153
- package/src/runtime/locations/runtime.ts +16 -28
- package/src/runtime/messaging/creation-payload-codec.ts +3 -3
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/index.ts +28 -4
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +1 -1
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +16 -6
- package/src/runtime/spots/spot-actor-packet-drain.ts +21 -6
- package/src/runtime/spots/spot-entry-activation.ts +1 -1
- package/src/runtime/spots/spot-node-runtime-manager.ts +8 -6
- package/src/runtime/spots/spot-route-packet-dispatch.ts +8 -4
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +3 -1
- package/src/runtime/spots/spot-serial-executor.ts +1 -1
- package/src/runtime/spots/spot-subscription-dispatch.ts +3 -1
- package/src/runtime/spots/spot-timer.ts +1 -1
- package/src/runtime/streams/actor-session-binding-registry.ts +30 -3
- package/src/runtime/streams/index.ts +30 -4
- package/src/runtime/streams/managed-stream.ts +2 -1
- package/src/runtime/streams/session-calls.ts +9 -14
- package/src/runtime/streams/session-context.ts +6 -11
- package/src/runtime/streams/stream-session-runtime.ts +49 -20
|
@@ -6,7 +6,7 @@ import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message
|
|
|
6
6
|
import type { ZLinkMessageSerializer } from '../../contracts';
|
|
7
7
|
import {
|
|
8
8
|
decodeApplicationPayloadView,
|
|
9
|
-
|
|
9
|
+
encodeOwnedApplicationPayload
|
|
10
10
|
} from '../foundation/service-wire-m6a-codec';
|
|
11
11
|
import {
|
|
12
12
|
decodeFrameworkPayloadMessage,
|
|
@@ -23,7 +23,7 @@ export function encodeFrameworkCreationPayload(
|
|
|
23
23
|
): Buffer {
|
|
24
24
|
const message = encodeFrameworkPayloadMessage(payload ?? null, registry);
|
|
25
25
|
try {
|
|
26
|
-
return
|
|
26
|
+
return encodeOwnedApplicationPayload({
|
|
27
27
|
packetName: CREATION_PACKET_NAME,
|
|
28
28
|
contentType: frameworkPayloadContentType(message),
|
|
29
29
|
payload: message.data()
|
|
@@ -42,7 +42,7 @@ export function decodeFrameworkCreationPayload<T>(
|
|
|
42
42
|
if (application.packetName !== CREATION_PACKET_NAME) {
|
|
43
43
|
throw new RangeError('Creation payload has an unexpected packet name.');
|
|
44
44
|
}
|
|
45
|
-
//
|
|
45
|
+
// Creation frames use owned storage and stay alive through synchronous decode.
|
|
46
46
|
const message = RuntimeMessage.fromOwned(application.payload as Buffer);
|
|
47
47
|
try {
|
|
48
48
|
return decodeFrameworkPayloadMessage<T>(
|
|
@@ -5398,7 +5398,7 @@ function writeRelocationControlData(input: RelocationControlData, writer: Writer
|
|
|
5398
5398
|
export function decodeRelocationControlData(bytes: Uint8Array, context: ServiceWireDecoderContext): RelocationControlData { const reader = new Reader(bytes); const value = readRelocationControlData(reader, context, {}, 0); reader.done("relocation-control-data"); return value; }
|
|
5399
5399
|
export function encodeRelocationControlData(value: RelocationControlData, context: ServiceWireDecoderContext): Uint8Array { const writer = new Writer(); writeRelocationControlData(value, writer, context, {}, 0); return writer.result(); }
|
|
5400
5400
|
|
|
5401
|
-
export type RequestSpecificTail = { readonly originalOperationKind: "actorLookup"; readonly terminalResult: "ok"; readonly actor: ActorRef; readonly spotId: Text8; readonly spotGeneration: NonzeroU64; readonly membershipEpoch: NonzeroU64; readonly authorityOwnerGeneration: NonzeroU64 } | { readonly originalOperationKind: "actorJoin"; readonly terminalResult: "ok"; readonly join: ActorJoinReplyTail } | { readonly originalOperationKind: "streamBind"; readonly terminalResult: "ok"; readonly bindingGeneration: NonzeroU64; readonly authorityOwnerGeneration: NonzeroU64 } | { readonly originalOperationKind: "userSpotCreate"; readonly terminalResult: "ok"; readonly createResult: UserSpotCreateResult; readonly spot: SpotRef } | { readonly originalOperationKind: "userSpotClose"; readonly terminalResult: "ok"; readonly closed: Bool8 } | { readonly originalOperationKind: "actorCreate"; readonly terminalResult: "ok"; readonly creation: ActorCreateTerminal } | { readonly originalOperationKind: MeshOperationKind; readonly terminalResult: RequestTerminalResult };
|
|
5401
|
+
export type RequestSpecificTail = { readonly originalOperationKind: "actorLookup"; readonly terminalResult: "ok"; readonly actor: ActorRef; readonly spotId: Text8; readonly spotGeneration: NonzeroU64; readonly membershipEpoch: NonzeroU64; readonly authorityOwnerGeneration: NonzeroU64 } | { readonly originalOperationKind: "actorJoin"; readonly terminalResult: "ok"; readonly join: ActorJoinReplyTail } | { readonly originalOperationKind: "streamBind"; readonly terminalResult: "ok"; readonly bindingGeneration: NonzeroU64; readonly authorityOwnerGeneration: NonzeroU64 } | { readonly originalOperationKind: "streamBind"; readonly terminalResult: "rejected"; readonly rejectionMessage: NonemptyText16 } | { readonly originalOperationKind: "userSpotCreate"; readonly terminalResult: "ok"; readonly createResult: UserSpotCreateResult; readonly spot: SpotRef } | { readonly originalOperationKind: "userSpotClose"; readonly terminalResult: "ok"; readonly closed: Bool8 } | { readonly originalOperationKind: "actorCreate"; readonly terminalResult: "ok"; readonly creation: ActorCreateTerminal } | { readonly originalOperationKind: MeshOperationKind; readonly terminalResult: RequestTerminalResult };
|
|
5402
5402
|
|
|
5403
5403
|
function readRequestSpecificTail(reader: Reader, context: ServiceWireDecoderContext, enclosing: any, flags: number): RequestSpecificTail {
|
|
5404
5404
|
void context; void enclosing; void flags;
|
|
@@ -5433,6 +5433,10 @@ function readRequestSpecificTail(reader: Reader, context: ServiceWireDecoderCont
|
|
|
5433
5433
|
value["authorityOwnerGeneration"] = readNonzeroU64(body, context, value, flags);
|
|
5434
5434
|
|
|
5435
5435
|
|
|
5436
|
+
} else if (same(value["originalOperationKind"], "streamBind") && same(value["terminalResult"], "rejected")) {
|
|
5437
|
+
value["rejectionMessage"] = readNonemptyText16(body, context, value, flags);
|
|
5438
|
+
|
|
5439
|
+
|
|
5436
5440
|
} else if (same(value["originalOperationKind"], "userSpotCreate") && same(value["terminalResult"], "ok")) {
|
|
5437
5441
|
value["createResult"] = readUserSpotCreateResult(body, context, value, flags);
|
|
5438
5442
|
|
|
@@ -5462,7 +5466,7 @@ function writeRequestSpecificTail(input: RequestSpecificTail, writer: Writer, co
|
|
|
5462
5466
|
|
|
5463
5467
|
const body = writer;
|
|
5464
5468
|
if (same(value["originalOperationKind"], "actorLookup") && same(value["terminalResult"], "ok")) {
|
|
5465
|
-
if (value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5469
|
+
if (value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["rejectionMessage"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5466
5470
|
if (value["actor"] === undefined) fail("actor required");
|
|
5467
5471
|
|
|
5468
5472
|
|
|
@@ -5484,13 +5488,13 @@ function writeRequestSpecificTail(input: RequestSpecificTail, writer: Writer, co
|
|
|
5484
5488
|
|
|
5485
5489
|
writeNonzeroU64(numeric(value["authorityOwnerGeneration"]), body, context, value, flags);
|
|
5486
5490
|
} else if (same(value["originalOperationKind"], "actorJoin") && same(value["terminalResult"], "ok")) {
|
|
5487
|
-
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["bindingGeneration"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5491
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["bindingGeneration"] !== undefined || value["rejectionMessage"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5488
5492
|
if (value["join"] === undefined) fail("join required");
|
|
5489
5493
|
|
|
5490
5494
|
|
|
5491
5495
|
writeActorJoinReplyTail(value["join"], body, context, value, flags);
|
|
5492
5496
|
} else if (same(value["originalOperationKind"], "streamBind") && same(value["terminalResult"], "ok")) {
|
|
5493
|
-
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["join"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5497
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["join"] !== undefined || value["rejectionMessage"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5494
5498
|
if (value["bindingGeneration"] === undefined) fail("bindingGeneration required");
|
|
5495
5499
|
|
|
5496
5500
|
|
|
@@ -5499,8 +5503,14 @@ function writeRequestSpecificTail(input: RequestSpecificTail, writer: Writer, co
|
|
|
5499
5503
|
|
|
5500
5504
|
|
|
5501
5505
|
writeNonzeroU64(numeric(value["authorityOwnerGeneration"]), body, context, value, flags);
|
|
5506
|
+
} else if (same(value["originalOperationKind"], "streamBind") && same(value["terminalResult"], "rejected")) {
|
|
5507
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5508
|
+
if (value["rejectionMessage"] === undefined) fail("rejectionMessage required");
|
|
5509
|
+
|
|
5510
|
+
|
|
5511
|
+
writeNonemptyText16(value["rejectionMessage"], body, context, value, flags);
|
|
5502
5512
|
} else if (same(value["originalOperationKind"], "userSpotCreate") && same(value["terminalResult"], "ok")) {
|
|
5503
|
-
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5513
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["rejectionMessage"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5504
5514
|
if (value["createResult"] === undefined) fail("createResult required");
|
|
5505
5515
|
|
|
5506
5516
|
|
|
@@ -5510,19 +5520,19 @@ function writeRequestSpecificTail(input: RequestSpecificTail, writer: Writer, co
|
|
|
5510
5520
|
|
|
5511
5521
|
writeSpotRef(value["spot"], body, context, value, flags);
|
|
5512
5522
|
} else if (same(value["originalOperationKind"], "userSpotClose") && same(value["terminalResult"], "ok")) {
|
|
5513
|
-
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5523
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["rejectionMessage"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5514
5524
|
if (value["closed"] === undefined) fail("closed required");
|
|
5515
5525
|
|
|
5516
5526
|
|
|
5517
5527
|
writeBool8(value["closed"], body, context, value, flags);
|
|
5518
5528
|
} else if (same(value["originalOperationKind"], "actorCreate") && same(value["terminalResult"], "ok")) {
|
|
5519
|
-
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5529
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["rejectionMessage"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5520
5530
|
if (value["creation"] === undefined) fail("creation required");
|
|
5521
5531
|
|
|
5522
5532
|
|
|
5523
5533
|
writeActorCreateTerminal(value["creation"], body, context, value, flags);
|
|
5524
5534
|
} else {
|
|
5525
|
-
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5535
|
+
if (value["actor"] !== undefined || value["spotId"] !== undefined || value["spotGeneration"] !== undefined || value["membershipEpoch"] !== undefined || value["authorityOwnerGeneration"] !== undefined || value["join"] !== undefined || value["bindingGeneration"] !== undefined || value["rejectionMessage"] !== undefined || value["createResult"] !== undefined || value["spot"] !== undefined || value["closed"] !== undefined || value["creation"] !== undefined) fail("request-specific-tail discriminator agreement");
|
|
5526
5536
|
|
|
5527
5537
|
}
|
|
5528
5538
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// <auto-generated> DO NOT EDIT. schema-sha256:
|
|
1
|
+
// <auto-generated> DO NOT EDIT. schema-sha256: 1a066261b5770782bf4027d3d08723669d4092a085699963afb214872f27d710
|
|
2
2
|
export interface ServiceWireRouteFence { readonly id: string; readonly generation: bigint; readonly targetNodeRid: Uint8Array; readonly targetNodeGeneration: bigint; readonly expectedAuthorityOwnerGeneration: bigint; readonly expectedOwnerLeaseGeneration: bigint; }
|
|
3
3
|
export interface ApplicationPayloadEnvelopeV1 { readonly packetName: string; readonly contentType: string; readonly payload: Uint8Array; }
|
|
4
4
|
export interface ActorJoin28 { readonly correlation: bigint; readonly actor: ServiceWireRouteFence; readonly entry: boolean; readonly targetSpot: ServiceWireRouteFence; readonly payload?: ApplicationPayloadEnvelopeV1; }
|
|
@@ -346,14 +346,14 @@ export class DefaultZLinkSpotManager {
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
private readonly factories: ReadonlySet<Type<ZLinkSpot>>;
|
|
349
|
-
|
|
349
|
+
readonly activations: ZLinkSpotActivationRegistry;
|
|
350
350
|
private readonly workerRuntime: ZLinkWorkerRuntime;
|
|
351
351
|
private readonly locationClaim: ZLinkSpotLocationClaim;
|
|
352
352
|
private readonly routedSpotPackets: ZLinkRoutedSpotPacketDispatch;
|
|
353
353
|
private readonly actorMembership: ZLinkSpotActorMembership;
|
|
354
354
|
private readonly activationLifecycle: ZLinkSpotActivationLifecycle;
|
|
355
355
|
private readonly formalRemoteTransfers = new ZLinkFormalRemoteActorTransferRegistry();
|
|
356
|
-
|
|
356
|
+
readonly formalRemoteActorAdmissions = new ZLinkFormalRemoteActorAdmissionRegistry();
|
|
357
357
|
private readonly pendingInstanceMaterializations = new Map<
|
|
358
358
|
string,
|
|
359
359
|
Promise<ZLinkSpotActivation>
|
|
@@ -365,7 +365,7 @@ export class DefaultZLinkSpotManager {
|
|
|
365
365
|
string,
|
|
366
366
|
Map<string, Promise<ZLinkSpotActivation>>
|
|
367
367
|
>();
|
|
368
|
-
|
|
368
|
+
readonly closeOperations = new Map<string, ZLinkTargetSpotCloseOperation>();
|
|
369
369
|
private readonly pendingInstanceTerminals = new Map<string, number>();
|
|
370
370
|
private readonly pendingInstanceTerminalGenerations = new Map<string, Map<string, number>>();
|
|
371
371
|
private readonly deferredInstanceAuthorityReleases = new Map<string, Set<bigint>>();
|
|
@@ -1684,6 +1684,30 @@ export class DefaultZLinkSpotManager {
|
|
|
1684
1684
|
return this.admitRoutedActorPacketPrefix(owner.spotId, actorId, records);
|
|
1685
1685
|
}
|
|
1686
1686
|
|
|
1687
|
+
/** Runs an owner-side lifecycle decision in the Actor's existing execution gate. */
|
|
1688
|
+
executeActorTurn<T>(
|
|
1689
|
+
meshName: string,
|
|
1690
|
+
spotId: RoutingId | undefined,
|
|
1691
|
+
actorId: string,
|
|
1692
|
+
operation: () => Promise<T>
|
|
1693
|
+
): Promise<T> {
|
|
1694
|
+
if (spotId === undefined) {
|
|
1695
|
+
if (this.options.executeEntryActor === undefined) {
|
|
1696
|
+
throw new ZLinkConfigurationException(
|
|
1697
|
+
`Entry Spot Actor '${actorId}' has no execution gate for MeshNode '${meshName}'.`
|
|
1698
|
+
);
|
|
1699
|
+
}
|
|
1700
|
+
return this.options.executeEntryActor(meshName, actorId, operation);
|
|
1701
|
+
}
|
|
1702
|
+
const activation = this.resolveApplicationActivation(spotId, meshName);
|
|
1703
|
+
if (activation === undefined) {
|
|
1704
|
+
throw new ZLinkConfigurationException(
|
|
1705
|
+
`Actor '${actorId}' has no active Spot execution gate for '${String(spotId)}'.`
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1708
|
+
return activation.executeActor(actorId, operation);
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1687
1711
|
async dispatchRoutedSpotSend(
|
|
1688
1712
|
spotId: RoutingId,
|
|
1689
1713
|
packetName: string | undefined,
|
|
@@ -2254,7 +2278,7 @@ export class DefaultZLinkSpotManager {
|
|
|
2254
2278
|
}
|
|
2255
2279
|
}
|
|
2256
2280
|
|
|
2257
|
-
|
|
2281
|
+
async dispatchMeshActorJoinCore(
|
|
2258
2282
|
meshName: string,
|
|
2259
2283
|
owner: ReadyRecord,
|
|
2260
2284
|
record: ReceiveRecord,
|
|
@@ -255,7 +255,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
|
|
|
255
255
|
: this.options.actorResolver(actorId);
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
async commitTransferredActorTransaction(
|
|
259
259
|
activation: ZLinkSpotActivation,
|
|
260
260
|
actor: ZLinkActor,
|
|
261
261
|
backlog: readonly ZLinkActorHandoffPacket[],
|
|
@@ -79,6 +79,7 @@ export interface ZLinkActorRequestTerminal {
|
|
|
79
79
|
/** One admitted Actor packet and the routing context that must move with it. */
|
|
80
80
|
export interface ZLinkActorPacketDelivery {
|
|
81
81
|
readonly origin: ApplicationJobOrigin;
|
|
82
|
+
readonly receivedAt?: Date;
|
|
82
83
|
readonly actorId: string;
|
|
83
84
|
readonly parts: readonly Message[];
|
|
84
85
|
readonly returnResponse: boolean;
|
|
@@ -142,6 +143,7 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
142
143
|
): Promise<unknown> {
|
|
143
144
|
return this.dispatchDelivery(serial, {
|
|
144
145
|
origin,
|
|
146
|
+
receivedAt: new Date(),
|
|
145
147
|
actorId,
|
|
146
148
|
parts,
|
|
147
149
|
returnResponse,
|
|
@@ -168,10 +170,12 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
168
170
|
actorId,
|
|
169
171
|
parts,
|
|
170
172
|
returnResponse,
|
|
173
|
+
receivedAt: deliveryReceivedAt,
|
|
171
174
|
remoteBoundSessionTarget,
|
|
172
175
|
fallbackActorRef,
|
|
173
176
|
requestTerminal
|
|
174
177
|
} = delivery;
|
|
178
|
+
const receivedAt = deliveryReceivedAt ?? new Date();
|
|
175
179
|
if (parts.length < 2) {
|
|
176
180
|
this.reportInvalidFrame(actorId, ZLinkDispatchMessageKind.ActorSend);
|
|
177
181
|
return { response: undefined };
|
|
@@ -298,7 +302,8 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
298
302
|
zlinkSerialWorkOptions(
|
|
299
303
|
parts[1].data().byteLength,
|
|
300
304
|
zlinkMetadataByteLength(header.metadata)
|
|
301
|
-
)
|
|
305
|
+
),
|
|
306
|
+
receivedAt
|
|
302
307
|
)
|
|
303
308
|
};
|
|
304
309
|
}
|
|
@@ -375,7 +380,8 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
375
380
|
requestTerminal: ZLinkActorRequestTerminal | undefined,
|
|
376
381
|
requestDeadlineUnixMs: number | undefined,
|
|
377
382
|
serial: ZLinkSpotSerialTurnExecutor | undefined,
|
|
378
|
-
workOptions: ZLinkSerialWorkOptions
|
|
383
|
+
workOptions: ZLinkSerialWorkOptions,
|
|
384
|
+
receivedAt: Date
|
|
379
385
|
): Promise<unknown> {
|
|
380
386
|
const spot = typeof this.options.spot === 'function' ? this.options.spot() : this.options.spot;
|
|
381
387
|
const dispatcher = new ZLinkSpotActorDispatcher({
|
|
@@ -415,7 +421,8 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
415
421
|
await dispatcher.dispatchSendDecoded(actor, header.name, decodePayload, {
|
|
416
422
|
meshName: spot.context.meshName,
|
|
417
423
|
metadata: zlinkMessageMetadata(header.metadata),
|
|
418
|
-
correlationId: header.correlationId ?? undefined
|
|
424
|
+
correlationId: header.correlationId ?? undefined,
|
|
425
|
+
receivedAt
|
|
419
426
|
});
|
|
420
427
|
this.trace(
|
|
421
428
|
ZLinkMessageFlowOutcome.Completed,
|
|
@@ -448,7 +455,8 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
448
455
|
{
|
|
449
456
|
meshName: spot.context.meshName,
|
|
450
457
|
metadata: zlinkMessageMetadata(header.metadata),
|
|
451
|
-
correlationId: header.correlationId ?? header.requestSeq.toString()
|
|
458
|
+
correlationId: header.correlationId ?? header.requestSeq.toString(),
|
|
459
|
+
receivedAt
|
|
452
460
|
},
|
|
453
461
|
async (response) => {
|
|
454
462
|
this.trace(
|
|
@@ -476,7 +484,8 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
476
484
|
{
|
|
477
485
|
meshName: spot.context.meshName,
|
|
478
486
|
metadata: zlinkMessageMetadata(header.metadata),
|
|
479
|
-
correlationId: header.correlationId ?? header.requestSeq.toString()
|
|
487
|
+
correlationId: header.correlationId ?? header.requestSeq.toString(),
|
|
488
|
+
receivedAt
|
|
480
489
|
}
|
|
481
490
|
);
|
|
482
491
|
this.trace(
|
|
@@ -494,7 +503,8 @@ export class ZLinkSpotActorPacketDispatch {
|
|
|
494
503
|
{
|
|
495
504
|
meshName: spot.context.meshName,
|
|
496
505
|
metadata: zlinkMessageMetadata(header.metadata),
|
|
497
|
-
correlationId: header.correlationId ?? header.requestSeq.toString()
|
|
506
|
+
correlationId: header.correlationId ?? header.requestSeq.toString(),
|
|
507
|
+
receivedAt
|
|
498
508
|
},
|
|
499
509
|
async (response, replyOptions) => {
|
|
500
510
|
this.trace(
|
|
@@ -37,14 +37,16 @@ interface ZLinkSpotActorPacketDrainOptions {
|
|
|
37
37
|
) => void;
|
|
38
38
|
readonly waitIdle: () => Promise<void>;
|
|
39
39
|
readonly flowEnabled?: () => boolean;
|
|
40
|
+
readonly receivedAtClock?: () => Date;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
const ZLINK_SPOT_ACTOR_RECV_INFO_NO_BIND = 1;
|
|
44
|
+
const systemReceivedAtClock = (): Date => new Date();
|
|
43
45
|
|
|
44
46
|
export class ZLinkSpotActorPacketDrain {
|
|
45
47
|
private readonly continuations = new Map<
|
|
46
48
|
string,
|
|
47
|
-
{ readonly owner: string; readonly parts: Message[] }
|
|
49
|
+
{ readonly owner: string; readonly parts: Message[]; readonly receivedAt: Date }
|
|
48
50
|
>();
|
|
49
51
|
|
|
50
52
|
constructor(private readonly options: ZLinkSpotActorPacketDrainOptions) {}
|
|
@@ -60,6 +62,7 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
60
62
|
let requestId: bigint | undefined;
|
|
61
63
|
let flags: number | undefined;
|
|
62
64
|
let packetKey: string | undefined;
|
|
65
|
+
let receivedAt: Date | undefined;
|
|
63
66
|
try {
|
|
64
67
|
for (;;) {
|
|
65
68
|
const part = info.recvActorPart(ZLINK_RECV_DONT_WAIT);
|
|
@@ -67,7 +70,8 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
67
70
|
if (parts.length > 0 && packetKey !== undefined) {
|
|
68
71
|
this.continuations.set(packetKey, {
|
|
69
72
|
owner: continuationOwner(parts[0], this.flowEnabled()),
|
|
70
|
-
parts: parts.splice(0)
|
|
73
|
+
parts: parts.splice(0),
|
|
74
|
+
receivedAt: receivedAt ?? (this.options.receivedAtClock ?? systemReceivedAtClock)()
|
|
71
75
|
});
|
|
72
76
|
return;
|
|
73
77
|
}
|
|
@@ -78,6 +82,8 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
78
82
|
if (packetKey === undefined) {
|
|
79
83
|
packetKey = currentPacketKey;
|
|
80
84
|
const pending = this.continuations.get(currentPacketKey);
|
|
85
|
+
receivedAt =
|
|
86
|
+
pending?.receivedAt ?? (this.options.receivedAtClock ?? systemReceivedAtClock)();
|
|
81
87
|
if (pending !== undefined) {
|
|
82
88
|
if (isStreamHeaderMessage(part.message, this.flowEnabled())) {
|
|
83
89
|
closeMessages(pending.parts);
|
|
@@ -125,7 +131,13 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
125
131
|
return;
|
|
126
132
|
}
|
|
127
133
|
if (noBindInfo !== undefined) {
|
|
128
|
-
await this.dispatchNoBindActorRequest(
|
|
134
|
+
await this.dispatchNoBindActorRequest(
|
|
135
|
+
noBindInfo,
|
|
136
|
+
actorId,
|
|
137
|
+
parts,
|
|
138
|
+
actorRef,
|
|
139
|
+
receivedAt ?? (this.options.receivedAtClock ?? systemReceivedAtClock)()
|
|
140
|
+
);
|
|
129
141
|
} else {
|
|
130
142
|
await this.options.actorPacketHandler({
|
|
131
143
|
origin: 'remote',
|
|
@@ -133,7 +145,8 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
133
145
|
parts,
|
|
134
146
|
returnResponse: false,
|
|
135
147
|
sourceSessionRid,
|
|
136
|
-
fallbackActorRef: actorRef as unknown as ActorRef | undefined
|
|
148
|
+
fallbackActorRef: actorRef as unknown as ActorRef | undefined,
|
|
149
|
+
receivedAt
|
|
137
150
|
});
|
|
138
151
|
}
|
|
139
152
|
} finally {
|
|
@@ -188,7 +201,8 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
188
201
|
info: ZLinkBackendActorRecvInfo,
|
|
189
202
|
actorId: string,
|
|
190
203
|
parts: readonly Message[],
|
|
191
|
-
actorRef: ZLinkBackendActorRef | undefined
|
|
204
|
+
actorRef: ZLinkBackendActorRef | undefined,
|
|
205
|
+
receivedAt: Date
|
|
192
206
|
): Promise<void> {
|
|
193
207
|
try {
|
|
194
208
|
const response = await this.options.actorPacketHandler?.({
|
|
@@ -197,7 +211,8 @@ export class ZLinkSpotActorPacketDrain {
|
|
|
197
211
|
parts,
|
|
198
212
|
returnResponse: true,
|
|
199
213
|
sourceSessionRid: info.sourceSessionRid,
|
|
200
|
-
fallbackActorRef: actorRef as unknown as ActorRef | undefined
|
|
214
|
+
fallbackActorRef: actorRef as unknown as ActorRef | undefined,
|
|
215
|
+
receivedAt
|
|
201
216
|
});
|
|
202
217
|
this.options.replyActorNoBind?.(
|
|
203
218
|
info,
|
|
@@ -105,7 +105,7 @@ interface ZLinkEntrySpotActivationOptions {
|
|
|
105
105
|
|
|
106
106
|
export class ZLinkEntrySpotActivation {
|
|
107
107
|
private readonly serial: ZLinkSpotSerialTurnExecutor;
|
|
108
|
-
|
|
108
|
+
readonly spotSerialExecutor: ZLinkSpotSerialExecutor;
|
|
109
109
|
private readonly timers: ZLinkSpotTimerRegistry;
|
|
110
110
|
private readonly actorHandlers = new ZLinkSpotActorHandlerRegistryRuntime();
|
|
111
111
|
private readonly handlers: DefaultZLinkSpotHandlerRegistry;
|
|
@@ -158,10 +158,10 @@ export interface ZLinkSpotNodeRuntimeManagerOptions {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
export class ZLinkSpotNodeRuntimeManager {
|
|
161
|
-
|
|
161
|
+
readonly meshNodes = new Map<string, ZLinkBackendMeshNode>();
|
|
162
162
|
private readonly meshPumps = new Map<string, ZLinkMeshDispatchPump>();
|
|
163
163
|
private readonly meshCompletions = new Map<string, ZLinkMeshCompletionTable>();
|
|
164
|
-
|
|
164
|
+
readonly entryActivations = new Map<string, ZLinkEntrySpotActivation>();
|
|
165
165
|
private readonly entryActivationStarts = new Map<string, Promise<void>>();
|
|
166
166
|
private readonly publishers = new Map<
|
|
167
167
|
string,
|
|
@@ -179,11 +179,11 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
179
179
|
private readonly runtimeChannelWeights = new Map<string, Map<string, number>>();
|
|
180
180
|
private readonly entrySpotIds = new Map<string, string>();
|
|
181
181
|
private runtimeWeightPublication = Promise.resolve();
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
statePublication = Promise.resolve();
|
|
183
|
+
locationAutoConnect?: ZLinkSpotNodeLocationAutoConnectContext;
|
|
184
184
|
private readonly applicationJobQueue: ApplicationJobQueue;
|
|
185
185
|
|
|
186
|
-
constructor(
|
|
186
|
+
constructor(readonly options: ZLinkSpotNodeRuntimeManagerOptions) {
|
|
187
187
|
if ((options.detachedTaskRunner as unknown) === undefined) {
|
|
188
188
|
throw new ZLinkConfigurationException('Spot node runtime requires a detached task runner.');
|
|
189
189
|
}
|
|
@@ -304,6 +304,8 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
304
304
|
const node = meshAdapter.createMeshNode(this.options.context, {
|
|
305
305
|
meshName: spotNodeName,
|
|
306
306
|
routingId,
|
|
307
|
+
sendHighWaterMark: spotNode.router?.sendHighWaterMark,
|
|
308
|
+
receiveHighWaterMark: spotNode.router?.receiveHighWaterMark,
|
|
307
309
|
receiveTimeoutMs: spotNode.router?.receiveTimeoutMs,
|
|
308
310
|
applicationJobQueue: this.applicationJobQueue,
|
|
309
311
|
infrastructureTaskRunner: this.options.detachedTaskRunner,
|
|
@@ -1089,7 +1091,7 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
1089
1091
|
}
|
|
1090
1092
|
}
|
|
1091
1093
|
|
|
1092
|
-
|
|
1094
|
+
async initializeEntrySpot(
|
|
1093
1095
|
spotNodeName: string,
|
|
1094
1096
|
node: ZLinkBackendMeshNode,
|
|
1095
1097
|
spotNode: ZLinkSpotNodeOptions
|
|
@@ -79,9 +79,10 @@ export class ZLinkSpotRoutePacketDispatch {
|
|
|
79
79
|
constructor(private readonly options: ZLinkSpotRoutePacketDispatchOptions) {}
|
|
80
80
|
|
|
81
81
|
async dispatch(received: BackendReceived): Promise<boolean> {
|
|
82
|
+
const receivedAt = new Date();
|
|
82
83
|
const directEnvelope = decodeSpotDirectEnvelope(received.parts);
|
|
83
84
|
if (directEnvelope !== undefined) {
|
|
84
|
-
await this.dispatchSpotDirectEnvelope(received, directEnvelope);
|
|
85
|
+
await this.dispatchSpotDirectEnvelope(received, directEnvelope, receivedAt);
|
|
85
86
|
return true;
|
|
86
87
|
}
|
|
87
88
|
let envelope: ReturnType<typeof decodeChannelEnvelope>;
|
|
@@ -148,7 +149,8 @@ export class ZLinkSpotRoutePacketDispatch {
|
|
|
148
149
|
contentType: envelope.header.contentType,
|
|
149
150
|
packetName: envelope.packetName!,
|
|
150
151
|
metadata: zlinkMessageMetadata(envelope.header.metadata),
|
|
151
|
-
correlationId: envelope.header.correlationId ?? undefined
|
|
152
|
+
correlationId: envelope.header.correlationId ?? undefined,
|
|
153
|
+
receivedAt
|
|
152
154
|
};
|
|
153
155
|
try {
|
|
154
156
|
let response: unknown;
|
|
@@ -245,7 +247,8 @@ export class ZLinkSpotRoutePacketDispatch {
|
|
|
245
247
|
|
|
246
248
|
private async dispatchSpotDirectEnvelope(
|
|
247
249
|
received: BackendReceived,
|
|
248
|
-
envelope: ZLinkSpotDirectEnvelope
|
|
250
|
+
envelope: ZLinkSpotDirectEnvelope,
|
|
251
|
+
receivedAt: Date
|
|
249
252
|
): Promise<void> {
|
|
250
253
|
const replyable =
|
|
251
254
|
envelope.kind === ZLinkChannelMessageKind.Request && hasReplyToken(received.replyToken);
|
|
@@ -296,7 +299,8 @@ export class ZLinkSpotRoutePacketDispatch {
|
|
|
296
299
|
channelName: envelope.channelName,
|
|
297
300
|
packetName: envelope.packetName!,
|
|
298
301
|
metadata: zlinkMessageMetadata(envelope.metadata),
|
|
299
|
-
correlationId: undefined
|
|
302
|
+
correlationId: undefined,
|
|
303
|
+
receivedAt
|
|
300
304
|
};
|
|
301
305
|
releaseApplicationJobPermitBeforeHandler();
|
|
302
306
|
response = await handler.handle(spot, envelope.payload, handlerContext);
|
|
@@ -109,6 +109,7 @@ export class ZLinkRoutedSpotPacketDispatch {
|
|
|
109
109
|
context: ZLinkRoutedSpotPacketContext,
|
|
110
110
|
returnResponse: boolean
|
|
111
111
|
): Promise<unknown> {
|
|
112
|
+
const receivedAt = new Date();
|
|
112
113
|
const activation = this.options.resolveActivation(spotId);
|
|
113
114
|
if (activation === undefined) {
|
|
114
115
|
this.reportMissing(spotId, packetName, context, returnResponse);
|
|
@@ -210,7 +211,8 @@ export class ZLinkRoutedSpotPacketDispatch {
|
|
|
210
211
|
channelName: context.channelName,
|
|
211
212
|
contentType: context.contentType,
|
|
212
213
|
packetName: packetName!,
|
|
213
|
-
metadata: zlinkMessageMetadata({})
|
|
214
|
+
metadata: zlinkMessageMetadata({}),
|
|
215
|
+
receivedAt
|
|
214
216
|
};
|
|
215
217
|
releaseApplicationJobPermitBeforeHandler();
|
|
216
218
|
response = await handler.handle(current.spot, payload, handlerContext);
|
|
@@ -28,7 +28,7 @@ export type ZLinkActorPacketTurnDispatch = (
|
|
|
28
28
|
export class ZLinkSpotSerialExecutor {
|
|
29
29
|
private readonly actorSerials = new Map<string, ZLinkSpotSerialTurnExecutor>();
|
|
30
30
|
private readonly timerSerials = new Map<string, ZLinkSpotSerialTurnExecutor>();
|
|
31
|
-
|
|
31
|
+
readonly actorExecutors = new Map<string, ZLinkActorSerialExecutor>();
|
|
32
32
|
private executionBarrier: ZLinkExecutionBarrier | undefined;
|
|
33
33
|
private closing = false;
|
|
34
34
|
private closePromise: Promise<void> | undefined;
|
|
@@ -133,6 +133,7 @@ export class ZLinkSpotSubscriptionDispatch {
|
|
|
133
133
|
readonly parts: readonly Message[];
|
|
134
134
|
readonly routingId: RoutingId | unknown | null;
|
|
135
135
|
}): Promise<void> {
|
|
136
|
+
const receivedAt = new Date();
|
|
136
137
|
if (message.parts.length === 0) {
|
|
137
138
|
this.options.dispatchErrors?.report({
|
|
138
139
|
surface: ZLinkDispatchErrorSurface.SpotSubscription,
|
|
@@ -213,7 +214,8 @@ export class ZLinkSpotSubscriptionDispatch {
|
|
|
213
214
|
topic: message.topic,
|
|
214
215
|
source: subSource,
|
|
215
216
|
metadata: zlinkMessageMetadata(envelope.header.metadata),
|
|
216
|
-
correlationId: envelope.header.correlationId ?? undefined
|
|
217
|
+
correlationId: envelope.header.correlationId ?? undefined,
|
|
218
|
+
receivedAt
|
|
217
219
|
});
|
|
218
220
|
} catch (error) {
|
|
219
221
|
this.options.dispatchErrors?.report({
|
|
@@ -522,7 +522,7 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
522
522
|
private pendingScheduledIndex: bigint | undefined;
|
|
523
523
|
private timeout: unknown;
|
|
524
524
|
/** The dispatch in flight, from its timer callback until `completeFireCore`. */
|
|
525
|
-
|
|
525
|
+
running: Promise<void> | undefined;
|
|
526
526
|
private dispatchFailure: { readonly cause: unknown } | undefined;
|
|
527
527
|
private finalization: ZLinkTimerFinalization | undefined;
|
|
528
528
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ZLinkStreamHeaderFlags, type ZLinkStreamFrameHeader } from './protocol';
|
|
1
2
|
import {
|
|
2
3
|
ZLinkFrameworkErrorKind,
|
|
3
4
|
ZLinkFrameworkException
|
|
@@ -153,9 +154,9 @@ export class ZLinkActorSessionBindingRegistry<
|
|
|
153
154
|
TContext extends ZLinkActorSessionBindingContext<TActor>,
|
|
154
155
|
TActor extends ZLinkActorSessionBindingActor
|
|
155
156
|
> {
|
|
156
|
-
|
|
157
|
+
readonly lane = new ZLinkStateLane();
|
|
157
158
|
private readonly routes = new Map<string, ZLinkActorSessionRoute<TContext, TActor>>();
|
|
158
|
-
|
|
159
|
+
readonly nextActorSlots = new WeakMap<TContext, number>();
|
|
159
160
|
private readonly sealWaiters = new Map<
|
|
160
161
|
string,
|
|
161
162
|
Set<{
|
|
@@ -166,7 +167,7 @@ export class ZLinkActorSessionBindingRegistry<
|
|
|
166
167
|
>();
|
|
167
168
|
private readonly activeFrameWaiters = new Map<string, Set<ZLinkActorSessionActiveFrameWaiter>>();
|
|
168
169
|
private readonly relocations = new Map<string, ZLinkActorSessionRelocationQueue>();
|
|
169
|
-
|
|
170
|
+
readonly absentSessionRelocationResults = new Map<
|
|
170
171
|
string,
|
|
171
172
|
{
|
|
172
173
|
readonly result: SessionRelocationResult;
|
|
@@ -409,6 +410,32 @@ export class ZLinkActorSessionBindingRegistry<
|
|
|
409
410
|
return await this.lane.run(() => this.routeCore(actorId));
|
|
410
411
|
}
|
|
411
412
|
|
|
413
|
+
async submitReply<T>(
|
|
414
|
+
context: TContext,
|
|
415
|
+
header: ZLinkStreamFrameHeader,
|
|
416
|
+
submit: (header: ZLinkStreamFrameHeader) => Promise<T>
|
|
417
|
+
): Promise<T> {
|
|
418
|
+
const { submission } = await this.lane.run(() => {
|
|
419
|
+
const current =
|
|
420
|
+
header.actorSlot === undefined ||
|
|
421
|
+
[...this.routes.values()].some(
|
|
422
|
+
(route) => route.context === context && route.actorSlot === header.actorSlot
|
|
423
|
+
);
|
|
424
|
+
return {
|
|
425
|
+
submission: submit(
|
|
426
|
+
current
|
|
427
|
+
? header
|
|
428
|
+
: {
|
|
429
|
+
...header,
|
|
430
|
+
actorSlot: undefined,
|
|
431
|
+
flags: header.flags & ~ZLinkStreamHeaderFlags.HasActorSlot
|
|
432
|
+
}
|
|
433
|
+
)
|
|
434
|
+
};
|
|
435
|
+
});
|
|
436
|
+
return await submission;
|
|
437
|
+
}
|
|
438
|
+
|
|
412
439
|
/** Registers a current binding's frame in the same turn that can retire its slot. */
|
|
413
440
|
async submitCurrent<T>(
|
|
414
441
|
actorId: string,
|