@zlink-systems/framework 0.19.0 → 0.21.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 +0 -2
- package/dist/contracts/Configuration/Configs.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -2
- package/dist/contracts/Locations/Authority.d.ts +1 -7
- package/dist/runtime/actors/actor-authority-publication.js +25 -22
- package/dist/runtime/actors/actor-creation.js +30 -9
- package/dist/runtime/actors/actor-runtime-state.d.ts +3 -0
- package/dist/runtime/actors/index.d.ts +3 -0
- package/dist/runtime/actors/index.js +14 -3
- package/dist/runtime/admission.d.ts +2 -0
- package/dist/runtime/admission.js +11 -5
- package/dist/runtime/backend/contracts/index.d.ts +4 -1
- package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -0
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +2 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +12 -5
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +6 -0
- package/dist/runtime/channels/channel-socket-options.js +7 -0
- package/dist/runtime/channels/channel-socket-registry.js +3 -0
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +1 -1
- package/dist/runtime/foundation/service-stateful-runtime.js +1 -5
- package/dist/runtime/host/actor-placement-coordinator.d.ts +14 -5
- package/dist/runtime/host/actor-placement-coordinator.js +159 -47
- package/dist/runtime/host/index.d.ts +2 -1
- package/dist/runtime/host/index.js +77 -120
- package/dist/runtime/host/location-runtime-owner.js +4 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +12 -3
- package/dist/runtime/locations/creation-operation-id.d.ts +4 -0
- package/dist/runtime/locations/creation-operation-id.js +12 -0
- package/dist/runtime/locations/in-memory-authority-store.js +8 -22
- package/dist/runtime/locations/location-store-repository.js +36 -59
- package/dist/runtime/locations/opaque-record-key.d.ts +5 -0
- package/dist/runtime/locations/opaque-record-key.js +16 -0
- package/dist/runtime/locations/runtime.d.ts +7 -0
- package/dist/runtime/locations/runtime.js +130 -42
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1672 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +9169 -0
- package/dist/runtime/spots/spot-node-runtime-manager.js +2 -2
- package/package.json +2 -2
- package/src/contracts/Configuration/Builders.ts +0 -2
- package/src/contracts/Configuration/Configs.ts +1 -0
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -2
- package/src/contracts/Locations/Authority.ts +1 -8
- package/src/runtime/actors/actor-authority-publication.ts +25 -22
- package/src/runtime/actors/actor-creation.ts +45 -11
- package/src/runtime/actors/actor-runtime-state.ts +4 -0
- package/src/runtime/actors/index.ts +32 -4
- package/src/runtime/admission.ts +8 -5
- package/src/runtime/backend/contracts/index.ts +4 -1
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +2 -1
- package/src/runtime/backend/node/node-raw-binding-port.ts +16 -5
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +1 -1
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +7 -0
- package/src/runtime/channels/channel-socket-options.ts +9 -0
- package/src/runtime/channels/channel-socket-registry.ts +4 -0
- package/src/runtime/foundation/service-stateful-runtime.ts +2 -6
- package/src/runtime/host/actor-placement-coordinator.ts +216 -77
- package/src/runtime/host/index.ts +95 -135
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +15 -3
- package/src/runtime/locations/creation-operation-id.ts +11 -0
- package/src/runtime/locations/in-memory-authority-store.ts +7 -29
- package/src/runtime/locations/location-store-repository.ts +71 -69
- package/src/runtime/locations/opaque-record-key.ts +26 -0
- package/src/runtime/locations/runtime.ts +154 -60
- package/src/runtime/protocol/service_wire_codec.generated.ts +8302 -0
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/spot-node-runtime-manager.ts +2 -2
|
@@ -77,8 +77,6 @@ export interface ZLinkMeshChannelServerBuilder {
|
|
|
77
77
|
export interface ZLinkMeshNodeSocketConfig {
|
|
78
78
|
sendHighWaterMark: number;
|
|
79
79
|
receiveHighWaterMark: number;
|
|
80
|
-
mailboxMessageBudget: number;
|
|
81
|
-
mailboxByteBudget: number;
|
|
82
80
|
receiveTimeoutMs?: number;
|
|
83
81
|
sendTimeoutMs?: number;
|
|
84
82
|
}
|
|
@@ -165,8 +165,6 @@ export interface ZLinkClientCapabilityOptions {
|
|
|
165
165
|
readonly manualConnections?: readonly string[];
|
|
166
166
|
readonly sendHighWaterMark?: number;
|
|
167
167
|
readonly receiveHighWaterMark?: number;
|
|
168
|
-
readonly mailboxMessageBudget?: number;
|
|
169
|
-
readonly mailboxByteBudget?: number;
|
|
170
168
|
readonly sendTimeoutMs?: number;
|
|
171
169
|
readonly maxMessageSize?: number;
|
|
172
170
|
}
|
|
@@ -359,6 +357,7 @@ export interface ZLinkSpotRouterCapabilityOptions {
|
|
|
359
357
|
readonly routingId?: string;
|
|
360
358
|
readonly sendHighWaterMark?: number;
|
|
361
359
|
readonly receiveHighWaterMark?: number;
|
|
360
|
+
readonly receiveTimeoutMs?: number;
|
|
362
361
|
readonly sendTimeoutMs?: number;
|
|
363
362
|
}
|
|
364
363
|
export interface ZLinkSpotRouterPeerConnectionOptions {
|
|
@@ -128,11 +128,9 @@ export interface ZLinkCreationOperationIdentity {
|
|
|
128
128
|
readonly sourceNodeGeneration: bigint;
|
|
129
129
|
readonly operationId: ZLinkCreationOperationId;
|
|
130
130
|
}
|
|
131
|
-
export type ZLinkCreationTerminalState = 'created' | 'rejected' | 'failed';
|
|
132
131
|
export interface ZLinkCreationTerminalPublication {
|
|
133
132
|
readonly operation: ZLinkCreationOperationIdentity;
|
|
134
133
|
readonly terminalEnvelope: Uint8Array;
|
|
135
|
-
readonly terminalEnvelopeSha256: Uint8Array;
|
|
136
134
|
/**
|
|
137
135
|
* The original operation deadline. Providers retain the terminal for five
|
|
138
136
|
* minutes after this absolute instant.
|
|
@@ -140,12 +138,8 @@ export interface ZLinkCreationTerminalPublication {
|
|
|
140
138
|
readonly operationDeadline: Date;
|
|
141
139
|
}
|
|
142
140
|
export interface ZLinkCreationTerminalRecord {
|
|
143
|
-
readonly state: ZLinkCreationTerminalState;
|
|
144
141
|
readonly operation: ZLinkCreationOperationIdentity;
|
|
145
|
-
readonly reservationId: string;
|
|
146
|
-
readonly objectKind: ZLinkPlacementObjectKind;
|
|
147
142
|
readonly terminalEnvelope: Uint8Array;
|
|
148
|
-
readonly terminalEnvelopeSha256: Uint8Array;
|
|
149
143
|
readonly expiresAt: Date;
|
|
150
144
|
readonly storeNow: Date;
|
|
151
145
|
}
|
|
@@ -154,7 +148,7 @@ export type ZLinkCreationTerminalReadResult = {
|
|
|
154
148
|
readonly storeNow: Date;
|
|
155
149
|
} | {
|
|
156
150
|
readonly kind: 'found';
|
|
157
|
-
readonly
|
|
151
|
+
readonly terminalEnvelope: Uint8Array;
|
|
158
152
|
};
|
|
159
153
|
export interface ZLinkObjectReserveRequest {
|
|
160
154
|
readonly key: ZLinkObjectCreationKey;
|
|
@@ -8,8 +8,10 @@ exports.rewriteActorAuthorityRoute = rewriteActorAuthorityRoute;
|
|
|
8
8
|
exports.rewriteActorAuthorityOwner = rewriteActorAuthorityOwner;
|
|
9
9
|
exports.isActorAuthorityPayload = isActorAuthorityPayload;
|
|
10
10
|
const node_crypto_1 = require("node:crypto");
|
|
11
|
+
const creation_operation_id_1 = require("../locations/creation-operation-id");
|
|
11
12
|
const actor_authority_payload_codec_1 = require("./actor-authority-payload-codec");
|
|
12
13
|
const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
|
|
14
|
+
const service_wire_codec_generated_1 = require("../protocol/service_wire_codec.generated");
|
|
13
15
|
const CREATION_OPERATION_TIMEOUT_MS = 30_000;
|
|
14
16
|
/**
|
|
15
17
|
* Publishes the authority record that owns durable Actor lifecycle state.
|
|
@@ -45,12 +47,20 @@ async function publishInitialActorAuthority(store, identity, signal) {
|
|
|
45
47
|
throw new Error(`Actor '${identity.actor.actorId}' authority reservation failed with '${reserved.kind}'.`);
|
|
46
48
|
}
|
|
47
49
|
try {
|
|
48
|
-
const terminalEnvelope = Buffer.from(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const terminalEnvelope = Buffer.from((0, service_wire_codec_generated_1.encodeCreationOperationTerminalV1)({
|
|
51
|
+
terminalResult: 'ok',
|
|
52
|
+
failureCode: 'none',
|
|
53
|
+
hasCreation: 'true',
|
|
54
|
+
creation: {
|
|
55
|
+
createResult: 'created',
|
|
56
|
+
actor: {
|
|
57
|
+
actorId: identity.actor.actorId,
|
|
58
|
+
objectGeneration: identity.actor.objectGeneration
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
hasApplicationPayload: 'false'
|
|
62
|
+
}, { runtimePredicates: {} }));
|
|
63
|
+
const operationId = (0, creation_operation_id_1.randomOperationId)();
|
|
54
64
|
const completed = await store.completeCreation({
|
|
55
65
|
key: { kind: 'actor', globalId: identity.actor.actorId },
|
|
56
66
|
reservationId: reserved.reservationId,
|
|
@@ -63,13 +73,9 @@ async function publishInitialActorAuthority(store, identity, signal) {
|
|
|
63
73
|
operation: {
|
|
64
74
|
sourceNodeRid: identity.actor.nodeRid,
|
|
65
75
|
sourceNodeGeneration: identity.ownerNodeGeneration,
|
|
66
|
-
operationId
|
|
67
|
-
high: operationBytes.readBigUInt64BE(0),
|
|
68
|
-
low: operationBytes.readBigUInt64BE(8)
|
|
69
|
-
}
|
|
76
|
+
operationId
|
|
70
77
|
},
|
|
71
78
|
terminalEnvelope,
|
|
72
|
-
terminalEnvelopeSha256: (0, node_crypto_1.createHash)('sha256').update(terminalEnvelope).digest(),
|
|
73
79
|
operationDeadline: new Date(Date.now() + CREATION_OPERATION_TIMEOUT_MS)
|
|
74
80
|
}
|
|
75
81
|
}
|
|
@@ -81,17 +87,14 @@ async function publishInitialActorAuthority(store, identity, signal) {
|
|
|
81
87
|
return completed.ready;
|
|
82
88
|
}
|
|
83
89
|
catch (error) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
catch {
|
|
93
|
-
// A completed creation cannot be aborted; the validated authority remains.
|
|
94
|
-
}
|
|
90
|
+
const aborted = await store.abort({
|
|
91
|
+
key: { kind: 'actor', globalId: identity.actor.actorId },
|
|
92
|
+
reservationId: reserved.reservationId,
|
|
93
|
+
expectedStoreVersion: reserved.creating.storeVersion.value,
|
|
94
|
+
target
|
|
95
|
+
}, signal);
|
|
96
|
+
if (aborted.kind === 'stale')
|
|
97
|
+
throw error;
|
|
95
98
|
throw error;
|
|
96
99
|
}
|
|
97
100
|
}
|
|
@@ -25,7 +25,7 @@ class ZLinkActorCreationCoordinator {
|
|
|
25
25
|
state.clearAfterDestroy();
|
|
26
26
|
}, () => this.createActorAfterClaim(actorId, actorType, state, createRequest, true, signal));
|
|
27
27
|
if (activation.activated !== undefined) {
|
|
28
|
-
if (activation.activated.status
|
|
28
|
+
if (activation.activated.status !== 'created') {
|
|
29
29
|
await lifecycle.releaseActor(actorType, actorId);
|
|
30
30
|
return activation.activated;
|
|
31
31
|
}
|
|
@@ -61,16 +61,24 @@ class ZLinkActorCreationCoordinator {
|
|
|
61
61
|
const factory = await this.createFactory(actorType);
|
|
62
62
|
const context = state.ensureContext(() => new actor_context_1.DefaultZLinkActorContext(state, this.options.joinCoordinator, this.options.boundSessionFactory, this.options.messageSerializers, this.options.actorMeshNameProvider));
|
|
63
63
|
const nativeActorNode = this.options.nativeActorNode ?? this.options.nativeActorNodeProvider?.();
|
|
64
|
+
let actor;
|
|
65
|
+
try {
|
|
66
|
+
actor = await factory.create(context, signal);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
await this.discardStagingActor(state, nativeActorNode);
|
|
70
|
+
return { status: 'failed', error };
|
|
71
|
+
}
|
|
72
|
+
let meshName;
|
|
73
|
+
let nodeRid;
|
|
64
74
|
try {
|
|
65
|
-
const actor = await factory.create(context, signal);
|
|
66
75
|
if (actor.context !== context || actor.context.actorId !== context.actorId) {
|
|
67
76
|
throw new configuration_1.ZLinkConfigurationException(`Actor factory '${actorType}' must return an Actor bound to the exact supplied context.`);
|
|
68
77
|
}
|
|
69
|
-
|
|
78
|
+
meshName = state.meshName ?? '';
|
|
70
79
|
if (meshName.length === 0 && state.nativeActorRef === undefined) {
|
|
71
80
|
throw new configuration_1.ZLinkConfigurationException(`Actor '${actorId}' has no RouteMesh identity.`);
|
|
72
81
|
}
|
|
73
|
-
let nodeRid;
|
|
74
82
|
if (nativeActorNode !== undefined) {
|
|
75
83
|
const actorRef = state.ensureNativeActorRef(nativeActorNode, createRequest.nativeRequest);
|
|
76
84
|
nodeRid = (0, actor_runtime_state_1.toFrameworkRoutingId)(actorRef.nodeRid);
|
|
@@ -78,13 +86,26 @@ class ZLinkActorCreationCoordinator {
|
|
|
78
86
|
else {
|
|
79
87
|
nodeRid = this.options.actorCreatedNodeRidProvider?.();
|
|
80
88
|
}
|
|
81
|
-
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
await this.discardStagingActor(state, nativeActorNode);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
let response;
|
|
95
|
+
try {
|
|
96
|
+
response = nodeRid === undefined
|
|
82
97
|
? { accepted: true }
|
|
83
98
|
: await this.options.actorCreatedNotifier?.(nodeRid, actor, createRequest.callbackRequest, signal) ?? { accepted: true };
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
await this.discardStagingActor(state, nativeActorNode);
|
|
102
|
+
return { status: 'failed', error };
|
|
103
|
+
}
|
|
104
|
+
if (!response.accepted) {
|
|
105
|
+
await this.discardStagingActor(state, nativeActorNode);
|
|
106
|
+
return { status: 'rejected', reply: response.reply };
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
88
109
|
state.bindActor(actor, context);
|
|
89
110
|
if (nativeActorNode !== undefined) {
|
|
90
111
|
const actorRef = state.nativeActorRef;
|
|
@@ -72,6 +72,9 @@ export type ZLinkActorCreationAttemptResult = {
|
|
|
72
72
|
} | {
|
|
73
73
|
readonly status: 'rejected';
|
|
74
74
|
readonly reply?: unknown;
|
|
75
|
+
} | {
|
|
76
|
+
readonly status: 'failed';
|
|
77
|
+
readonly error: unknown;
|
|
75
78
|
};
|
|
76
79
|
export declare class ZLinkActorRuntimeState {
|
|
77
80
|
readonly actorId: string;
|
|
@@ -235,6 +235,9 @@ class DefaultZLinkActorManager {
|
|
|
235
235
|
? { status: 'rejected' }
|
|
236
236
|
: { status: 'rejected', reply: result.reply };
|
|
237
237
|
}
|
|
238
|
+
if (result.status === 'failed') {
|
|
239
|
+
throw actorApplicationFailure(actorId, result.error);
|
|
240
|
+
}
|
|
238
241
|
return result.reply === undefined
|
|
239
242
|
? { status: result.status, actor: result.actorRef }
|
|
240
243
|
: { status: result.status, actor: result.actorRef, reply: result.reply };
|
|
@@ -453,7 +456,7 @@ class DefaultZLinkActorManager {
|
|
|
453
456
|
const operation = state.getOrStartCreation(actorType, failIfExists, () => this.creation.createActor(actorId, actorType, state, createRequest, claimLocation, signal));
|
|
454
457
|
if (operation.created) {
|
|
455
458
|
void operation.task.then((result) => {
|
|
456
|
-
if (result.status
|
|
459
|
+
if (result.status !== 'created') {
|
|
457
460
|
this.discardFailedState(actorId, state, operation.task);
|
|
458
461
|
}
|
|
459
462
|
}, () => this.discardFailedState(actorId, state, operation.task));
|
|
@@ -470,7 +473,9 @@ class DefaultZLinkActorManager {
|
|
|
470
473
|
};
|
|
471
474
|
}
|
|
472
475
|
if (operation.created) {
|
|
473
|
-
return
|
|
476
|
+
return result.status === 'failed'
|
|
477
|
+
? { status: 'failed', error: result.error }
|
|
478
|
+
: { status: 'rejected', reply: result.reply };
|
|
474
479
|
}
|
|
475
480
|
}
|
|
476
481
|
catch (error) {
|
|
@@ -610,10 +615,16 @@ class ZLinkActorCreateCallRuntime {
|
|
|
610
615
|
class ZLinkActorGetOrCreateCallRuntime extends ZLinkActorCreateCallRuntime {
|
|
611
616
|
}
|
|
612
617
|
function requireCreatedActor(result, actorId) {
|
|
613
|
-
if (result.status
|
|
618
|
+
if (result.status === 'existing' || result.status === 'created')
|
|
614
619
|
return result.actor;
|
|
620
|
+
if (result.status === 'failed') {
|
|
621
|
+
throw actorApplicationFailure(actorId, result.error);
|
|
622
|
+
}
|
|
615
623
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorCreateRejected, `Actor '${actorId}' create request was rejected.`);
|
|
616
624
|
}
|
|
625
|
+
function actorApplicationFailure(actorId, error) {
|
|
626
|
+
return (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorCreateFailed, `Actor '${actorId}' creation failed: ${error instanceof Error ? error.message : String(error)}`, false, error);
|
|
627
|
+
}
|
|
617
628
|
async function waitForCreationRetry(signal) {
|
|
618
629
|
(0, abort_1.throwIfAborted)(signal);
|
|
619
630
|
await new Promise((resolve, reject) => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ZLinkFrameworkInternalErrorKind } from './framework-errors-internal';
|
|
2
2
|
export declare class ZLinkRuntimeAdmissionGate {
|
|
3
|
+
private readonly ownerAdmissionOpen;
|
|
3
4
|
private readonly meshes;
|
|
5
|
+
constructor(ownerAdmissionOpen?: () => boolean);
|
|
4
6
|
get acceptsNewWork(): boolean;
|
|
5
7
|
register(meshName: string): void;
|
|
6
8
|
accepts(meshName: string): boolean;
|
|
@@ -3,8 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ZLinkRuntimeAdmissionGate = void 0;
|
|
4
4
|
const framework_errors_internal_1 = require("./framework-errors-internal");
|
|
5
5
|
class ZLinkRuntimeAdmissionGate {
|
|
6
|
+
ownerAdmissionOpen;
|
|
6
7
|
meshes = new Map();
|
|
8
|
+
constructor(ownerAdmissionOpen = () => true) {
|
|
9
|
+
this.ownerAdmissionOpen = ownerAdmissionOpen;
|
|
10
|
+
}
|
|
7
11
|
get acceptsNewWork() {
|
|
12
|
+
if (!this.ownerAdmissionOpen())
|
|
13
|
+
return false;
|
|
8
14
|
for (const state of this.meshes.values()) {
|
|
9
15
|
if (state.sealed)
|
|
10
16
|
return false;
|
|
@@ -24,7 +30,7 @@ class ZLinkRuntimeAdmissionGate {
|
|
|
24
30
|
}
|
|
25
31
|
}
|
|
26
32
|
accepts(meshName) {
|
|
27
|
-
return !this.requireState(meshName).sealed;
|
|
33
|
+
return this.ownerAdmissionOpen() && !this.requireState(meshName).sealed;
|
|
28
34
|
}
|
|
29
35
|
pending(meshName) {
|
|
30
36
|
return this.requireState(meshName).active;
|
|
@@ -42,7 +48,7 @@ class ZLinkRuntimeAdmissionGate {
|
|
|
42
48
|
}
|
|
43
49
|
claim(meshName, operation) {
|
|
44
50
|
const state = this.requireState(meshName);
|
|
45
|
-
if (!state.sealed) {
|
|
51
|
+
if (this.ownerAdmissionOpen() && !state.sealed) {
|
|
46
52
|
state.active += 1;
|
|
47
53
|
let closed = false;
|
|
48
54
|
return {
|
|
@@ -59,7 +65,7 @@ class ZLinkRuntimeAdmissionGate {
|
|
|
59
65
|
}
|
|
60
66
|
};
|
|
61
67
|
}
|
|
62
|
-
throw (0, framework_errors_internal_1.createInternalFrameworkException)(state.sealedReason, `${operation} was rejected because
|
|
68
|
+
throw (0, framework_errors_internal_1.createInternalFrameworkException)(state.sealedReason, `${operation} was rejected because framework admission is closed.`);
|
|
63
69
|
}
|
|
64
70
|
async run(meshName, operation, work) {
|
|
65
71
|
const claim = this.claim(meshName, operation);
|
|
@@ -106,7 +112,7 @@ class ZLinkRuntimeAdmissionGate {
|
|
|
106
112
|
}
|
|
107
113
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(meshName === undefined
|
|
108
114
|
? this.firstSealedReason()
|
|
109
|
-
: this.requireState(meshName).sealedReason, `${operation} was rejected because
|
|
115
|
+
: this.requireState(meshName).sealedReason, `${operation} was rejected because framework admission is closed.`);
|
|
110
116
|
}
|
|
111
117
|
requireActorCreate(actorId, meshName) {
|
|
112
118
|
if (meshName === undefined) {
|
|
@@ -121,7 +127,7 @@ class ZLinkRuntimeAdmissionGate {
|
|
|
121
127
|
: this.requireState(meshName).sealedReason;
|
|
122
128
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(reason === framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RuntimeShutdown
|
|
123
129
|
? framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RuntimeShutdown
|
|
124
|
-
: framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorCreateRejected, `Actor '${actorId}' create request was rejected because
|
|
130
|
+
: framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorCreateRejected, `Actor '${actorId}' create request was rejected because framework admission is closed.`);
|
|
125
131
|
}
|
|
126
132
|
requireState(meshName) {
|
|
127
133
|
const state = this.meshes.get(meshName);
|
|
@@ -83,7 +83,7 @@ export interface ZLinkBackendMeshNode {
|
|
|
83
83
|
registerUserSpotOperationHandler(handler: ServiceUserSpotOperationHandler): void;
|
|
84
84
|
requestUserSpotCreate(targetNodeRid: string, request: Omit<ServiceUserSpotCreateRecord, 'kind' | 'correlation' | 'operation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
85
85
|
requestUserSpotClose(targetNodeRid: string, request: Omit<ServiceUserSpotCloseRecord, 'kind' | 'correlation' | 'operation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
86
|
-
requestActorCreate(targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'
|
|
86
|
+
requestActorCreate(targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
87
87
|
connectPeer(options: {
|
|
88
88
|
readonly endpoint: string;
|
|
89
89
|
readonly expectedRid?: unknown;
|
|
@@ -311,6 +311,7 @@ export interface ZLinkBackendDealerSocket extends ZLinkBackendConnectableSocket
|
|
|
311
311
|
peerWeight: number;
|
|
312
312
|
sendHighWaterMark: number;
|
|
313
313
|
receiveHighWaterMark: number;
|
|
314
|
+
receiveTimeoutMs: number;
|
|
314
315
|
sendTimeoutMs: number;
|
|
315
316
|
maxMessageSize: number;
|
|
316
317
|
send(message: Message | readonly Message[]): Promise<void>;
|
|
@@ -337,6 +338,7 @@ export interface ZLinkBackendRouterSocket extends ZLinkBackendConnectableSocket
|
|
|
337
338
|
peerWeight: number;
|
|
338
339
|
sendHighWaterMark: number;
|
|
339
340
|
receiveHighWaterMark: number;
|
|
341
|
+
receiveTimeoutMs: number;
|
|
340
342
|
sendTimeoutMs: number;
|
|
341
343
|
maxMessageSize: number;
|
|
342
344
|
setRoutingId(routingId: RoutingId): void;
|
|
@@ -466,6 +468,7 @@ export interface ZLinkMeshBackendAdapter {
|
|
|
466
468
|
createMeshNode(context: ZLinkBackendContext, options: {
|
|
467
469
|
readonly meshName: string;
|
|
468
470
|
readonly routingId?: RoutingId;
|
|
471
|
+
readonly receiveTimeoutMs?: number;
|
|
469
472
|
readonly trustProfile?: string;
|
|
470
473
|
readonly applicationJobQueue: import('../../application-jobs/contracts').ApplicationJobQueuePort;
|
|
471
474
|
readonly applicationJobReceiveFlowFailureSink?: (error: unknown) => void;
|
|
@@ -3,6 +3,7 @@ export declare class ZLinkNodeMeshBackendAdapter implements ZLinkMeshBackendAdap
|
|
|
3
3
|
createMeshNode(context: ZLinkBackendContext, options: {
|
|
4
4
|
readonly meshName: string;
|
|
5
5
|
readonly routingId?: string;
|
|
6
|
+
readonly receiveTimeoutMs?: number;
|
|
6
7
|
readonly trustProfile?: string;
|
|
7
8
|
readonly applicationJobQueue: import('../../application-jobs/contracts').ApplicationJobQueuePort;
|
|
8
9
|
readonly applicationJobReceiveFlowFailureSink?: (error: unknown) => void;
|
|
@@ -12,7 +12,7 @@ class ZLinkNodeMeshBackendAdapter {
|
|
|
12
12
|
if (!isBindingContext(bindingContext)) {
|
|
13
13
|
throw new TypeError('Node MeshNode creation requires the Node binding Context owned by the host.');
|
|
14
14
|
}
|
|
15
|
-
return new node_raw_mesh_backend_1.ZLinkNodeRawMeshBackend(options.meshName, options.routingId, new node_raw_binding_port_1.ZLinkNodeRawBindingPort(bindingContext), options.applicationJobQueue, options.applicationJobReceiveFlowFailureSink, options.peerAdmissionSealed);
|
|
15
|
+
return new node_raw_mesh_backend_1.ZLinkNodeRawMeshBackend(options.meshName, options.routingId, new node_raw_binding_port_1.ZLinkNodeRawBindingPort(bindingContext, options.receiveTimeoutMs), options.applicationJobQueue, options.applicationJobReceiveFlowFailureSink, options.peerAdmissionSealed);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
exports.ZLinkNodeMeshBackendAdapter = ZLinkNodeMeshBackendAdapter;
|
|
@@ -3,6 +3,7 @@ import type { ZLinkRawBindingPort, ZLinkRawHostPort } from '../raw-binding-port'
|
|
|
3
3
|
export type { ZLinkRawBindingPort, ZLinkRawDealerPort, ZLinkRawHostPort, ZLinkRawMonitorPort, ZLinkRawMonitorRecord, ZLinkRawReceivedRecord, ZLinkRawRouterPort, ZLinkRawSocketPort } from '../raw-binding-port';
|
|
4
4
|
export declare class ZLinkNodeRawBindingPort implements ZLinkRawBindingPort {
|
|
5
5
|
private readonly sharedContext?;
|
|
6
|
-
|
|
6
|
+
private readonly routerReceiveTimeoutMs?;
|
|
7
|
+
constructor(sharedContext?: Context | undefined, routerReceiveTimeoutMs?: number | undefined);
|
|
7
8
|
createHost(): ZLinkRawHostPort;
|
|
8
9
|
}
|
|
@@ -7,26 +7,30 @@ const node_socket_backend_adapter_1 = require("./node-socket-backend-adapter");
|
|
|
7
7
|
const node_event_loop_poller_1 = require("./node-event-loop-poller");
|
|
8
8
|
class ZLinkNodeRawBindingPort {
|
|
9
9
|
sharedContext;
|
|
10
|
-
|
|
10
|
+
routerReceiveTimeoutMs;
|
|
11
|
+
constructor(sharedContext, routerReceiveTimeoutMs) {
|
|
11
12
|
this.sharedContext = sharedContext;
|
|
13
|
+
this.routerReceiveTimeoutMs = routerReceiveTimeoutMs;
|
|
12
14
|
}
|
|
13
15
|
createHost() {
|
|
14
|
-
return new NodeRawHostPort(this.sharedContext ?? (0, zlink_1.createContext)(), this.sharedContext === undefined);
|
|
16
|
+
return new NodeRawHostPort(this.sharedContext ?? (0, zlink_1.createContext)(), this.sharedContext === undefined, this.routerReceiveTimeoutMs);
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
exports.ZLinkNodeRawBindingPort = ZLinkNodeRawBindingPort;
|
|
18
20
|
class NodeRawHostPort {
|
|
19
21
|
context;
|
|
20
22
|
ownsContext;
|
|
23
|
+
routerReceiveTimeoutMs;
|
|
21
24
|
resources = [];
|
|
22
25
|
state = 'open';
|
|
23
|
-
constructor(context, ownsContext) {
|
|
26
|
+
constructor(context, ownsContext, routerReceiveTimeoutMs) {
|
|
24
27
|
this.context = context;
|
|
25
28
|
this.ownsContext = ownsContext;
|
|
29
|
+
this.routerReceiveTimeoutMs = routerReceiveTimeoutMs;
|
|
26
30
|
}
|
|
27
31
|
createRouter() {
|
|
28
32
|
this.requireOpen();
|
|
29
|
-
return this.own(new NodeRawRouterPort((0, zlink_1.createRouterSocket)(this.context)));
|
|
33
|
+
return this.own(new NodeRawRouterPort((0, zlink_1.createRouterSocket)(this.context), this.routerReceiveTimeoutMs));
|
|
30
34
|
}
|
|
31
35
|
createDealer() {
|
|
32
36
|
this.requireOpen();
|
|
@@ -178,11 +182,14 @@ class NodeRawRouterPort extends NodeRawSocketPort {
|
|
|
178
182
|
this.requireOpen();
|
|
179
183
|
this.socket.disconnectRid(bindingRoutingId(routingId));
|
|
180
184
|
}
|
|
181
|
-
constructor(socket) {
|
|
185
|
+
constructor(socket, receiveTimeoutMs) {
|
|
182
186
|
super(socket);
|
|
183
187
|
socket.options.handover = true;
|
|
184
188
|
socket.options.mandatory = true;
|
|
185
189
|
socket.options.probe = true;
|
|
190
|
+
if (receiveTimeoutMs !== undefined) {
|
|
191
|
+
socket.options.recvTimeout = receiveTimeoutMs;
|
|
192
|
+
}
|
|
186
193
|
}
|
|
187
194
|
localEndpoint() {
|
|
188
195
|
this.requireOpen();
|
|
@@ -178,7 +178,7 @@ export declare class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
178
178
|
registerUserSpotOperationHandler(handler: ServiceUserSpotOperationHandler): void;
|
|
179
179
|
requestUserSpotCreate(targetNodeRid: string, request: Omit<ServiceUserSpotCreateRecord, 'kind' | 'correlation' | 'operation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
180
180
|
requestUserSpotClose(targetNodeRid: string, request: Omit<ServiceUserSpotCloseRecord, 'kind' | 'correlation' | 'operation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
181
|
-
requestActorCreate(targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'
|
|
181
|
+
requestActorCreate(targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
182
182
|
recoverInstanceActivation(envelope: ServiceInstanceActivationRecoveryEnvelope, route: ServiceInstanceRouteFence, expectedCurrentRoute?: ServiceInstanceRouteFence | null): Promise<boolean>;
|
|
183
183
|
recoverPendingInstanceActivation(envelope: ServiceInstanceActivationRecoveryEnvelope, pending: ServicePendingInstanceActivation, expectedCurrentRoute?: ServiceInstanceRouteFence | null): Promise<boolean>;
|
|
184
184
|
completeRecoveredInstanceActivation(target: ServiceInstanceActivationTarget, route: ServiceInstanceRouteFence, expectedCurrentRoute?: ServiceInstanceRouteFence | null): Promise<ServiceInstanceRouteFence | undefined>;
|
|
@@ -92,6 +92,12 @@ function wrapSocket(nativeInstance, pollCompletion) {
|
|
|
92
92
|
set receiveHighWaterMark(value) {
|
|
93
93
|
requireSocketOptions(socket).recvHwm = value;
|
|
94
94
|
},
|
|
95
|
+
get receiveTimeoutMs() {
|
|
96
|
+
return socket.options?.recvTimeout ?? 0;
|
|
97
|
+
},
|
|
98
|
+
set receiveTimeoutMs(value) {
|
|
99
|
+
requireSocketOptions(socket).recvTimeout = value;
|
|
100
|
+
},
|
|
95
101
|
get sendTimeoutMs() {
|
|
96
102
|
return socket.options?.sendTimeout ?? 0;
|
|
97
103
|
},
|
|
@@ -33,6 +33,13 @@ class ZLinkLiveSocketConfig {
|
|
|
33
33
|
validateHighWaterMark(value, 'receiveHighWaterMark');
|
|
34
34
|
this.socket.receiveHighWaterMark = value;
|
|
35
35
|
}
|
|
36
|
+
get receiveTimeoutMs() {
|
|
37
|
+
return this.socket.receiveTimeoutMs;
|
|
38
|
+
}
|
|
39
|
+
set receiveTimeoutMs(value) {
|
|
40
|
+
(0, SendTimeoutValidation_1.requireValidSendTimeoutMs)('receiveTimeoutMs', value);
|
|
41
|
+
this.socket.receiveTimeoutMs = value;
|
|
42
|
+
}
|
|
36
43
|
get sendTimeoutMs() {
|
|
37
44
|
return this.socket.sendTimeoutMs;
|
|
38
45
|
}
|
|
@@ -1446,6 +1446,9 @@ function applySocketConfig(socket, config) {
|
|
|
1446
1446
|
if (config.receiveHighWaterMark !== undefined) {
|
|
1447
1447
|
socket.receiveHighWaterMark = config.receiveHighWaterMark;
|
|
1448
1448
|
}
|
|
1449
|
+
if (config.receiveTimeoutMs !== undefined) {
|
|
1450
|
+
socket.receiveTimeoutMs = config.receiveTimeoutMs;
|
|
1451
|
+
}
|
|
1449
1452
|
if (config.sendTimeoutMs !== undefined) {
|
|
1450
1453
|
socket.sendTimeoutMs = config.sendTimeoutMs;
|
|
1451
1454
|
}
|
|
@@ -253,7 +253,7 @@ export declare class ServiceStatefulRuntime {
|
|
|
253
253
|
registerUserSpotOperationHandler(handler: ServiceUserSpotOperationHandler): void;
|
|
254
254
|
requestUserSpotCreate(targetNodeRid: string, request: Omit<ServiceUserSpotCreateRecord, 'kind' | 'correlation' | 'operation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
255
255
|
requestUserSpotClose(targetNodeRid: string, request: Omit<ServiceUserSpotCloseRecord, 'kind' | 'correlation' | 'operation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
256
|
-
requestActorCreate(targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'
|
|
256
|
+
requestActorCreate(targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'>, timeoutMs: number): Promise<ServiceUserSpotOperationResult>;
|
|
257
257
|
recoverInstanceActivation(envelope: ServiceInstanceActivationRecoveryEnvelope, route: ServiceInstanceRouteFence, expectedCurrentRoute?: ServiceInstanceRouteFence | null): Promise<boolean>;
|
|
258
258
|
private finishRecoveredInstanceActivation;
|
|
259
259
|
recoverPendingInstanceActivation(envelope: ServiceInstanceActivationRecoveryEnvelope, pending: ServicePendingInstanceActivation, expectedCurrentRoute?: ServiceInstanceRouteFence | null): Promise<boolean>;
|
|
@@ -289,16 +289,12 @@ class ServiceStatefulRuntime {
|
|
|
289
289
|
}
|
|
290
290
|
requestActorCreate(targetNodeRid, request, timeoutMs) {
|
|
291
291
|
const correlation = this.nextUserSpotOperation++;
|
|
292
|
-
const operation = {
|
|
293
|
-
high: this.nodeGeneration,
|
|
294
|
-
low: correlation
|
|
295
|
-
};
|
|
296
292
|
return this.requestUserSpotOperation(targetNodeRid, (0, service_stateful_wire_codec_1.encodeActorCreateHeader)({
|
|
297
293
|
...request,
|
|
298
294
|
sourceNodeRid: this.nodeRid,
|
|
299
295
|
sourceNodeGeneration: this.nodeGeneration,
|
|
300
296
|
correlation,
|
|
301
|
-
operation
|
|
297
|
+
operation: request.operation
|
|
302
298
|
}), correlation, 'actorCreate', timeoutMs);
|
|
303
299
|
}
|
|
304
300
|
async recoverInstanceActivation(envelope, route, expectedCurrentRoute) {
|
|
@@ -10,11 +10,13 @@ export interface ZLinkActorPlacementTarget {
|
|
|
10
10
|
readonly entrySpotId: string;
|
|
11
11
|
readonly owner: ZLinkLocationOwnerToken;
|
|
12
12
|
readonly isLocal: boolean;
|
|
13
|
+
readonly sourceNodeRid: RoutingId;
|
|
14
|
+
readonly sourceNodeGeneration: bigint;
|
|
13
15
|
}
|
|
14
16
|
export interface ZLinkActorPlacementCoordinatorOptions {
|
|
15
17
|
readonly store: ZLinkObjectCreationStore & ZLinkAuthorityStore;
|
|
16
18
|
readonly target: (meshName: string | undefined, stableType: string, signal?: AbortSignal, excludedNodeRids?: ReadonlySet<string>) => Promise<ZLinkActorPlacementTarget | undefined>;
|
|
17
|
-
readonly remoteCreate: (meshName: string, targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'
|
|
19
|
+
readonly remoteCreate: (meshName: string, targetNodeRid: string, request: Omit<ServiceActorCreateRecord, 'kind' | 'correlation'>, timeoutMs: number) => Promise<ServiceUserSpotOperationResult>;
|
|
18
20
|
readonly decodeRemoteReply?: (payload: Uint8Array) => unknown;
|
|
19
21
|
}
|
|
20
22
|
export declare class ZLinkActorPlacementCoordinator {
|
|
@@ -22,11 +24,18 @@ export declare class ZLinkActorPlacementCoordinator {
|
|
|
22
24
|
constructor(options: ZLinkActorPlacementCoordinatorOptions);
|
|
23
25
|
create(actorId: string, stableType: string, createOnly: boolean, meshName: string | undefined, requestPayload: Uint8Array, timeoutMs: number, signal?: AbortSignal): Promise<ZLinkActorCreateResult>;
|
|
24
26
|
handleRemoteCreate(record: ServiceActorCreateRecord, materialize: (requestPayload: Uint8Array, authority: ZLinkAuthoritySnapshot, signal: AbortSignal) => Promise<{
|
|
25
|
-
readonly result: 'created'
|
|
26
|
-
readonly actor
|
|
27
|
+
readonly result: 'created';
|
|
28
|
+
readonly actor: ActorRef;
|
|
27
29
|
readonly reply?: Uint8Array;
|
|
28
30
|
readonly onPublished?: () => void;
|
|
29
|
-
readonly entrySpotId
|
|
30
|
-
readonly entrySpotGeneration
|
|
31
|
+
readonly entrySpotId: string;
|
|
32
|
+
readonly entrySpotGeneration: bigint;
|
|
33
|
+
} | {
|
|
34
|
+
readonly result: 'rejected';
|
|
35
|
+
readonly reply?: Uint8Array;
|
|
36
|
+
readonly onPublished?: () => void;
|
|
37
|
+
} | {
|
|
38
|
+
readonly result: 'failed';
|
|
39
|
+
readonly error: unknown;
|
|
31
40
|
}>, signal: AbortSignal): Promise<ServiceUserSpotOperationResult>;
|
|
32
41
|
}
|