@zlink-systems/framework 0.29.1 → 0.30.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/Configuration/Builders.d.ts +1 -2
- package/dist/contracts/Configuration/Configs.d.ts +0 -5
- package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
- package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
- package/dist/contracts/Configuration/index.d.ts +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +3 -1
- package/dist/runtime/actors/actor-handoff.d.ts +3 -2
- package/dist/runtime/actors/actor-handoff.js +9 -4
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +3 -1
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
- package/dist/runtime/application-jobs/contracts.d.ts +5 -1
- package/dist/runtime/backend/contracts/index.d.ts +10 -19
- package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
- package/dist/runtime/backend/mesh-completion-table.js +28 -18
- package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
- package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
- package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
- package/dist/runtime/channels/channel-receive-loops.js +3 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
- package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
- package/dist/runtime/channels/channel-socket-registry.js +59 -82
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow.js +3 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
- package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
- package/dist/runtime/foundation/service-liveness-registry.js +57 -44
- package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
- package/dist/runtime/foundation/service-mailbox.js +2 -1
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +34 -23
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
- package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
- package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
- package/dist/runtime/foundation/service-topology-registry.js +9 -4
- package/dist/runtime/host/actor-packet-relay.js +7 -7
- package/dist/runtime/host/actor-runtime-options-factory.js +1 -1
- package/dist/runtime/host/application-job-queue.d.ts +11 -4
- package/dist/runtime/host/application-job-queue.js +66 -10
- package/dist/runtime/host/entry-actor-runtime.js +1 -1
- package/dist/runtime/host/index.js +15 -11
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
- package/dist/runtime/host/instance-activation-authority.js +89 -25
- package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
- package/dist/runtime/host/spot-address-transport.d.ts +1 -0
- package/dist/runtime/host/spot-address-transport.js +25 -12
- package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
- package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
- package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
- package/dist/runtime/locations/in-memory-authority-store.js +80 -8
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +19 -3
- package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
- package/dist/runtime/locations/location-store-repository.d.ts +3 -2
- package/dist/runtime/locations/location-store-repository.js +165 -22
- package/dist/runtime/locations/resolvers.d.ts +2 -1
- package/dist/runtime/locations/resolvers.js +10 -1
- package/dist/runtime/messaging/submission-result.d.ts +1 -1
- package/dist/runtime/messaging/submission-result.js +2 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
- package/dist/runtime/spots/index.d.ts +4 -3
- package/dist/runtime/spots/index.js +14 -14
- package/dist/runtime/spots/spot-activation.d.ts +2 -1
- package/dist/runtime/spots/spot-activation.js +4 -4
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
- package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
- package/dist/runtime/spots/spot-entry-activation.js +3 -1
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
- package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
- package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
- package/dist/runtime/streams/stream-session-runtime.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Configuration/Builders.ts +1 -2
- package/src/contracts/Configuration/Configs.ts +0 -6
- package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
- package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
- package/src/contracts/Configuration/index.ts +1 -6
- package/src/internal.ts +1 -0
- package/src/runtime/actors/actor-handoff.ts +13 -4
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
- package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
- package/src/runtime/application-jobs/contracts.ts +14 -1
- package/src/runtime/backend/contracts/index.ts +10 -18
- package/src/runtime/backend/mesh-completion-table.ts +36 -19
- package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
- package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
- package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
- package/src/runtime/backend/raw-binding-port.ts +12 -2
- package/src/runtime/channels/channel-receive-loops.ts +3 -3
- package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
- package/src/runtime/channels/channel-socket-registry.ts +84 -130
- package/src/runtime/diagnostics/message-flow.ts +1 -1
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
- package/src/runtime/foundation/service-liveness-registry.ts +68 -59
- package/src/runtime/foundation/service-mailbox.ts +7 -1
- package/src/runtime/foundation/service-stateful-runtime.ts +61 -35
- package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
- package/src/runtime/foundation/service-topology-registry.ts +13 -7
- package/src/runtime/host/actor-packet-relay.ts +7 -0
- package/src/runtime/host/actor-runtime-options-factory.ts +1 -0
- package/src/runtime/host/application-job-queue.ts +77 -10
- package/src/runtime/host/entry-actor-runtime.ts +1 -0
- package/src/runtime/host/index.ts +24 -5
- package/src/runtime/host/instance-activation-authority.ts +132 -27
- package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
- package/src/runtime/host/spot-address-transport.ts +45 -22
- package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
- package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
- package/src/runtime/locations/domain-store-contract.ts +6 -2
- package/src/runtime/locations/in-memory-authority-store.ts +113 -9
- package/src/runtime/locations/in-memory-location-store.ts +25 -3
- package/src/runtime/locations/internal-location-contracts.ts +4 -0
- package/src/runtime/locations/location-store-repository.ts +220 -15
- package/src/runtime/locations/resolvers.ts +25 -2
- package/src/runtime/messaging/submission-result.ts +2 -2
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
- package/src/runtime/spots/index.ts +16 -0
- package/src/runtime/spots/spot-activation.ts +5 -0
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
- package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
- package/src/runtime/spots/spot-entry-activation.ts +3 -0
- package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
- package/src/runtime/spots/spot-routing-internal.ts +14 -0
- package/src/runtime/spots/spot-runtime-ports.ts +2 -0
- package/src/runtime/streams/stream-session-runtime.ts +1 -1
|
@@ -7,7 +7,6 @@ import type { ZLinkDispatchOptionsBuilder, ZLinkInboundDispatchOptions } from '.
|
|
|
7
7
|
import type { ZLinkLocationOptions, ZLinkLocationStore, ZLinkRelocationStore } from '../Locations';
|
|
8
8
|
import type { RoutingId, Type } from '../Common';
|
|
9
9
|
import type { ZLinkWorkerOptions } from './RegistrationTypes';
|
|
10
|
-
import type { ZLinkSpotPublisherConfig } from './Configs';
|
|
11
10
|
import type {
|
|
12
11
|
ZLinkActorFactoryBuilder,
|
|
13
12
|
ZLinkInstanceSpotFactoryBuilder,
|
|
@@ -120,7 +119,6 @@ export interface ZLinkMeshNodeBuilder {
|
|
|
120
119
|
setActivationConcurrency(limit: number): this;
|
|
121
120
|
setInstanceSpotIdleTimeout(timeoutMs: number): this;
|
|
122
121
|
configureRouterSocket(): ZLinkMeshNodeSocketConfig;
|
|
123
|
-
configureSpotPublisher(): ZLinkSpotPublisherConfig;
|
|
124
122
|
peerConnections(): ZLinkMeshPeerConnections;
|
|
125
123
|
setDefaultRequestTimeout(timeoutMs: number): this;
|
|
126
124
|
objects(): ZLinkMeshObjectRoleBuilder;
|
|
@@ -180,6 +178,7 @@ export interface ZLinkFanoutChannelBuilder {
|
|
|
180
178
|
routingId(routingId: string): this;
|
|
181
179
|
setRoutingIdPrefix(prefix: string): this;
|
|
182
180
|
setNoDrop(noDrop?: boolean): this;
|
|
181
|
+
setSendTimeout(timeoutMs: number): this;
|
|
183
182
|
enableSubscriber(): this;
|
|
184
183
|
subscribe(topic: string): this;
|
|
185
184
|
connect(endpoint: string): this;
|
|
@@ -27,7 +27,6 @@ import type {
|
|
|
27
27
|
ZLinkSession,
|
|
28
28
|
ZLinkSessionFactory,
|
|
29
29
|
ZLinkSpot,
|
|
30
|
-
ZLinkSpotPublisherConfig,
|
|
31
30
|
ZLinkStreamCompressionBuilder,
|
|
32
31
|
ZLinkStreamCompressionCodec,
|
|
33
32
|
ZLinkStreamNodeBuilder,
|
|
@@ -53,6 +52,7 @@ import type { ZLinkEndpointConnections } from './Connections';
|
|
|
53
52
|
import { requireMessageFlowLogMode, requireTraceSampleRate } from './DiagnosticsValidation';
|
|
54
53
|
import { normalizeEndpoint } from './EndpointNotation';
|
|
55
54
|
import { requirePublicFanoutTopic } from './FanoutTopic';
|
|
55
|
+
import { requireValidSendTimeoutMs } from './SendTimeoutValidation';
|
|
56
56
|
import { DEFAULT_STREAM_NODE_MAX_MESSAGE_SIZE } from './InternalDefaults';
|
|
57
57
|
import {
|
|
58
58
|
type ZLinkActorFactoryBuilder,
|
|
@@ -519,6 +519,12 @@ class DefaultFanoutChannelBuilder implements ZLinkFanoutChannelBuilder {
|
|
|
519
519
|
return this;
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
+
setSendTimeout(timeoutMs: number): this {
|
|
523
|
+
requireValidSendTimeoutMs(`Fanout channel '${this.name}' send timeout`, timeoutMs);
|
|
524
|
+
this.channel.sendTimeoutMs = timeoutMs;
|
|
525
|
+
return this;
|
|
526
|
+
}
|
|
527
|
+
|
|
522
528
|
enableSubscriber(endpoint?: string): this {
|
|
523
529
|
this.selectSubscriberMode(endpoint === undefined ? 'automatic' : 'manual');
|
|
524
530
|
this.channel.subscriber ??= { manualConnections: [] };
|
|
@@ -984,11 +990,6 @@ class DefaultMeshNodeBuilder implements ZLinkMeshNodeBuilder {
|
|
|
984
990
|
return this.node.router as ZLinkMeshNodeSocketConfig;
|
|
985
991
|
}
|
|
986
992
|
|
|
987
|
-
configureSpotPublisher(): ZLinkSpotPublisherConfig {
|
|
988
|
-
this.node.publisherConfig ??= {};
|
|
989
|
-
return this.node.publisherConfig as ZLinkSpotPublisherConfig;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
993
|
peerConnections(): ZLinkMeshPeerConnections {
|
|
993
994
|
this.node.router ??= {};
|
|
994
995
|
return new DefaultMeshPeerConnections(this.node.router);
|
|
@@ -1576,6 +1577,7 @@ interface MutableChannelOptions {
|
|
|
1576
1577
|
routingId?: string;
|
|
1577
1578
|
routingIdPrefix?: string;
|
|
1578
1579
|
noDrop?: boolean;
|
|
1580
|
+
sendTimeoutMs?: number;
|
|
1579
1581
|
publisher?: MutablePublisherCapabilityOptions;
|
|
1580
1582
|
publishHandlers?: ZLinkChannelPublishHandlerRegistration[];
|
|
1581
1583
|
subscriptions?: string[];
|
|
@@ -1607,7 +1609,6 @@ interface MutableClientCapabilityOptions {
|
|
|
1607
1609
|
}
|
|
1608
1610
|
|
|
1609
1611
|
interface MutablePublisherCapabilityOptions {
|
|
1610
|
-
sendTimeoutMs?: number;
|
|
1611
1612
|
bind?: string;
|
|
1612
1613
|
bindHost?: string;
|
|
1613
1614
|
advertiseHost?: string;
|
|
@@ -1668,11 +1669,6 @@ interface MutableSpotNodeOptions {
|
|
|
1668
1669
|
routeSendHandlers?: Array<{ packetName: string; handlerType: Type }>;
|
|
1669
1670
|
routeRequestHandlers?: Array<{ packetName: string; handlerType: Type }>;
|
|
1670
1671
|
requestTimeoutMs?: number;
|
|
1671
|
-
publisherConfig?: {
|
|
1672
|
-
sendHighWaterMark?: number;
|
|
1673
|
-
sendTimeoutMs?: number;
|
|
1674
|
-
lingerMs?: number;
|
|
1675
|
-
};
|
|
1676
1672
|
}
|
|
1677
1673
|
|
|
1678
1674
|
interface MutableObjectFactoryRegistration<T, TImplementation = T, TOptions = unknown> {
|
|
@@ -166,6 +166,7 @@ export interface ZLinkChannelOptions {
|
|
|
166
166
|
readonly routingId?: string;
|
|
167
167
|
readonly routingIdPrefix?: string;
|
|
168
168
|
readonly noDrop?: boolean;
|
|
169
|
+
readonly sendTimeoutMs?: number;
|
|
169
170
|
readonly requestTimeoutMs?: number;
|
|
170
171
|
readonly client?: ZLinkClientCapabilityOptions;
|
|
171
172
|
readonly publisher?: ZLinkPublisherCapabilityOptions;
|
|
@@ -196,7 +197,6 @@ export interface ZLinkClientCapabilityOptions {
|
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
export interface ZLinkPublisherCapabilityOptions {
|
|
199
|
-
readonly sendTimeoutMs?: number;
|
|
200
200
|
readonly bind?: string;
|
|
201
201
|
readonly bindHost?: string;
|
|
202
202
|
readonly advertiseHost?: string;
|
|
@@ -297,11 +297,6 @@ export interface ZLinkSpotNodeOptions {
|
|
|
297
297
|
readonly routeSendHandlers?: readonly ZLinkRouteMeshSendHandlerRegistration[];
|
|
298
298
|
readonly routeRequestHandlers?: readonly ZLinkRouteMeshRequestHandlerRegistration[];
|
|
299
299
|
readonly requestTimeoutMs?: number;
|
|
300
|
-
readonly publisherConfig?: {
|
|
301
|
-
readonly sendHighWaterMark?: number;
|
|
302
|
-
readonly sendTimeoutMs?: number;
|
|
303
|
-
readonly lingerMs?: number;
|
|
304
|
-
};
|
|
305
300
|
readonly entrySpotTimerHandlers?: readonly ZLinkEntrySpotTimerHandlerRegistration[];
|
|
306
301
|
readonly entrySpotPacketHandlers?: readonly ZLinkEntrySpotPacketHandlerRegistration[];
|
|
307
302
|
readonly entrySpotSubscriptionHandlers?: readonly ZLinkEntrySpotSubscriptionHandlerRegistration[];
|
|
@@ -217,9 +217,12 @@ function validateChannelCapabilities(
|
|
|
217
217
|
if (channel.noDrop !== undefined && typeof channel.noDrop !== 'boolean') {
|
|
218
218
|
throw new ZLinkConfigurationException(`Channel '${channelName}' NoDrop must be a boolean.`);
|
|
219
219
|
}
|
|
220
|
-
if (
|
|
220
|
+
if (
|
|
221
|
+
(channel.noDrop !== undefined || channel.sendTimeoutMs !== undefined) &&
|
|
222
|
+
channel.publisher === undefined
|
|
223
|
+
) {
|
|
221
224
|
throw new ZLinkConfigurationException(
|
|
222
|
-
`Channel '${channelName}' NoDrop
|
|
225
|
+
`Channel '${channelName}': NoDrop and send timeout require the publisher role.`
|
|
223
226
|
);
|
|
224
227
|
}
|
|
225
228
|
if (channel.server !== undefined) {
|
|
@@ -235,11 +238,11 @@ function validateChannelCapabilities(
|
|
|
235
238
|
requirePeerWeight(`channel '${channelName}' server weight`, channel.server.weight);
|
|
236
239
|
requireSocketOptions(`channel '${channelName}' server`, channel.server);
|
|
237
240
|
}
|
|
241
|
+
requireValidSendTimeoutMs(
|
|
242
|
+
`channel '${channelName}' publisher sendTimeoutMs`,
|
|
243
|
+
channel.sendTimeoutMs
|
|
244
|
+
);
|
|
238
245
|
if (channel.publisher !== undefined) {
|
|
239
|
-
requireValidSendTimeoutMs(
|
|
240
|
-
`channel '${channelName}' publisher sendTimeoutMs`,
|
|
241
|
-
channel.publisher.sendTimeoutMs
|
|
242
|
-
);
|
|
243
246
|
requireEndpoint(`channel '${channelName}' publisher`, channel.publisher.bind);
|
|
244
247
|
validateListenerNetworkIdentity(
|
|
245
248
|
`channel '${channelName}' publisher`,
|
|
@@ -345,10 +348,6 @@ function validateSpotNodes(registration: ZLinkFrameworkRegistration): void {
|
|
|
345
348
|
`SpotNode '${spotNodeName}' instanceSpotIdleTimeoutMs`,
|
|
346
349
|
spotNode.instanceSpotIdleTimeoutMs
|
|
347
350
|
);
|
|
348
|
-
requireValidSendTimeoutMs(
|
|
349
|
-
`SpotNode '${spotNodeName}' publisher sendTimeoutMs`,
|
|
350
|
-
spotNode.publisherConfig?.sendTimeoutMs
|
|
351
|
-
);
|
|
352
351
|
validateSpotNodeFactories(spotNodeName, spotNode);
|
|
353
352
|
validateSpotNodeTimers(spotNode);
|
|
354
353
|
if (
|
|
@@ -20,12 +20,7 @@ export type {
|
|
|
20
20
|
ZLinkStreamSocketConfig,
|
|
21
21
|
ZLinkStreamNodeBuilder
|
|
22
22
|
} from './Builders';
|
|
23
|
-
export type {
|
|
24
|
-
ZLinkOutboundRouteConfig,
|
|
25
|
-
ZLinkRouteConfig,
|
|
26
|
-
ZLinkSocketConfig,
|
|
27
|
-
ZLinkSpotPublisherConfig
|
|
28
|
-
} from './Configs';
|
|
23
|
+
export type { ZLinkOutboundRouteConfig, ZLinkRouteConfig, ZLinkSocketConfig } from './Configs';
|
|
29
24
|
export * from './Connections';
|
|
30
25
|
export * from './ObjectRoles';
|
|
31
26
|
export type {
|
package/src/internal.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Test and companion-package integration surface. It is not exported by package.json. */
|
|
2
2
|
export * from './index';
|
|
3
|
+
export { requireValidSendTimeoutMs } from './contracts/Configuration/SendTimeoutValidation';
|
|
3
4
|
export * from './runtime/diagnostics';
|
|
4
5
|
export * from './runtime/host';
|
|
5
6
|
export * from './runtime/admission';
|
|
@@ -3,6 +3,7 @@ import { type ActorRef, type RoutingId, ZLinkFrameworkException } from '../../co
|
|
|
3
3
|
import type { Message } from '../../contracts/Common/Message';
|
|
4
4
|
import { zlinkDefaultLocationOptions } from '../../contracts/Locations/Options';
|
|
5
5
|
import { releaseApplicationJobPermitForDurableHandoff } from '../application-jobs/application-job-queue-scope';
|
|
6
|
+
import type { ApplicationJobOrigin } from '../application-jobs/contracts';
|
|
6
7
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
7
8
|
import {
|
|
8
9
|
MessageFollowSuppressionRegistry,
|
|
@@ -108,7 +109,8 @@ export interface ZLinkActorHandoffPreparedReplayAdmission {
|
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
export type ZLinkActorHandoffReplayPreparation = (
|
|
111
|
-
signal: AbortSignal
|
|
112
|
+
signal: AbortSignal,
|
|
113
|
+
origin: ApplicationJobOrigin
|
|
112
114
|
) => Promise<ZLinkActorHandoffPreparedReplayAdmission>;
|
|
113
115
|
|
|
114
116
|
export interface ZLinkActorHandoffPrefixAdmission {
|
|
@@ -137,6 +139,7 @@ export type ZLinkActorHandoffPrefixQueue = (
|
|
|
137
139
|
) => ZLinkActorHandoffPrefixAdmission;
|
|
138
140
|
|
|
139
141
|
interface PendingPacket {
|
|
142
|
+
readonly origin: ApplicationJobOrigin;
|
|
140
143
|
readonly packet: ZLinkActorHandoffPacket;
|
|
141
144
|
readonly resolve?: (value: unknown) => void;
|
|
142
145
|
readonly reject?: (reason: unknown) => void;
|
|
@@ -554,7 +557,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
554
557
|
try {
|
|
555
558
|
await waitForHandoffReplayStart(release.start, signal);
|
|
556
559
|
if (release.preparation !== undefined) {
|
|
557
|
-
const next = await release.preparation(signal);
|
|
560
|
+
const next = await release.preparation(signal, pending.origin);
|
|
558
561
|
if (signal.aborted) {
|
|
559
562
|
next.cancel();
|
|
560
563
|
throw signal.reason;
|
|
@@ -765,6 +768,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
765
768
|
}
|
|
766
769
|
|
|
767
770
|
capture(
|
|
771
|
+
origin: ApplicationJobOrigin,
|
|
768
772
|
actorId: string,
|
|
769
773
|
parts: readonly Message[],
|
|
770
774
|
returnResponse = false,
|
|
@@ -823,7 +827,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
823
827
|
this.reportRequestFrame(actorId, packet);
|
|
824
828
|
}
|
|
825
829
|
if (!returnResponse) {
|
|
826
|
-
handoff.pending.push({ packet });
|
|
830
|
+
handoff.pending.push({ packet, origin });
|
|
827
831
|
// The durable handoff now owns this record. Return the ingress permit
|
|
828
832
|
// before waiting for a later replay, which must acquire its own fresh
|
|
829
833
|
// application-job permit.
|
|
@@ -859,7 +863,12 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
859
863
|
}, RELOCATION_REPLY_RETENTION_MS);
|
|
860
864
|
route.deadline.unref();
|
|
861
865
|
this.replyRoutes.set(source.replyRouteId, route);
|
|
862
|
-
handoff.pending.push({
|
|
866
|
+
handoff.pending.push({
|
|
867
|
+
packet: requestPacket,
|
|
868
|
+
origin,
|
|
869
|
+
resolve,
|
|
870
|
+
reject
|
|
871
|
+
});
|
|
863
872
|
});
|
|
864
873
|
releaseApplicationJobPermitForDurableHandoff();
|
|
865
874
|
if (handoff.prefixRelease !== undefined) {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ApplicationJobOrigin,
|
|
3
|
+
ApplicationJobPermitPort,
|
|
4
|
+
ApplicationJobQueuePort
|
|
5
|
+
} from './contracts';
|
|
2
6
|
|
|
3
7
|
export type ApplicationJobRecordDomain = 'application' | 'infrastructure';
|
|
4
8
|
|
|
@@ -85,6 +89,10 @@ export class ApplicationJobRecordLease implements ApplicationJobPermitPort {
|
|
|
85
89
|
private readonly permit: ApplicationJobPermitPort
|
|
86
90
|
) {}
|
|
87
91
|
|
|
92
|
+
get origin(): ApplicationJobOrigin {
|
|
93
|
+
return this.shared.origin;
|
|
94
|
+
}
|
|
95
|
+
|
|
88
96
|
markApplicationQueued(): void {
|
|
89
97
|
// The owner classifies and marks the child atomically when it is created;
|
|
90
98
|
// downstream dispatch must not mutate queue accounting a second time.
|
|
@@ -132,12 +140,14 @@ class SharedIngressRecordState {
|
|
|
132
140
|
private jobCount = 0;
|
|
133
141
|
private initialPermit?: ApplicationJobPermitPort;
|
|
134
142
|
private recordClosed = false;
|
|
143
|
+
readonly origin: ApplicationJobOrigin;
|
|
135
144
|
|
|
136
145
|
constructor(
|
|
137
146
|
private readonly queue: ApplicationJobQueuePort,
|
|
138
147
|
initialPermit: ApplicationJobPermitPort,
|
|
139
148
|
private readonly record: IngressRecordPort
|
|
140
149
|
) {
|
|
150
|
+
this.origin = initialPermit.origin;
|
|
141
151
|
this.initialPermit = initialPermit;
|
|
142
152
|
}
|
|
143
153
|
|
|
@@ -160,7 +170,7 @@ class SharedIngressRecordState {
|
|
|
160
170
|
}
|
|
161
171
|
|
|
162
172
|
acquirePermit(signal: AbortSignal): Promise<ApplicationJobPermitPort> {
|
|
163
|
-
return this.queue.acquire(signal);
|
|
173
|
+
return this.queue.acquire(signal, this.origin);
|
|
164
174
|
}
|
|
165
175
|
|
|
166
176
|
createJob(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
|
|
3
|
-
import type { ApplicationJobPermitPort } from './contracts';
|
|
3
|
+
import type { ApplicationJobOrigin, ApplicationJobPermitPort } from './contracts';
|
|
4
4
|
|
|
5
5
|
interface ApplicationJobPermitScope {
|
|
6
6
|
readonly permit: ApplicationJobPermitPort;
|
|
@@ -42,6 +42,11 @@ export function hasApplicationJobPermit(): boolean {
|
|
|
42
42
|
return applicationJobPermitScope.getStore() !== undefined;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/** Keeps the ingress origin when a durable record later reacquires its permit. */
|
|
46
|
+
export function currentApplicationJobOrigin(): ApplicationJobOrigin {
|
|
47
|
+
return applicationJobPermitScope.getStore()!.permit.origin;
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
/** Re-enters the captured permit scope when a serial executor runs later. */
|
|
46
51
|
export function bindApplicationJobPermit<TResult, TArgument>(
|
|
47
52
|
callback: (argument?: TArgument) => Promise<TResult> | TResult
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export type ApplicationJobOrigin = 'local' | 'remote';
|
|
2
|
+
|
|
1
3
|
export interface ApplicationJobPermitPort {
|
|
4
|
+
readonly origin: ApplicationJobOrigin;
|
|
2
5
|
markApplicationQueued(): void;
|
|
3
6
|
/** Transfers ingress-record cleanup to a detached exact-target handler turn. */
|
|
4
7
|
detachForHandlerTurn?(): void;
|
|
@@ -7,7 +10,17 @@ export interface ApplicationJobPermitPort {
|
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export interface ApplicationJobQueuePort {
|
|
10
|
-
acquire(
|
|
13
|
+
acquire(
|
|
14
|
+
signal: AbortSignal | undefined,
|
|
15
|
+
origin: ApplicationJobOrigin
|
|
16
|
+
): Promise<ApplicationJobPermitPort>;
|
|
17
|
+
/** Returns a grant now, or registers one FIFO waiter that later calls resume. */
|
|
18
|
+
acquireOrResume(
|
|
19
|
+
resume: (permit: ApplicationJobPermitPort) => void,
|
|
20
|
+
reject: (reason: unknown) => void,
|
|
21
|
+
signal: AbortSignal | undefined,
|
|
22
|
+
origin: ApplicationJobOrigin
|
|
23
|
+
): ApplicationJobPermitPort | undefined;
|
|
11
24
|
registerReceiveFlowTarget?(
|
|
12
25
|
identity: object,
|
|
13
26
|
applyState: (state: 'running' | 'paused') => void,
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ZLinkBackendReceived,
|
|
7
7
|
ZLinkBackendTopicMessage
|
|
8
8
|
} from '../runtime-values';
|
|
9
|
-
import type { CoreHwmBudgetSnapshot } from '@zlink-systems/zlink';
|
|
9
|
+
import type { CoreHwmBudgetSnapshot, ReceiveFlowState } from '@zlink-systems/zlink';
|
|
10
10
|
import { type ZLinkBackendRecvFlags, type ZLinkBackendSendFlags } from '../runtime-values';
|
|
11
11
|
export * from '../runtime-values';
|
|
12
12
|
type MessageLike = ZLinkBackendMessageLike;
|
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
import type { RoutingId } from '../../../contracts';
|
|
28
28
|
import type { ZLinkCoreHwmOptions } from '../../../contracts/Configuration';
|
|
29
29
|
import type { ZLinkSubmitResult } from '../../messaging/submission-result';
|
|
30
|
+
import type { ZLinkMeshCompletionHandler } from '../mesh-completion-table';
|
|
30
31
|
import type { Message } from '../../../contracts/Common/Message';
|
|
31
32
|
import type {
|
|
32
33
|
ServiceSpotMessageFollowSeal,
|
|
@@ -38,6 +39,7 @@ import type {
|
|
|
38
39
|
ServiceActorCreateRecord,
|
|
39
40
|
ServiceDirectSpotRouteFence,
|
|
40
41
|
ServiceInstanceRouteFence,
|
|
42
|
+
ServiceInstanceColdActivationTarget,
|
|
41
43
|
ServiceUserSpotCloseRecord,
|
|
42
44
|
ServiceUserSpotCreateRecord
|
|
43
45
|
} from '../../foundation/service-stateful-wire-codec';
|
|
@@ -112,26 +114,14 @@ export interface ZLinkBackendMeshNode {
|
|
|
112
114
|
selectObjectPlacement(stableType: string): ZLinkBackendObjectPlacement;
|
|
113
115
|
instanceSpotPlacementTypes?(): readonly string[];
|
|
114
116
|
sendToMissingInstanceSpot(
|
|
115
|
-
target:
|
|
116
|
-
readonly targetNodeRid: string;
|
|
117
|
-
readonly targetNodeGeneration: bigint;
|
|
118
|
-
readonly targetSpotId: string;
|
|
119
|
-
readonly stableType: string;
|
|
120
|
-
readonly descriptorVersion: string;
|
|
121
|
-
},
|
|
117
|
+
target: ServiceInstanceColdActivationTarget,
|
|
122
118
|
parts: ZLinkBackendMessageLike | readonly ZLinkBackendMessageLike[],
|
|
123
119
|
deadlineUnixMs: bigint,
|
|
124
120
|
sourceSpotId?: string,
|
|
125
121
|
metadata?: ReadonlyMap<string, string>
|
|
126
122
|
): Promise<SubmitResult>;
|
|
127
123
|
requestToMissingInstanceSpot(
|
|
128
|
-
target:
|
|
129
|
-
readonly targetNodeRid: string;
|
|
130
|
-
readonly targetNodeGeneration: bigint;
|
|
131
|
-
readonly targetSpotId: string;
|
|
132
|
-
readonly stableType: string;
|
|
133
|
-
readonly descriptorVersion: string;
|
|
134
|
-
},
|
|
124
|
+
target: ServiceInstanceColdActivationTarget,
|
|
135
125
|
parts: ZLinkBackendMessageLike | readonly ZLinkBackendMessageLike[],
|
|
136
126
|
deadlineUnixMs: bigint,
|
|
137
127
|
sourceSpotId?: string,
|
|
@@ -390,6 +380,7 @@ export interface ZLinkBackendMeshNode {
|
|
|
390
380
|
timeoutMs?: number
|
|
391
381
|
): MeshOperationId;
|
|
392
382
|
setReadyHandler(handler: (readyDomains: number) => number): void;
|
|
383
|
+
setCompletionHandler(handler: ZLinkMeshCompletionHandler): void;
|
|
393
384
|
createReadyBatch(capacity: number): ReadyBatch;
|
|
394
385
|
createReceiveBatch(messageCapacity: number, partCapacity: number): ReceiveBatch;
|
|
395
386
|
drainReady(
|
|
@@ -476,7 +467,6 @@ export interface ZLinkBackendSocket extends ZLinkBackendObject {
|
|
|
476
467
|
readonly lastEndpoint?: string;
|
|
477
468
|
bind(endpoint: string): void;
|
|
478
469
|
setChannelName(channelName: string): void;
|
|
479
|
-
setReceiveFlowState?(state: 0 | 1): void;
|
|
480
470
|
dispose(): Promise<void>;
|
|
481
471
|
}
|
|
482
472
|
|
|
@@ -486,7 +476,7 @@ export interface ZLinkBackendConnectableSocket extends ZLinkBackendSocket {
|
|
|
486
476
|
}
|
|
487
477
|
|
|
488
478
|
export interface ZLinkBackendDealerSocket extends ZLinkBackendConnectableSocket {
|
|
489
|
-
|
|
479
|
+
receiveAdmission?: import('../../foundation/service-liveness-registry').ServiceLivenessConnection;
|
|
490
480
|
setRoutingId(routingId: RoutingId): void;
|
|
491
481
|
peerWeight: number;
|
|
492
482
|
sendHighWaterMark: number;
|
|
@@ -515,7 +505,7 @@ export interface ZLinkBackendRequestOperation {
|
|
|
515
505
|
}
|
|
516
506
|
|
|
517
507
|
export interface ZLinkBackendRouterSocket extends ZLinkBackendConnectableSocket {
|
|
518
|
-
setReceiveFlowState(state:
|
|
508
|
+
setReceiveFlowState(state: ReceiveFlowState): void;
|
|
519
509
|
/** Enables the native probe handshake for manually configured routes. */
|
|
520
510
|
setProbe(enabled: boolean): void;
|
|
521
511
|
peerWeight: number;
|
|
@@ -549,6 +539,7 @@ export interface ZLinkBackendRouterSocket extends ZLinkBackendConnectableSocket
|
|
|
549
539
|
}
|
|
550
540
|
|
|
551
541
|
export interface ZLinkBackendPublisherSocket extends ZLinkBackendSocket {
|
|
542
|
+
lingerMs: number;
|
|
552
543
|
sendTimeoutMs: number;
|
|
553
544
|
sendHighWaterMark: number;
|
|
554
545
|
noDrop: boolean;
|
|
@@ -739,6 +730,7 @@ export interface ZLinkMeshBackendAdapter {
|
|
|
739
730
|
readonly trustProfile?: string;
|
|
740
731
|
readonly applicationJobQueue: import('../../application-jobs/contracts').ApplicationJobQueuePort;
|
|
741
732
|
readonly applicationJobReceiveFlowFailureSink?: (error: unknown) => void;
|
|
733
|
+
readonly infrastructureTaskRunner?: import('../../spots/spot-actor-join-dispatch').ZLinkDetachedTaskRunner;
|
|
742
734
|
readonly peerAdmissionSealed?: () => boolean;
|
|
743
735
|
}
|
|
744
736
|
): ZLinkBackendMeshNode;
|
|
@@ -27,8 +27,14 @@ interface PendingCompletion {
|
|
|
27
27
|
readonly removeAbort?: () => void;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
export type ZLinkMeshCompletionTerminal = Pick<ReceiveRecord, 'operationId' | 'terminalResult'>;
|
|
31
|
+
export type ZLinkMeshCompletionHandler = (
|
|
32
|
+
terminal: ZLinkMeshCompletionTerminal,
|
|
33
|
+
materialize: () => ReceiveRecord
|
|
34
|
+
) => void;
|
|
35
|
+
|
|
30
36
|
export class ZLinkMeshCompletionTable {
|
|
31
|
-
private readonly pending = new Map<string, PendingCompletion>();
|
|
37
|
+
private readonly pending = new Map<string | symbol, PendingCompletion>();
|
|
32
38
|
private disposed = false;
|
|
33
39
|
|
|
34
40
|
constructor(
|
|
@@ -36,10 +42,9 @@ export class ZLinkMeshCompletionTable {
|
|
|
36
42
|
) {}
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* arrived before their waiter.
|
|
45
|
+
* Reserves the dispatcher slot before transport submission. The backend
|
|
46
|
+
* observes native terminals through Promises, so identity binding finishes
|
|
47
|
+
* before the terminal callback can run, without an infrastructure pump.
|
|
43
48
|
*/
|
|
44
49
|
submit(operation: () => MeshOperationId, signal?: AbortSignal): Promise<ZLinkMeshCompletion> {
|
|
45
50
|
if (this.isDisposed()) {
|
|
@@ -50,17 +55,8 @@ export class ZLinkMeshCompletionTable {
|
|
|
50
55
|
signal.reason ?? new DOMException('The operation was aborted.', 'AbortError')
|
|
51
56
|
);
|
|
52
57
|
}
|
|
53
|
-
const operationId = operation();
|
|
54
|
-
// The backend submission callback can synchronously re-enter `dispose()`.
|
|
55
|
-
// TypeScript's control-flow analysis cannot observe mutation through it.
|
|
56
|
-
if (this.disposed) {
|
|
57
|
-
return Promise.reject(new Error('Mesh completion table is disposed.'));
|
|
58
|
-
}
|
|
59
|
-
const key = operationIdentityKey(operationId);
|
|
60
|
-
if (this.pending.has(key)) {
|
|
61
|
-
return Promise.reject(new Error(`Mesh operation '${key}' is already pending.`));
|
|
62
|
-
}
|
|
63
58
|
return new Promise((resolve, reject) => {
|
|
59
|
+
let key: string | symbol = Symbol();
|
|
64
60
|
const abort = () => {
|
|
65
61
|
this.pending.delete(key);
|
|
66
62
|
reject(signal?.reason ?? new DOMException('The operation was aborted.', 'AbortError'));
|
|
@@ -70,12 +66,29 @@ export class ZLinkMeshCompletionTable {
|
|
|
70
66
|
return;
|
|
71
67
|
}
|
|
72
68
|
signal?.addEventListener('abort', abort, { once: true });
|
|
73
|
-
|
|
69
|
+
const entry: PendingCompletion = {
|
|
74
70
|
resolve,
|
|
75
71
|
reject,
|
|
76
72
|
removeAbort:
|
|
77
73
|
signal === undefined ? undefined : () => signal.removeEventListener('abort', abort)
|
|
78
|
-
}
|
|
74
|
+
};
|
|
75
|
+
this.pending.set(key, entry);
|
|
76
|
+
try {
|
|
77
|
+
const operationId = operation();
|
|
78
|
+
// dispose/abort can consume the reserved slot during submission.
|
|
79
|
+
if (!this.pending.delete(key)) return;
|
|
80
|
+
key = operationIdentityKey(operationId);
|
|
81
|
+
if (this.pending.has(key)) {
|
|
82
|
+
throw new Error(`Mesh operation '${key}' is already pending.`);
|
|
83
|
+
}
|
|
84
|
+
this.pending.set(key, entry);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
// Remove only this submission's slot; a duplicate identity retains
|
|
87
|
+
// the original waiter.
|
|
88
|
+
if (this.pending.get(key) === entry) this.pending.delete(key);
|
|
89
|
+
entry.removeAbort?.();
|
|
90
|
+
reject(error);
|
|
91
|
+
}
|
|
79
92
|
});
|
|
80
93
|
}
|
|
81
94
|
|
|
@@ -83,7 +96,9 @@ export class ZLinkMeshCompletionTable {
|
|
|
83
96
|
return this.disposed;
|
|
84
97
|
}
|
|
85
98
|
|
|
86
|
-
complete(record: ReceiveRecord): void
|
|
99
|
+
complete(record: ReceiveRecord): void;
|
|
100
|
+
complete(record: ZLinkMeshCompletionTerminal, materialize: () => ReceiveRecord): void;
|
|
101
|
+
complete(record: ZLinkMeshCompletionTerminal, materialize?: () => ReceiveRecord): void {
|
|
87
102
|
const key = operationIdentityKey(record.operationId);
|
|
88
103
|
const pending = this.pending.get(key);
|
|
89
104
|
if (pending === undefined) {
|
|
@@ -97,7 +112,9 @@ export class ZLinkMeshCompletionTable {
|
|
|
97
112
|
this.pending.delete(key);
|
|
98
113
|
pending.removeAbort?.();
|
|
99
114
|
try {
|
|
100
|
-
pending.resolve(
|
|
115
|
+
pending.resolve(
|
|
116
|
+
retainCompletion(materialize === undefined ? (record as ReceiveRecord) : materialize())
|
|
117
|
+
);
|
|
101
118
|
} catch (error) {
|
|
102
119
|
pending.reject(error);
|
|
103
120
|
}
|
|
@@ -253,7 +253,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
253
253
|
): Promise<boolean> {
|
|
254
254
|
let claimsDrained = 0;
|
|
255
255
|
try {
|
|
256
|
-
|
|
256
|
+
while (!this.disposed) {
|
|
257
257
|
if (claimBudget !== undefined && claimsDrained >= claimBudget) {
|
|
258
258
|
// Lifecycle work has priority, but a bounded turn lets application
|
|
259
259
|
// work make progress when lifecycle records keep arriving.
|
|
@@ -282,19 +282,18 @@ export class ZLinkMeshDispatchPump {
|
|
|
282
282
|
);
|
|
283
283
|
const capacity =
|
|
284
284
|
owner.ordinaryIngressPreAdmitted === true ? MESH_DISPATCH_RECEIVE_CAPACITY : 1;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
// This owner keeps its claim while it drains, so its records stay in FIFO order.
|
|
285
|
+
let claimPermit =
|
|
286
|
+
owner.terminalCompletion === true ||
|
|
287
|
+
owner.ordinaryIngressPreAdmitted === true ||
|
|
288
|
+
domain === ReadyDomain.Infrastructure
|
|
289
|
+
? undefined
|
|
290
|
+
: await this.acquirePermit();
|
|
291
|
+
try {
|
|
292
|
+
if (this.capacityStop.signal.aborted) return;
|
|
293
|
+
ownerReceiveBatch.reset(capacity);
|
|
294
|
+
const received = claim.recvBatch(ownerReceiveBatch, ZLINK_BACKEND_RECV_DONT_WAIT);
|
|
295
|
+
if (received.ok) {
|
|
296
|
+
// The bounded batch stays in claim order until its records finish.
|
|
298
297
|
try {
|
|
299
298
|
for (const record of received.records) {
|
|
300
299
|
if (this.disposed) break;
|
|
@@ -327,8 +326,6 @@ export class ZLinkMeshDispatchPump {
|
|
|
327
326
|
if (permit === claimPermit) claimPermit = undefined;
|
|
328
327
|
await runWithApplicationJobPermit(permit, dispatch);
|
|
329
328
|
}
|
|
330
|
-
const yieldTurn = this.yieldIfNeeded();
|
|
331
|
-
if (yieldTurn !== undefined) await yieldTurn;
|
|
332
329
|
}
|
|
333
330
|
} finally {
|
|
334
331
|
// Batch ownership includes records whose dispatch never began,
|
|
@@ -338,14 +335,16 @@ export class ZLinkMeshDispatchPump {
|
|
|
338
335
|
record.releaseRetainedIngress?.();
|
|
339
336
|
}
|
|
340
337
|
}
|
|
341
|
-
} finally {
|
|
342
|
-
claimPermit?.releaseAfterInternalProcessing();
|
|
343
338
|
}
|
|
339
|
+
} finally {
|
|
340
|
+
claimPermit?.releaseAfterInternalProcessing();
|
|
344
341
|
}
|
|
345
342
|
} finally {
|
|
346
343
|
claim.release();
|
|
347
344
|
if (receiveBatch === undefined) ownerReceiveBatch?.close();
|
|
348
345
|
}
|
|
346
|
+
const yieldTurn = this.yieldIfNeeded();
|
|
347
|
+
if (yieldTurn !== undefined) await yieldTurn;
|
|
349
348
|
};
|
|
350
349
|
// An application worker drains the one owner it claimed. Infrastructure owners
|
|
351
350
|
// drain independently, so a suspended owner does not hold the other claims.
|
|
@@ -366,10 +365,8 @@ export class ZLinkMeshDispatchPump {
|
|
|
366
365
|
this.recordsSinceYield += 1;
|
|
367
366
|
const yieldTurn = this.yieldIfNeeded();
|
|
368
367
|
if (yieldTurn !== undefined) await yieldTurn;
|
|
369
|
-
if (!drained.hasResidue) {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
368
|
}
|
|
369
|
+
return false;
|
|
373
370
|
} finally {
|
|
374
371
|
readyBatch.reset();
|
|
375
372
|
}
|
|
@@ -394,7 +391,7 @@ export class ZLinkMeshDispatchPump {
|
|
|
394
391
|
|
|
395
392
|
private async acquirePermit(): Promise<ApplicationJobPermitPort | undefined> {
|
|
396
393
|
try {
|
|
397
|
-
return await this.options.applicationJobQueue.acquire(this.capacityStop.signal);
|
|
394
|
+
return await this.options.applicationJobQueue.acquire(this.capacityStop.signal, 'remote');
|
|
398
395
|
} catch (error) {
|
|
399
396
|
if (this.disposed || this.capacityStop.signal.aborted) return undefined;
|
|
400
397
|
throw error;
|