@zlink-systems/framework 0.30.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +150 -68
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
- package/dist/contracts/Channels/Calls.d.ts +2 -1
- package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
- package/dist/contracts/Handlers/Attributes.d.ts +5 -13
- package/dist/contracts/Handlers/Attributes.js +7 -11
- package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
- package/dist/contracts/Handlers/JsonContract.js +4 -153
- package/dist/contracts/Spots/Contracts.d.ts +2 -1
- package/dist/nest-integration.d.ts +1 -1
- package/dist/nest-integration.js +2 -1
- package/dist/runtime/actors/actor-client.d.ts +1 -1
- package/dist/runtime/actors/actor-client.js +14 -12
- package/dist/runtime/actors/actor-handoff.d.ts +1 -1
- package/dist/runtime/actors/actor-handoff.js +7 -4
- package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
- package/dist/runtime/actors/actor-local-native-join.js +9 -12
- package/dist/runtime/actors/actor-remote-wire.js +15 -0
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
- package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
- package/dist/runtime/actors/index.d.ts +2 -1
- package/dist/runtime/actors/index.js +18 -6
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
- package/dist/runtime/admission.d.ts +1 -1
- package/dist/runtime/admission.js +15 -5
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +2 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +37 -22
- package/dist/runtime/application-jobs/contracts.d.ts +10 -1
- package/dist/runtime/backend/contracts/index.d.ts +18 -9
- package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
- package/dist/runtime/backend/mesh-completion-table.js +149 -49
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
- package/dist/runtime/backend/mesh-dispatch-pump.js +32 -11
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +42 -22
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +13 -5
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +69 -51
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +6 -6
- package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
- package/dist/runtime/backend/runtime-message.d.ts +1 -0
- package/dist/runtime/backend/runtime-message.js +5 -0
- package/dist/runtime/backend/runtime-values.d.ts +1 -0
- package/dist/runtime/backend/runtime-values.js +2 -1
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +58 -21
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
- package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
- package/dist/runtime/channels/channel-dispatch-services.js +45 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
- package/dist/runtime/channels/channel-dispatchers.js +27 -26
- package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
- package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +83 -8
- package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
- package/dist/runtime/channels/channel-runtime-manager.js +12 -12
- package/dist/runtime/channels/channel-transports.d.ts +18 -15
- package/dist/runtime/channels/channel-transports.js +48 -31
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +2 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
- package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
- package/dist/runtime/channels/source-spot-router.d.ts +2 -2
- package/dist/runtime/channels/source-spot-router.js +4 -4
- package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-node-route-transport.js +4 -4
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
- package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
- package/dist/runtime/execution/serial-execution-queue.js +1 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
- package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
- package/dist/runtime/foundation/durable-service-request.js +98 -0
- package/dist/runtime/foundation/operation-identity.d.ts +1 -0
- package/dist/runtime/foundation/operation-identity.js +5 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +22 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +356 -232
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
- package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
- package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -4
- package/dist/runtime/foundation/service-stateful-runtime.js +44 -103
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -5
- package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
- package/dist/runtime/foundation/service-topology-registry.js +61 -27
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
- package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
- package/dist/runtime/handlers/handler-instance-scope.js +54 -11
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
- package/dist/runtime/host/application-job-queue.d.ts +19 -7
- package/dist/runtime/host/application-job-queue.js +150 -42
- package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
- package/dist/runtime/host/entry-actor-runtime.js +3 -0
- package/dist/runtime/host/index.d.ts +7 -1
- package/dist/runtime/host/index.js +142 -118
- package/dist/runtime/host/remote-bound-session-relay.js +2 -18
- package/dist/runtime/host/route-mesh-runtime.js +1 -1
- package/dist/runtime/host/service-relocation-control.d.ts +1 -0
- package/dist/runtime/host/service-relocation-control.js +10 -4
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
- package/dist/runtime/host/service-relocation-host-runtime.js +213 -241
- package/dist/runtime/host/spot-address-transport.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.js +1 -0
- package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
- package/dist/runtime/locations/actor-location-claims.js +34 -19
- package/dist/runtime/locations/lifecycle.d.ts +1 -2
- package/dist/runtime/locations/lifecycle.js +2 -5
- package/dist/runtime/locations/runtime.d.ts +1 -1
- package/dist/runtime/locations/runtime.js +24 -23
- package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
- package/dist/runtime/messaging/framework-json-v1.js +38 -294
- package/dist/runtime/messaging/packet-name.d.ts +1 -1
- package/dist/runtime/messaging/packet-name.js +8 -24
- package/dist/runtime/messaging/request-result.d.ts +2 -0
- package/dist/runtime/messaging/request-result.js +54 -0
- package/dist/runtime/messaging/submission-result.d.ts +1 -0
- package/dist/runtime/messaging/submission-result.js +5 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
- package/dist/runtime/spots/index.d.ts +3 -0
- package/dist/runtime/spots/index.js +9 -2
- package/dist/runtime/spots/spot-activation.d.ts +1 -0
- package/dist/runtime/spots/spot-activation.js +17 -8
- package/dist/runtime/spots/spot-entry-activation.js +6 -2
- package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
- package/dist/runtime/spots/spot-handler-registry.js +18 -8
- package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
- package/dist/runtime/spots/spot-outbound.d.ts +3 -0
- package/dist/runtime/spots/spot-outbound.js +24 -15
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -0
- package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
- package/dist/runtime/spots/spot-timer.js +1 -0
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
- package/dist/runtime/streams/stream-session-runtime.js +13 -27
- package/package.json +2 -2
- package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
- package/src/contracts/Channels/Calls.ts +2 -1
- package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
- package/src/contracts/Handlers/Attributes.ts +14 -21
- package/src/contracts/Handlers/JsonContract.ts +8 -216
- package/src/contracts/Spots/Contracts.ts +2 -1
- package/src/nest-integration.ts +1 -0
- package/src/runtime/actors/actor-client.ts +40 -16
- package/src/runtime/actors/actor-handoff.ts +9 -4
- package/src/runtime/actors/actor-join-relocation.ts +1 -0
- package/src/runtime/actors/actor-local-native-join.ts +17 -26
- package/src/runtime/actors/actor-remote-wire.ts +17 -0
- package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
- package/src/runtime/actors/actor-routed-json-request.ts +10 -2
- package/src/runtime/actors/index.ts +19 -5
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
- package/src/runtime/admission.ts +18 -5
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
- package/src/runtime/application-jobs/application-job-queue-scope.ts +51 -22
- package/src/runtime/application-jobs/contracts.ts +14 -1
- package/src/runtime/backend/contracts/index.ts +53 -14
- package/src/runtime/backend/mesh-completion-table.ts +156 -57
- package/src/runtime/backend/mesh-dispatch-pump.ts +40 -10
- package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +57 -30
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +128 -65
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +21 -6
- package/src/runtime/backend/raw-binding-port.ts +7 -2
- package/src/runtime/backend/runtime-message.ts +6 -0
- package/src/runtime/backend/runtime-values.ts +1 -0
- package/src/runtime/channels/channel-clients.ts +90 -41
- package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
- package/src/runtime/channels/channel-dispatch-services.ts +69 -1
- package/src/runtime/channels/channel-dispatchers.ts +29 -27
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
- package/src/runtime/channels/channel-envelope.ts +133 -8
- package/src/runtime/channels/channel-outbound-operations.ts +22 -8
- package/src/runtime/channels/channel-runtime-manager.ts +29 -12
- package/src/runtime/channels/channel-transports.ts +128 -60
- package/src/runtime/channels/local-spot-route-transport.ts +3 -1
- package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
- package/src/runtime/channels/source-spot-router.ts +8 -4
- package/src/runtime/channels/spot-node-route-transport.ts +8 -4
- package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
- package/src/runtime/execution/serial-execution-queue.ts +2 -0
- package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
- package/src/runtime/foundation/durable-service-request.ts +137 -0
- package/src/runtime/foundation/operation-identity.ts +5 -1
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +484 -293
- package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
- package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
- package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
- package/src/runtime/foundation/service-stateful-runtime.ts +67 -125
- package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -5
- package/src/runtime/foundation/service-topology-registry.ts +91 -36
- package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
- package/src/runtime/handlers/handler-instance-scope.ts +67 -16
- package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
- package/src/runtime/host/application-job-queue.ts +175 -41
- package/src/runtime/host/entry-actor-runtime.ts +4 -0
- package/src/runtime/host/index.ts +201 -156
- package/src/runtime/host/remote-bound-session-relay.ts +2 -23
- package/src/runtime/host/route-mesh-runtime.ts +1 -1
- package/src/runtime/host/service-relocation-control.ts +11 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +315 -291
- package/src/runtime/host/spot-address-transport.ts +4 -2
- package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
- package/src/runtime/locations/actor-location-claims.ts +52 -30
- package/src/runtime/locations/lifecycle.ts +8 -26
- package/src/runtime/locations/runtime.ts +28 -24
- package/src/runtime/messaging/framework-json-v1.ts +5 -325
- package/src/runtime/messaging/packet-name.ts +5 -25
- package/src/runtime/messaging/request-result.ts +58 -0
- package/src/runtime/messaging/submission-result.ts +5 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +43 -23
- package/src/runtime/spots/index.ts +14 -2
- package/src/runtime/spots/spot-activation.ts +28 -10
- package/src/runtime/spots/spot-entry-activation.ts +9 -2
- package/src/runtime/spots/spot-handler-registry.ts +41 -8
- package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
- package/src/runtime/spots/spot-outbound.ts +36 -16
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
- package/src/runtime/spots/spot-runtime-ports.ts +1 -0
- package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
- package/src/runtime/spots/spot-timer.ts +5 -1
- package/src/runtime/streams/stream-session-runtime.ts +12 -29
|
@@ -106,7 +106,7 @@ export class ZLinkEntrySpotActivation {
|
|
|
106
106
|
private readonly spotSerialExecutor: ZLinkSpotSerialExecutor;
|
|
107
107
|
private readonly timers: ZLinkSpotTimerRegistry;
|
|
108
108
|
private readonly actorHandlers = new ZLinkSpotActorHandlerRegistryRuntime();
|
|
109
|
-
private readonly handlers
|
|
109
|
+
private readonly handlers: DefaultZLinkSpotHandlerRegistry;
|
|
110
110
|
private readonly outbound: DefaultZLinkSpotOutbound;
|
|
111
111
|
private readonly workerRuntime: ZLinkWorkerRuntime;
|
|
112
112
|
private readonly lifecycleMetrics: ZLinkSpotLifecycleMetrics;
|
|
@@ -125,6 +125,10 @@ export class ZLinkEntrySpotActivation {
|
|
|
125
125
|
'Entry Spot activation requires a detached task runner.'
|
|
126
126
|
);
|
|
127
127
|
}
|
|
128
|
+
this.handlers = new DefaultZLinkSpotHandlerRegistry(
|
|
129
|
+
this.actorHandlers,
|
|
130
|
+
options.providerResolver
|
|
131
|
+
);
|
|
128
132
|
this.serial = new ZLinkSpotSerialTurnExecutor(false, options.nativeSpot.routingId);
|
|
129
133
|
this.spotSerialExecutor = new ZLinkSpotSerialExecutor(
|
|
130
134
|
this.serial,
|
|
@@ -328,7 +332,10 @@ export class ZLinkEntrySpotActivation {
|
|
|
328
332
|
await cleanup(() => this.timers.dispose());
|
|
329
333
|
await cleanup(() => this.spotSerialExecutor.close());
|
|
330
334
|
await cleanup(() => disposeLifecycleHandlers(this.entrySpot, this.options.detachedTaskRunner));
|
|
331
|
-
await cleanup(() =>
|
|
335
|
+
await cleanup(async () => {
|
|
336
|
+
await this.options.entryActorRuntime?.releaseMembers?.(this.options.spotNodeName);
|
|
337
|
+
await this.options.nativeSpot.dispose();
|
|
338
|
+
});
|
|
332
339
|
if (this.initialized) {
|
|
333
340
|
this.lifecycleMetrics.closed('entry');
|
|
334
341
|
}
|
|
@@ -16,7 +16,12 @@ import type {
|
|
|
16
16
|
ZLinkSpotPacketHandlerRegistration,
|
|
17
17
|
ZLinkSpotSubscriptionHandlerRegistration
|
|
18
18
|
} from '../../contracts/Configuration/RegistrationTypes';
|
|
19
|
-
import {
|
|
19
|
+
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
20
|
+
import { prepareHandlerInstance } from '../handlers/handler-instance-scope';
|
|
21
|
+
import {
|
|
22
|
+
ZLinkFrameworkInternalErrorKind,
|
|
23
|
+
createInternalFrameworkException
|
|
24
|
+
} from '../framework-errors-internal';
|
|
20
25
|
import { ZLinkActorPacketKind, ZLinkSpotActorHandlerRegistryRuntime } from '../actors';
|
|
21
26
|
import { readZLinkDecoratorMetadata } from '../../contracts/Handlers/Attributes';
|
|
22
27
|
|
|
@@ -34,7 +39,10 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
34
39
|
> implements ZLinkSpotHandlerRegistry {
|
|
35
40
|
private readonly entries: ZLinkSpotHandlerRegistration[] = [];
|
|
36
41
|
|
|
37
|
-
constructor(
|
|
42
|
+
constructor(
|
|
43
|
+
private readonly actorHandlers?: ZLinkSpotActorHandlerRegistryRuntime,
|
|
44
|
+
private readonly providerResolver?: ZLinkProviderResolver
|
|
45
|
+
) {}
|
|
38
46
|
|
|
39
47
|
addHandler<THandler>(handlerType: Type<THandler>, packetName?: string): this {
|
|
40
48
|
const metadata = readZLinkDecoratorMetadata(handlerType).find(
|
|
@@ -42,7 +50,8 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
42
50
|
);
|
|
43
51
|
const resolvedPacketName = packetName ?? metadata?.packetName;
|
|
44
52
|
if (metadata === undefined || resolvedPacketName === undefined) {
|
|
45
|
-
throw
|
|
53
|
+
throw createInternalFrameworkException(
|
|
54
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
46
55
|
`Actor packet handler '${handlerType.name}' must declare a packet name.`
|
|
47
56
|
);
|
|
48
57
|
}
|
|
@@ -62,7 +71,8 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
62
71
|
(entry) => entry.kind === 'spotActorSend' || entry.kind === 'spotActorRequest'
|
|
63
72
|
);
|
|
64
73
|
if (metadata?.packetName === undefined) {
|
|
65
|
-
throw
|
|
74
|
+
throw createInternalFrameworkException(
|
|
75
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
66
76
|
`Actor packet handler '${handlerType.name}' must declare a packet name.`
|
|
67
77
|
);
|
|
68
78
|
}
|
|
@@ -78,10 +88,21 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
78
88
|
const declared = readZLinkDecoratorMetadata(handlerType).find(
|
|
79
89
|
(entry) => entry.kind === 'packet'
|
|
80
90
|
)?.packetName;
|
|
91
|
+
prepareHandlerInstance(this.providerResolver, handlerType);
|
|
92
|
+
const resolvedPacketName = packetName ?? declared ?? handlerType.name;
|
|
93
|
+
if (
|
|
94
|
+
this.entries.some(
|
|
95
|
+
(entry) => entry.kind === 'packet' && entry.packetName === resolvedPacketName
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
throw createInternalFrameworkException(
|
|
99
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
100
|
+
`SPOT packet '${resolvedPacketName}' is already registered.`
|
|
101
|
+
);
|
|
81
102
|
this.entries.push({
|
|
82
103
|
kind: 'packet',
|
|
83
104
|
handlerType,
|
|
84
|
-
packetName:
|
|
105
|
+
packetName: resolvedPacketName
|
|
85
106
|
});
|
|
86
107
|
return this;
|
|
87
108
|
}
|
|
@@ -96,6 +117,7 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
96
117
|
actorType: Type<TActor>,
|
|
97
118
|
packetName: string
|
|
98
119
|
): this {
|
|
120
|
+
prepareHandlerInstance(this.providerResolver, handlerType);
|
|
99
121
|
this.entries.push({
|
|
100
122
|
kind: kind === ZLinkActorPacketKind.Send ? 'actorSend' : 'actorRequest',
|
|
101
123
|
handlerType,
|
|
@@ -139,10 +161,16 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
139
161
|
|
|
140
162
|
addSubscribe(handlerType: Type, channelName: string, topic: string): this {
|
|
141
163
|
if (channelName.trim().length === 0) {
|
|
142
|
-
throw
|
|
164
|
+
throw createInternalFrameworkException(
|
|
165
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
166
|
+
'SPOT subscribe channel name must not be empty.'
|
|
167
|
+
);
|
|
143
168
|
}
|
|
144
169
|
if (topic.trim().length === 0) {
|
|
145
|
-
throw
|
|
170
|
+
throw createInternalFrameworkException(
|
|
171
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
172
|
+
'SPOT subscribe topic must not be empty.'
|
|
173
|
+
);
|
|
146
174
|
}
|
|
147
175
|
if (
|
|
148
176
|
this.entries.some(
|
|
@@ -153,8 +181,12 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
153
181
|
entry.topic === topic
|
|
154
182
|
)
|
|
155
183
|
) {
|
|
156
|
-
|
|
184
|
+
throw createInternalFrameworkException(
|
|
185
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
186
|
+
`SPOT subscription '${channelName}/${topic}' is already registered.`
|
|
187
|
+
);
|
|
157
188
|
}
|
|
189
|
+
prepareHandlerInstance(this.providerResolver, handlerType);
|
|
158
190
|
this.entries.push({ kind: 'subscribe', handlerType, channelName, topic });
|
|
159
191
|
return this;
|
|
160
192
|
}
|
|
@@ -164,6 +196,7 @@ export class DefaultZLinkSpotHandlerRegistry<
|
|
|
164
196
|
}
|
|
165
197
|
|
|
166
198
|
addSpotHandler(handlerType: Type): this {
|
|
199
|
+
prepareHandlerInstance(this.providerResolver, handlerType);
|
|
167
200
|
this.entries.push({ kind: 'spotHandler', handlerType });
|
|
168
201
|
return this;
|
|
169
202
|
}
|
|
@@ -164,15 +164,19 @@ class ZLinkSpotNodeAutoConnectExecutor implements IZLinkAutoConnectExecutor {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
async connect(target: ZLinkAutoConnectTarget): Promise<boolean> {
|
|
167
|
-
if (this.manualConnections) return false;
|
|
168
167
|
const key = connectionKey(target);
|
|
168
|
+
if (
|
|
169
|
+
!this.connectionIntents.has(key) &&
|
|
170
|
+
this.node.hasPeerRouteOrConnectionIntent?.(target.nodeRid, target.endpoint) === true
|
|
171
|
+
)
|
|
172
|
+
return false;
|
|
169
173
|
const intent = await this.lane.run(() => this.prepareConnectCore(key));
|
|
170
174
|
if (intent === undefined) return true;
|
|
171
175
|
return await runDetachedSpotNodeAutoConnect(() => this.connectPeer(target, key, intent));
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
disconnect(target: ZLinkAutoConnectTarget): void {
|
|
175
|
-
if (this.
|
|
179
|
+
if (!this.connectionIntents.has(connectionKey(target))) return;
|
|
176
180
|
this.disconnectPeer(target);
|
|
177
181
|
}
|
|
178
182
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createZLinkRequest } from '../messaging/request-result';
|
|
1
2
|
import {
|
|
2
3
|
type RoutingId,
|
|
3
4
|
type ZLinkChannelClient,
|
|
@@ -174,6 +175,7 @@ export class DefaultZLinkSpotOutbound implements ZLinkSpotOutbound {
|
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
export interface ZLinkSpotAddressCallOptions {
|
|
178
|
+
readonly onAdmitted?: () => void;
|
|
177
179
|
readonly metadata?: ReadonlyMap<string, string>;
|
|
178
180
|
readonly instanceSpot: boolean;
|
|
179
181
|
readonly instanceSpotType?: string;
|
|
@@ -232,6 +234,7 @@ export interface ZLinkSpotRoutedSendOptions {
|
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
export interface ZLinkSpotRoutedRequestOptions extends ZLinkSpotRoutedSendOptions {
|
|
237
|
+
readonly onAdmitted?: () => void;
|
|
235
238
|
readonly timeoutMs?: number;
|
|
236
239
|
readonly signal?: AbortSignal;
|
|
237
240
|
}
|
|
@@ -308,14 +311,13 @@ function createAddressedSpotRequestCall(
|
|
|
308
311
|
sourceSpotProvider?: () => ZLinkBackendSpot | undefined
|
|
309
312
|
): ZLinkSpotRequestCall {
|
|
310
313
|
const options = newAddressCallOptions();
|
|
311
|
-
const begin = <TReply>(
|
|
312
|
-
markSubmitted(options);
|
|
313
|
-
rejectSameSpotAsyncRequest(serial, spotId, waitPolicy);
|
|
314
|
+
const begin = <TReply>(signal?: AbortSignal, onAdmitted?: () => void) => {
|
|
314
315
|
return startRequestOnSerial<TReply>(serial, () => ({
|
|
315
316
|
pending: transport.requestToSpotAddress<TReply>(spotId, request, {
|
|
316
317
|
...freezeAddressCallOptions(options, sourceSpotProvider?.()),
|
|
317
318
|
timeoutMs: options.timeoutMs,
|
|
318
|
-
signal
|
|
319
|
+
signal,
|
|
320
|
+
onAdmitted
|
|
319
321
|
})
|
|
320
322
|
}));
|
|
321
323
|
};
|
|
@@ -356,12 +358,18 @@ function createAddressedSpotRequestCall(
|
|
|
356
358
|
return this;
|
|
357
359
|
},
|
|
358
360
|
submit<TReply>(signal?: AbortSignal) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
+
markSubmitted(options);
|
|
362
|
+
rejectSameSpotAsyncRequest(serial, spotId, 'async');
|
|
363
|
+
return createZLinkRequest(
|
|
364
|
+
(onAdmitted) => begin<TReply>(signal, onAdmitted),
|
|
365
|
+
(pending) => (serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending))
|
|
366
|
+
);
|
|
361
367
|
},
|
|
362
368
|
yield<TReply>(signal?: AbortSignal) {
|
|
363
369
|
const turn = requireZLinkYieldTurn();
|
|
364
|
-
|
|
370
|
+
markSubmitted(options);
|
|
371
|
+
rejectSameSpotAsyncRequest(serial, spotId, 'yield');
|
|
372
|
+
const pending = begin<TReply>(signal);
|
|
365
373
|
return turn.yieldPromise(pending);
|
|
366
374
|
}
|
|
367
375
|
};
|
|
@@ -475,8 +483,12 @@ function wrapRequestCall(
|
|
|
475
483
|
serial: ZLinkSpotSerialTurnExecutor,
|
|
476
484
|
inner: ZLinkChannelRequestCall
|
|
477
485
|
): ZLinkChannelRequestCall {
|
|
478
|
-
const begin = <TReply>(signal?: AbortSignal) =>
|
|
479
|
-
startRequestOnSerial(serial, () =>
|
|
486
|
+
const begin = <TReply>(signal?: AbortSignal, onAdmitted?: () => void) =>
|
|
487
|
+
startRequestOnSerial(serial, () => {
|
|
488
|
+
const pending = inner.submit<TReply>(signal);
|
|
489
|
+
if (onAdmitted !== undefined) void pending.admitted.then(onAdmitted, () => undefined);
|
|
490
|
+
return { pending };
|
|
491
|
+
});
|
|
480
492
|
return {
|
|
481
493
|
metadata(key: string | ZLinkMessageMetadata, value?: string) {
|
|
482
494
|
if (typeof key === 'string') inner.metadata(key, value!);
|
|
@@ -488,8 +500,10 @@ function wrapRequestCall(
|
|
|
488
500
|
return this;
|
|
489
501
|
},
|
|
490
502
|
submit<TReply>(signal?: AbortSignal) {
|
|
491
|
-
|
|
492
|
-
|
|
503
|
+
return createZLinkRequest(
|
|
504
|
+
(onAdmitted) => begin<TReply>(signal, onAdmitted),
|
|
505
|
+
(pending) => (serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending))
|
|
506
|
+
);
|
|
493
507
|
},
|
|
494
508
|
yield<TReply>(signal?: AbortSignal) {
|
|
495
509
|
const turn = requireZLinkYieldTurn();
|
|
@@ -571,15 +585,15 @@ function wrapRoutedSpotRequestCall(
|
|
|
571
585
|
): ZLinkRequestCall & Pick<ZLinkChannelRequestCall, 'yield'> {
|
|
572
586
|
let selectedTimeoutMs: number | undefined;
|
|
573
587
|
const metadata = new Map<string, string>();
|
|
574
|
-
const begin = <TReply>(
|
|
588
|
+
const begin = <TReply>(signal?: AbortSignal, onAdmitted?: () => void) => {
|
|
575
589
|
// A request to the current Spot would wait behind the handler that owns
|
|
576
590
|
// the same Spot claim. Reject it before resolving a route or submitting
|
|
577
591
|
// transport work; one-way self-send remains a valid FIFO admission.
|
|
578
|
-
rejectSameSpotAsyncRequest(serial, spot.spotId, waitPolicy);
|
|
579
592
|
return startRequestOnSerial<TReply>(serial, () => ({
|
|
580
593
|
pending: requestToSpotHandle<TReply>(transport, spot, request, {
|
|
581
594
|
timeoutMs: selectedTimeoutMs,
|
|
582
595
|
signal,
|
|
596
|
+
onAdmitted,
|
|
583
597
|
metadata,
|
|
584
598
|
spotRouterChannelIdForMesh,
|
|
585
599
|
sourceSpot: sourceSpotProvider?.()
|
|
@@ -602,12 +616,16 @@ function wrapRoutedSpotRequestCall(
|
|
|
602
616
|
return this;
|
|
603
617
|
},
|
|
604
618
|
submit<TReply>(signal?: AbortSignal) {
|
|
605
|
-
|
|
606
|
-
return
|
|
619
|
+
rejectSameSpotAsyncRequest(serial, spot.spotId, 'async');
|
|
620
|
+
return createZLinkRequest(
|
|
621
|
+
(onAdmitted) => begin<TReply>(signal, onAdmitted),
|
|
622
|
+
(pending) => (serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending))
|
|
623
|
+
);
|
|
607
624
|
},
|
|
608
625
|
yield<TReply>(signal?: AbortSignal) {
|
|
609
626
|
const turn = requireZLinkYieldTurn();
|
|
610
|
-
|
|
627
|
+
rejectSameSpotAsyncRequest(serial, spot.spotId, 'yield');
|
|
628
|
+
const pending = begin<TReply>(signal);
|
|
611
629
|
return turn.yieldPromise(pending);
|
|
612
630
|
}
|
|
613
631
|
};
|
|
@@ -628,6 +646,7 @@ function rejectSameSpotAsyncRequest(
|
|
|
628
646
|
}
|
|
629
647
|
|
|
630
648
|
export interface ZLinkSpotHandleCallOptions {
|
|
649
|
+
readonly onAdmitted?: () => void;
|
|
631
650
|
readonly metadata?: ReadonlyMap<string, string>;
|
|
632
651
|
readonly timeoutMs?: number;
|
|
633
652
|
readonly signal?: AbortSignal;
|
|
@@ -672,6 +691,7 @@ export async function requestToSpotHandle<TReply = unknown>(
|
|
|
672
691
|
packetName,
|
|
673
692
|
timeoutMs: options.timeoutMs,
|
|
674
693
|
signal: options.signal,
|
|
694
|
+
onAdmitted: options.onAdmitted,
|
|
675
695
|
metadata: options.metadata
|
|
676
696
|
};
|
|
677
697
|
if (options.sourceSpot !== undefined && transport.requestFromSpotToSpot !== undefined) {
|
|
@@ -50,6 +50,7 @@ interface ZLinkRoutedSpotPacketDispatchOptions {
|
|
|
50
50
|
|
|
51
51
|
interface ZLinkRoutedSpotPacketContext {
|
|
52
52
|
readonly channelName: string;
|
|
53
|
+
readonly onAdmitted?: () => void;
|
|
53
54
|
readonly contentType?: string;
|
|
54
55
|
readonly workOptions?: ZLinkSerialWorkOptions;
|
|
55
56
|
readonly admissionTimeoutMs?: number;
|
|
@@ -265,7 +266,7 @@ export class ZLinkRoutedSpotPacketDispatch {
|
|
|
265
266
|
}
|
|
266
267
|
await activation.serial.execute(
|
|
267
268
|
runHandler,
|
|
268
|
-
context.workOptions,
|
|
269
|
+
{ ...context.workOptions, onAdmitted: context.onAdmitted },
|
|
269
270
|
instanceIntent ? runHandler : undefined
|
|
270
271
|
);
|
|
271
272
|
}
|
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
import type { ZLinkBackendSpotNode } from '../backend/contracts';
|
|
23
23
|
|
|
24
24
|
export interface ZLinkEntryActorRuntime {
|
|
25
|
+
releaseMembers?(meshName: string): Promise<void>;
|
|
25
26
|
resolveActor(actorId: string): ZLinkActor | undefined;
|
|
26
27
|
commitActorTransaction(actor: ZLinkActor, onJoined: () => Promise<void>): Promise<void>;
|
|
27
28
|
destroyActor(
|
|
@@ -68,9 +68,6 @@ export class ZLinkSpotSubscriptionDispatch {
|
|
|
68
68
|
}
|
|
69
69
|
const key = subscriptionKey(registration.channelName, registration.topic);
|
|
70
70
|
const existing = this.handlers.get(key) ?? [];
|
|
71
|
-
if (existing.some((entry) => entry.handlerType === registration.handlerType)) {
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
71
|
existing.push(registration);
|
|
75
72
|
this.handlers.set(key, existing);
|
|
76
73
|
this.options.nativeSpot.setSubscription(registration.channelName, registration.topic);
|
|
@@ -19,7 +19,10 @@ import { ZLinkTimerOverrunPolicy } from '../../contracts';
|
|
|
19
19
|
import { validateTimerRegistration } from '../../contracts/Configuration/TimerRegistrationValidator';
|
|
20
20
|
import { throwIfAborted } from '../abort';
|
|
21
21
|
import { ZLinkSpotSerialTurnExecutor } from './spot-serial-turn-executor';
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
prepareHandlerInstance,
|
|
24
|
+
resolveLifecycleHandler
|
|
25
|
+
} from '../handlers/handler-instance-scope';
|
|
23
26
|
import { createInboundFlow, runWithFlow } from '../diagnostics/flow-context';
|
|
24
27
|
import type { ZLinkExecutionBarrier } from '../execution';
|
|
25
28
|
import { ZLinkStateLane } from '../execution/state-lane';
|
|
@@ -135,6 +138,7 @@ export class ZLinkSpotTimerRegistry {
|
|
|
135
138
|
): Promise<ZLinkTimer> {
|
|
136
139
|
validateTimerRegistration(name, periodMs, options);
|
|
137
140
|
throwIfAborted(signal);
|
|
141
|
+
prepareHandlerInstance(providerResolver, handlerType);
|
|
138
142
|
const handler = await resolveLifecycleHandler(spot, handlerType, providerResolver);
|
|
139
143
|
const prepared = await this.lane.run(() => this.prepareAddCore(name));
|
|
140
144
|
if (prepared.previous !== undefined) await prepared.previous.timer.cancel(signal);
|
|
@@ -95,29 +95,6 @@ const systemLivenessClock: ZLinkStreamLivenessClock = {
|
|
|
95
95
|
clearTimer: (timer) => clearTimeout(timer as ReturnType<typeof setTimeout>)
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
class ZLinkStreamReceiveWake {
|
|
99
|
-
private pending?: Promise<void>;
|
|
100
|
-
private resolvePending?: () => void;
|
|
101
|
-
private readonly finish = (): void => {
|
|
102
|
-
const resolve = this.resolvePending;
|
|
103
|
-
this.pending = undefined;
|
|
104
|
-
this.resolvePending = undefined;
|
|
105
|
-
resolve?.();
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
wait(): Promise<void> {
|
|
109
|
-
if (this.pending !== undefined) return this.pending;
|
|
110
|
-
this.pending = new Promise<void>((resolve) => {
|
|
111
|
-
this.resolvePending = resolve;
|
|
112
|
-
});
|
|
113
|
-
return this.pending;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
wake(): void {
|
|
117
|
-
this.finish();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
98
|
export interface ZLinkStreamSessionContextFactory {
|
|
122
99
|
createSessionContext(
|
|
123
100
|
stream: ZLinkManagedStream,
|
|
@@ -928,7 +905,7 @@ export class ZLinkStreamSessionNodeRuntime {
|
|
|
928
905
|
private readonly receiveAbortController = new AbortController();
|
|
929
906
|
private receiveLoop: Promise<void> | undefined;
|
|
930
907
|
private monitorLoop: Promise<void> | undefined;
|
|
931
|
-
private
|
|
908
|
+
private receiveWake: AbortController | undefined;
|
|
932
909
|
private receiveWorkSinceYield = 0;
|
|
933
910
|
constructor(
|
|
934
911
|
private readonly options: ZLinkStreamSessionNodeRuntimeOptions & ZLinkStreamLivenessOptions
|
|
@@ -1455,14 +1432,20 @@ export class ZLinkStreamSessionNodeRuntime {
|
|
|
1455
1432
|
}
|
|
1456
1433
|
|
|
1457
1434
|
private async waitReceiveLoopWake(signal: AbortSignal): Promise<void> {
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1435
|
+
const wake = new AbortController();
|
|
1436
|
+
this.receiveWake = wake;
|
|
1437
|
+
try {
|
|
1438
|
+
// Readiness, internal wake and shutdown share one cancellable wait;
|
|
1439
|
+
// no losing Promise retains reactions across receive cycles.
|
|
1440
|
+
await this.options.readablePoller.waitForReadable(AbortSignal.any([signal, wake.signal]));
|
|
1441
|
+
} finally {
|
|
1442
|
+
wake.abort();
|
|
1443
|
+
this.receiveWake = undefined;
|
|
1444
|
+
}
|
|
1462
1445
|
}
|
|
1463
1446
|
|
|
1464
1447
|
private wakeReceiveLoop(): void {
|
|
1465
|
-
this.receiveWake
|
|
1448
|
+
this.receiveWake?.abort();
|
|
1466
1449
|
}
|
|
1467
1450
|
|
|
1468
1451
|
private getOrCreateSession(routingId: unknown): ZLinkStreamSessionRuntime | undefined {
|