@zlink-systems/framework 0.10.0 → 0.12.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/EndpointNotation.d.ts +5 -4
- package/dist/contracts/Configuration/EndpointNotation.js +5 -4
- package/dist/contracts/Configuration/InternalDefaults.d.ts +0 -1
- package/dist/contracts/Configuration/InternalDefaults.js +1 -2
- package/dist/contracts/Configuration/RegistrationNormalizers.js +1 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +2 -5
- package/dist/contracts/Configuration/RegistrationValidators.js +0 -1
- package/dist/contracts/Errors/ZLinkFrameworkException.d.ts +6 -7
- package/dist/contracts/Errors/ZLinkFrameworkException.js +6 -7
- package/dist/runtime/actors/actor-client.js +1 -1
- package/dist/runtime/actors/actor-mailbox.js +1 -5
- package/dist/runtime/backend/contracts/index.d.ts +2 -0
- package/dist/runtime/backend/mesh-completion-table.d.ts +1 -3
- package/dist/runtime/backend/mesh-completion-table.js +11 -15
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +11 -4
- package/dist/runtime/backend/mesh-dispatch-pump.js +201 -134
- package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +3 -4
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +51 -37
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +2 -2
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +16 -0
- package/dist/runtime/backend/node/node-event-loop-poller.js +49 -0
- package/dist/runtime/backend/node/node-raw-binding-port.js +24 -41
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +8 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +100 -107
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +3 -2
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +18 -67
- package/dist/runtime/backend/raw-binding-port.d.ts +1 -0
- package/dist/runtime/backend/runtime-values.d.ts +6 -1
- package/dist/runtime/backend/runtime-values.js +6 -0
- package/dist/runtime/channels/channel-dispatchers.js +2 -2
- package/dist/runtime/channels/channel-envelope.js +324 -121
- package/dist/runtime/channels/channel-multipart.d.ts +8 -1
- package/dist/runtime/channels/channel-outbound-operations.js +0 -2
- package/dist/runtime/channels/channel-receive-loops.d.ts +1 -3
- package/dist/runtime/channels/channel-receive-loops.js +25 -65
- package/dist/runtime/channels/channel-socket-registry.js +14 -1
- package/dist/runtime/channels/channel-transports.d.ts +2 -1
- package/dist/runtime/channels/channel-transports.js +12 -10
- package/dist/runtime/channels/client-server-location-runtime.js +15 -3
- package/dist/runtime/execution/serial-execution-queue.d.ts +5 -18
- package/dist/runtime/execution/serial-execution-queue.js +16 -80
- package/dist/runtime/foundation/event-loop-resources.d.ts +0 -3
- package/dist/runtime/foundation/event-loop-resources.js +2 -11
- package/dist/runtime/foundation/operation-registry.d.ts +2 -8
- package/dist/runtime/foundation/operation-registry.js +3 -21
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +19 -7
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +56 -10
- package/dist/runtime/foundation/service-mailbox.d.ts +1 -7
- package/dist/runtime/foundation/service-mailbox.js +3 -2
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +1 -1
- package/dist/runtime/foundation/service-stateful-registry.js +2 -2
- package/dist/runtime/foundation/service-stateful-runtime.js +14 -14
- package/dist/runtime/framework-errors-internal.d.ts +4 -4
- package/dist/runtime/framework-errors-internal.js +8 -10
- package/dist/runtime/host/actor-placement-coordinator.js +1 -1
- package/dist/runtime/host/index.js +1 -1
- package/dist/runtime/host/service-relocation-host-runtime.js +0 -4
- package/dist/runtime/host/spot-address-transport.js +1 -1
- package/dist/runtime/host/user-spot-creation-coordinator.js +1 -1
- package/dist/runtime/locations/location-store-repository.d.ts +1 -0
- package/dist/runtime/locations/location-store-repository.js +64 -75
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +0 -12
- package/dist/runtime/spots/spot-node-runtime-manager.js +6 -166
- package/dist/runtime/spots/spot-serial-turn-executor.js +1 -4
- package/dist/runtime/spots/spot-timer.d.ts +3 -0
- package/dist/runtime/spots/spot-timer.js +87 -18
- package/dist/runtime/streams/session-serial-executor.js +1 -3
- package/dist/runtime/streams/stream-session-runtime.d.ts +2 -2
- package/dist/runtime/streams/stream-session-runtime.js +13 -19
- package/dist/runtime/workers/index.d.ts +0 -1
- package/dist/runtime/workers/index.js +1 -9
- package/package.json +9 -3
- package/src/contracts/Configuration/EndpointNotation.ts +5 -4
- package/src/contracts/Configuration/InternalDefaults.ts +0 -1
- package/src/contracts/Configuration/RegistrationNormalizers.ts +2 -4
- package/src/contracts/Configuration/RegistrationTypes.ts +2 -5
- package/src/contracts/Configuration/RegistrationValidators.ts +0 -1
- package/src/contracts/Errors/ZLinkFrameworkException.ts +6 -7
- package/src/runtime/actors/actor-client.ts +1 -1
- package/src/runtime/actors/actor-mailbox.ts +1 -12
- package/src/runtime/backend/contracts/index.ts +2 -0
- package/src/runtime/backend/mesh-completion-table.ts +12 -23
- package/src/runtime/backend/mesh-dispatch-pump.ts +206 -138
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +66 -35
- package/src/runtime/backend/node/node-backend-adapter-support.ts +4 -4
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +2 -2
- package/src/runtime/backend/node/node-event-loop-poller.ts +55 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +30 -45
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +97 -110
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +23 -69
- package/src/runtime/backend/raw-binding-port.ts +1 -0
- package/src/runtime/backend/runtime-values.ts +13 -1
- package/src/runtime/channels/channel-dispatchers.ts +2 -2
- package/src/runtime/channels/channel-envelope.ts +379 -109
- package/src/runtime/channels/channel-multipart.ts +9 -1
- package/src/runtime/channels/channel-outbound-operations.ts +0 -1
- package/src/runtime/channels/channel-receive-loops.ts +24 -75
- package/src/runtime/channels/channel-socket-registry.ts +17 -1
- package/src/runtime/channels/channel-transports.ts +20 -10
- package/src/runtime/channels/client-server-location-runtime.ts +16 -2
- package/src/runtime/execution/serial-execution-queue.ts +16 -108
- package/src/runtime/foundation/event-loop-resources.ts +2 -11
- package/src/runtime/foundation/operation-registry.ts +2 -22
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +74 -19
- package/src/runtime/foundation/service-mailbox.ts +3 -13
- package/src/runtime/foundation/service-runtime-contracts.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +2 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +14 -14
- package/src/runtime/framework-errors-internal.ts +8 -10
- package/src/runtime/host/actor-placement-coordinator.ts +1 -1
- package/src/runtime/host/index.ts +2 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +0 -4
- package/src/runtime/host/spot-address-transport.ts +1 -1
- package/src/runtime/host/user-spot-creation-coordinator.ts +1 -1
- package/src/runtime/locations/location-store-repository.ts +118 -80
- package/src/runtime/spots/spot-node-runtime-manager.ts +13 -233
- package/src/runtime/spots/spot-serial-turn-executor.ts +1 -8
- package/src/runtime/spots/spot-timer.ts +109 -18
- package/src/runtime/streams/session-serial-executor.ts +1 -7
- package/src/runtime/streams/stream-session-runtime.ts +13 -17
- package/src/runtime/workers/index.ts +2 -17
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Socket } from '@zlink-systems/zlink';
|
|
1
2
|
import type { ZLinkBackendObject } from '../contracts';
|
|
2
3
|
import {
|
|
3
4
|
closeWithBusyRetry,
|
|
@@ -17,14 +18,14 @@ import {
|
|
|
17
18
|
type ZLinkBindingReplyOperation,
|
|
18
19
|
type ZLinkBindingAsyncSendOperation
|
|
19
20
|
} from './node-backend-adapter-support';
|
|
21
|
+
import { ZLinkNodeEventLoopPoller } from './node-event-loop-poller';
|
|
20
22
|
|
|
23
|
+
const eventLoopPollers = new WeakMap<object, ZLinkNodeEventLoopPoller>();
|
|
21
24
|
|
|
22
25
|
export function wrapSocket<T extends { close(): void }>(
|
|
23
|
-
nativeInstance: T
|
|
26
|
+
nativeInstance: T,
|
|
27
|
+
pollCompletion?: boolean
|
|
24
28
|
): T & ZLinkBackendObject {
|
|
25
|
-
const boundEndpoints = new Set<string>();
|
|
26
|
-
const connectedEndpoints = new Set<string>();
|
|
27
|
-
const peerRoutingIds = new Set<unknown>();
|
|
28
29
|
const socket = nativeInstance as T & {
|
|
29
30
|
options?: {
|
|
30
31
|
probe?: boolean;
|
|
@@ -40,32 +41,35 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
40
41
|
const hasRoutedPeer = hasRequest
|
|
41
42
|
&& typeof (nativeInstance as { reply?: unknown }).reply === 'function';
|
|
42
43
|
const hasStream = typeof (nativeInstance as { recvPacket?: unknown }).recvPacket === 'function';
|
|
44
|
+
const eventLoopPoller = pollCompletion === undefined
|
|
45
|
+
? undefined
|
|
46
|
+
: new ZLinkNodeEventLoopPoller(
|
|
47
|
+
nativeInstance as unknown as Socket,
|
|
48
|
+
pollCompletion,
|
|
49
|
+
() => {}
|
|
50
|
+
);
|
|
43
51
|
const adapter = {
|
|
44
52
|
nativeInstance,
|
|
45
53
|
async dispose(): Promise<void> {
|
|
54
|
+
eventLoopPoller?.dispose();
|
|
46
55
|
disableSocketLinger(nativeInstance);
|
|
47
|
-
closeSocketRoutes(nativeInstance, peerRoutingIds);
|
|
48
|
-
closeSocketEndpoints(nativeInstance, boundEndpoints, connectedEndpoints);
|
|
49
56
|
await closeWithBusyRetry(nativeInstance);
|
|
50
57
|
},
|
|
51
58
|
close(): void {
|
|
59
|
+
eventLoopPoller?.dispose();
|
|
52
60
|
nativeInstance.close();
|
|
53
61
|
},
|
|
54
62
|
bind(endpoint: string): void {
|
|
55
63
|
(nativeInstance as T & { bind(endpoint: string): void }).bind(endpoint);
|
|
56
|
-
boundEndpoints.add(endpoint);
|
|
57
64
|
},
|
|
58
65
|
unbind(endpoint: string): void {
|
|
59
66
|
(nativeInstance as T & { unbind(endpoint: string): void }).unbind(endpoint);
|
|
60
|
-
boundEndpoints.delete(endpoint);
|
|
61
67
|
},
|
|
62
68
|
connect(endpoint: string): void {
|
|
63
69
|
(nativeInstance as T & { connect(endpoint: string): void }).connect(endpoint);
|
|
64
|
-
connectedEndpoints.add(endpoint);
|
|
65
70
|
},
|
|
66
71
|
disconnect(endpoint: string): void {
|
|
67
72
|
(nativeInstance as T & { disconnect(endpoint: string): void }).disconnect(endpoint);
|
|
68
|
-
connectedEndpoints.delete(endpoint);
|
|
69
73
|
},
|
|
70
74
|
setChannelName(channelName: string): void {
|
|
71
75
|
const setChannelName = (nativeInstance as T & { setChannelName?: (value: string) => void }).setChannelName;
|
|
@@ -133,7 +137,6 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
133
137
|
send(...args: unknown[]): unknown {
|
|
134
138
|
if (hasStream) {
|
|
135
139
|
const [routingId, payload] = args as [unknown, unknown];
|
|
136
|
-
peerRoutingIds.add(routingId);
|
|
137
140
|
const operation = (nativeInstance as T & {
|
|
138
141
|
send(routingId: unknown): ZLinkBindingAsyncSendOperation;
|
|
139
142
|
}).send(toNativeRoutingId(routingId));
|
|
@@ -142,7 +145,6 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
142
145
|
}
|
|
143
146
|
if (hasRoutedPeer) {
|
|
144
147
|
const [routingId, payload] = args as [unknown, unknown];
|
|
145
|
-
peerRoutingIds.add(routingId);
|
|
146
148
|
return submitBindingAsyncSend(
|
|
147
149
|
(nativeInstance as T & { send(routingId: unknown): ZLinkBindingAsyncSendOperation })
|
|
148
150
|
.send(toNativeRoutingId(routingId)),
|
|
@@ -167,7 +169,6 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
167
169
|
},
|
|
168
170
|
submit(routingId: unknown, payload: unknown, _timeoutMs?: number): Promise<void> {
|
|
169
171
|
if (!hasStream) throw new TypeError('Async stream send requires a STREAM socket.');
|
|
170
|
-
peerRoutingIds.add(routingId);
|
|
171
172
|
return submitBindingAsyncSend(
|
|
172
173
|
(nativeInstance as T & { send(routingId: unknown): ZLinkBindingAsyncSendOperation })
|
|
173
174
|
.send(toNativeRoutingId(routingId)),
|
|
@@ -177,7 +178,6 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
177
178
|
request(...args: unknown[]): unknown {
|
|
178
179
|
if (hasRoutedPeer) {
|
|
179
180
|
const [routingId, payload, timeoutMs] = args as [unknown, unknown, number | undefined];
|
|
180
|
-
peerRoutingIds.add(routingId);
|
|
181
181
|
return submitBindingRequest(
|
|
182
182
|
(nativeInstance as T & { request(routingId: unknown): ZLinkBindingRequestOperation })
|
|
183
183
|
.request(toNativeRoutingId(routingId)),
|
|
@@ -197,7 +197,6 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
197
197
|
},
|
|
198
198
|
reply(...args: unknown[]): unknown {
|
|
199
199
|
const [routingId, replyToken, payload] = args as [unknown, unknown, unknown];
|
|
200
|
-
peerRoutingIds.add(routingId);
|
|
201
200
|
const operation = (nativeInstance as T & {
|
|
202
201
|
reply(routingId: unknown, replyToken: unknown): ZLinkBindingReplyOperation;
|
|
203
202
|
}).reply(toNativeRoutingId(routingId), replyToken);
|
|
@@ -287,9 +286,18 @@ export function wrapSocket<T extends { close(): void }>(
|
|
|
287
286
|
return false;
|
|
288
287
|
}
|
|
289
288
|
};
|
|
289
|
+
if (eventLoopPoller !== undefined) eventLoopPollers.set(adapter, eventLoopPoller);
|
|
290
290
|
return adapter as unknown as T & ZLinkBackendObject;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
export function nodeEventLoopPollerOf(socket: object): ZLinkNodeEventLoopPoller {
|
|
294
|
+
const poller = eventLoopPollers.get(socket);
|
|
295
|
+
if (poller === undefined) {
|
|
296
|
+
throw new TypeError('Node backend socket does not own an event-loop poller.');
|
|
297
|
+
}
|
|
298
|
+
return poller;
|
|
299
|
+
}
|
|
300
|
+
|
|
293
301
|
export function disconnectStreamPeer(
|
|
294
302
|
socket: { disconnectRid(routingId: unknown): void },
|
|
295
303
|
routingId: unknown
|
|
@@ -310,60 +318,6 @@ function requireSocketOptions<TOptions>(socket: { readonly options?: TOptions })
|
|
|
310
318
|
return socket.options;
|
|
311
319
|
}
|
|
312
320
|
|
|
313
|
-
function closeSocketRoutes(target: unknown, peerRoutingIds: Set<unknown>): void {
|
|
314
|
-
if (peerRoutingIds.size === 0 || !hasDisconnectRid(target)) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
for (const routingId of peerRoutingIds) {
|
|
318
|
-
try {
|
|
319
|
-
target.disconnectRid(toNativeRoutingId(routingId));
|
|
320
|
-
} catch (error) {
|
|
321
|
-
if (!isDisconnectRouteNotFoundError(error)) {
|
|
322
|
-
throw error;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
peerRoutingIds.delete(routingId);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export function isDisconnectRouteNotFoundError(error: unknown): boolean {
|
|
330
|
-
return isBindingNotFound(error) || isContextTerminatedError(error) || (
|
|
331
|
-
error instanceof Error && 'code' in error &&
|
|
332
|
-
((error as { code: unknown }).code === zlink.ConnectResult.NotFound ||
|
|
333
|
-
(error as { code: unknown }).code === zlink.ConnectResult.Busy ||
|
|
334
|
-
((error as { code: unknown }).code === zlink.ConnectResult.InternalError &&
|
|
335
|
-
/current state/i.test(error.message)))
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function hasDisconnectRid(target: unknown): target is { disconnectRid(routingId: unknown): void } {
|
|
340
|
-
return target !== null && typeof target === 'object' && 'disconnectRid' in target &&
|
|
341
|
-
typeof (target as { disconnectRid: unknown }).disconnectRid === 'function';
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function closeSocketEndpoints(target: unknown, boundEndpoints: Set<string>, connectedEndpoints: Set<string>): void {
|
|
345
|
-
for (const endpoint of connectedEndpoints) {
|
|
346
|
-
try {
|
|
347
|
-
(target as { disconnect(endpoint: string): void }).disconnect(endpoint);
|
|
348
|
-
} catch (error) {
|
|
349
|
-
if (!isEndpointCloseIgnorableError(error)) {
|
|
350
|
-
throw error;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
connectedEndpoints.delete(endpoint);
|
|
354
|
-
}
|
|
355
|
-
for (const endpoint of boundEndpoints) {
|
|
356
|
-
try {
|
|
357
|
-
(target as { unbind(endpoint: string): void }).unbind(endpoint);
|
|
358
|
-
} catch (error) {
|
|
359
|
-
if (!isEndpointCloseIgnorableError(error)) {
|
|
360
|
-
throw error;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
boundEndpoints.delete(endpoint);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
321
|
export function isEndpointCloseIgnorableError(error: unknown): boolean {
|
|
368
322
|
return isContextTerminatedError(error) || (
|
|
369
323
|
error instanceof Error && 'code' in error &&
|
|
@@ -68,10 +68,22 @@ export function isBackendNotConnectedError(error: unknown): boolean {
|
|
|
68
68
|
const result = error.result;
|
|
69
69
|
return result === SubmitResult.NotConnected || result === RequestResult.NotConnected;
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
export function isBackendRequestTimeoutError(error: unknown): boolean {
|
|
73
|
+
return isZLinkBackendResultError(error)
|
|
74
|
+
&& error.operation === 'request'
|
|
75
|
+
&& error.result === RequestResult.TimedOut;
|
|
76
|
+
}
|
|
71
77
|
export type ZLinkBackendMessageLike = Message | Buffer | Uint8Array | string;
|
|
78
|
+
/** Binding의 SendSubmission과 구조적으로 호환된다. binding 타입을 import 하지 않는다. */
|
|
79
|
+
export interface ZLinkBackendSendSubmission {
|
|
80
|
+
readonly admitted: Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
|
|
72
83
|
export interface ZLinkBackendSendSubmitBuilder {
|
|
73
84
|
message(message: ZLinkBackendMessageLike): ZLinkBackendSendSubmitBuilder;
|
|
74
|
-
|
|
85
|
+
// 제출 스냅샷을 그대로 돌려준다. admission을 기다리려면 .admitted를 await 한다.
|
|
86
|
+
submit(): ZLinkBackendSendSubmission;
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
export interface ZLinkBackendSendBuilder {
|
|
@@ -115,7 +115,7 @@ export class ZLinkChannelRequestDispatcher {
|
|
|
115
115
|
if (received.send === undefined) {
|
|
116
116
|
throw new ZLinkConfigurationException('Routed SPOT packet is missing a local SPOT delivery context.');
|
|
117
117
|
}
|
|
118
|
-
await appendParts(received.send(), received.parts).submit();
|
|
118
|
+
await appendParts(received.send(), received.parts).submit().admitted;
|
|
119
119
|
return true;
|
|
120
120
|
}
|
|
121
121
|
if (received.parts.length === 0 || received.parts[0].data().length === 0) {
|
|
@@ -523,7 +523,7 @@ export class ZLinkRoutePacketDispatcher {
|
|
|
523
523
|
if (received.send === undefined) {
|
|
524
524
|
throw new ZLinkConfigurationException('Routed SPOT packet is missing a local SPOT delivery context.');
|
|
525
525
|
}
|
|
526
|
-
return appendParts(received.send(), received.parts).submit();
|
|
526
|
+
return appendParts(received.send(), received.parts).submit().admitted;
|
|
527
527
|
}
|
|
528
528
|
return false;
|
|
529
529
|
}
|