@olane/o-node 0.7.12-alpha.66 → 0.7.12-alpha.68
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/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.js +2 -1
- package/dist/src/connection/stream-handler.d.ts +2 -1
- package/dist/src/connection/stream-handler.d.ts.map +1 -1
- package/dist/src/connection/stream-handler.js +9 -9
- package/dist/src/interfaces/o-node.config.d.ts +2 -16
- package/dist/src/interfaces/o-node.config.d.ts.map +1 -1
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts +13 -9
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -1
- package/dist/src/managers/o-connection-heartbeat.manager.js +47 -46
- package/dist/src/o-node.d.ts +1 -3
- package/dist/src/o-node.d.ts.map +1 -1
- package/dist/src/o-node.js +36 -21
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node-connection.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAEL,WAAW,EAGX,QAAQ,EACR,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,qBAAa,eAAgB,SAAQ,WAAW;IAIlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAHrD,aAAa,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;gBAER,MAAM,EAAE,qBAAqB;IAO5D,wBAAwB;IAYxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAmBlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"o-node-connection.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAEL,WAAW,EAGX,QAAQ,EACR,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,qBAAa,eAAgB,SAAQ,WAAW;IAIlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAHrD,aAAa,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;gBAER,MAAM,EAAE,qBAAqB;IAO5D,wBAAwB;IAYxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAmBlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IA0C/C,YAAY,CAAC,MAAM,EAAE,MAAM;IAQ3B,KAAK,CAAC,KAAK,EAAE,KAAK;IAMlB,KAAK;CAKZ"}
|
|
@@ -56,7 +56,8 @@ export class oNodeConnection extends oConnection {
|
|
|
56
56
|
await this.streamHandler.send(stream, data, streamConfig);
|
|
57
57
|
// Handle response using StreamHandler
|
|
58
58
|
// Pass request handler if configured to enable bidirectional stream processing
|
|
59
|
-
|
|
59
|
+
// Pass request ID to enable proper response correlation on shared streams
|
|
60
|
+
const response = await this.streamHandler.handleOutgoingStream(stream, this.emitter, streamConfig, this.config.requestHandler, request.id);
|
|
60
61
|
// Handle cleanup of the stream
|
|
61
62
|
await this.postTransmit(stream);
|
|
62
63
|
return response;
|
|
@@ -81,9 +81,10 @@ export declare class StreamHandler {
|
|
|
81
81
|
* @param emitter - Event emitter for chunk events
|
|
82
82
|
* @param config - Configuration including abort signal
|
|
83
83
|
* @param requestHandler - Optional handler for processing router requests received on this stream
|
|
84
|
+
* @param requestId - Optional request ID to filter responses (for stream reuse scenarios)
|
|
84
85
|
* @returns Promise that resolves with the final response
|
|
85
86
|
*/
|
|
86
|
-
handleOutgoingStream(stream: Stream, emitter: EventEmitter, config?: StreamHandlerConfig, requestHandler?: (request: oRequest, stream: Stream) => Promise<RunResult
|
|
87
|
+
handleOutgoingStream(stream: Stream, emitter: EventEmitter, config?: StreamHandlerConfig, requestHandler?: (request: oRequest, stream: Stream) => Promise<RunResult>, requestId?: string | number): Promise<oResponse>;
|
|
87
88
|
/**
|
|
88
89
|
* Forwards a request to the next hop and relays response chunks back
|
|
89
90
|
* This implements the middleware/proxy pattern for intermediate nodes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-handler.d.ts","sourceRoot":"","sources":["../../../src/connection/stream-handler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,QAAQ,EACR,SAAS,EAIT,MAAM,EAEP,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAI3B;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIhC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIjC;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7C;;;;;;OAMG;IACG,iBAAiB,CACrB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"stream-handler.d.ts","sourceRoot":"","sources":["../../../src/connection/stream-handler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,QAAQ,EACR,SAAS,EAIT,MAAM,EAEP,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAI3B;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIhC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIjC;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7C;;;;;;OAMG;IACG,iBAAiB,CACrB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,MAAM,CAAC;IAsClB;;;;;;OAMG;IACG,IAAI,CACR,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAiBhB;;;;;OAKG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5E;;;;;;;;OAQG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,GACtE,OAAO,CAAC,IAAI,CAAC;IAuChB;;;;;;OAMG;YACW,oBAAoB;IA4BlC;;;;;;;;;;;OAWG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,EACrB,MAAM,GAAE,mBAAwB,EAChC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,EAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAC1B,OAAO,CAAC,SAAS,CAAC;IA+GrB;;;;;;;OAOG;IACG,cAAc,CAClB,OAAO,EAAE,cAAc,EACvB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;CAyBjB"}
|
|
@@ -46,13 +46,6 @@ export class StreamHandler {
|
|
|
46
46
|
this.logger.debug('Reuse policy:', reusePolicy);
|
|
47
47
|
// Check for existing stream if reuse is enabled
|
|
48
48
|
if (reusePolicy === 'reuse') {
|
|
49
|
-
this.logger.debug('Reusing existing stream if we can find one. Stream insights:', JSON.stringify({
|
|
50
|
-
streamCount: connection.streams.length,
|
|
51
|
-
protocol: protocol,
|
|
52
|
-
}));
|
|
53
|
-
connection.streams.forEach((stream) => {
|
|
54
|
-
this.logger.debug('Stream re-use option:', stream.protocol, stream.status, stream.direction, stream.remoteWriteStatus, stream.writeStatus, stream.remoteReadStatus, stream.readStatus);
|
|
55
|
-
});
|
|
56
49
|
const existingStream = connection.streams.find((stream) => stream.status === 'open' &&
|
|
57
50
|
stream.protocol === protocol &&
|
|
58
51
|
stream.writeStatus === 'writable' &&
|
|
@@ -190,9 +183,10 @@ export class StreamHandler {
|
|
|
190
183
|
* @param emitter - Event emitter for chunk events
|
|
191
184
|
* @param config - Configuration including abort signal
|
|
192
185
|
* @param requestHandler - Optional handler for processing router requests received on this stream
|
|
186
|
+
* @param requestId - Optional request ID to filter responses (for stream reuse scenarios)
|
|
193
187
|
* @returns Promise that resolves with the final response
|
|
194
188
|
*/
|
|
195
|
-
async handleOutgoingStream(stream, emitter, config = {}, requestHandler) {
|
|
189
|
+
async handleOutgoingStream(stream, emitter, config = {}, requestHandler, requestId) {
|
|
196
190
|
return new Promise((resolve, reject) => {
|
|
197
191
|
let lastResponse;
|
|
198
192
|
const messageHandler = async (event) => {
|
|
@@ -211,9 +205,15 @@ export class StreamHandler {
|
|
|
211
205
|
}
|
|
212
206
|
if (this.isResponse(message)) {
|
|
213
207
|
const response = await CoreUtils.processStreamResponse(event);
|
|
208
|
+
// If requestId is provided, filter responses to only process those matching our request
|
|
209
|
+
// This prevents premature termination when multiple requests share the same stream
|
|
210
|
+
if (requestId !== undefined && response.id !== requestId) {
|
|
211
|
+
this.logger.debug(`Ignoring response for different request (expected: ${requestId}, received: ${response.id})`);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
214
|
// Emit chunk for streaming responses
|
|
215
215
|
emitter.emit('chunk', response);
|
|
216
|
-
// Check if this is the last chunk
|
|
216
|
+
// Check if this is the last chunk for THIS request
|
|
217
217
|
if (response.result._last || !response.result._isStreaming) {
|
|
218
218
|
lastResponse = response;
|
|
219
219
|
cleanup();
|
|
@@ -4,31 +4,17 @@ export interface oNodeConfig extends oCoreConfig {
|
|
|
4
4
|
leader: oNodeAddress | null;
|
|
5
5
|
parent: oNodeAddress | null;
|
|
6
6
|
/**
|
|
7
|
-
* Connection
|
|
8
|
-
* Detects dead connections
|
|
7
|
+
* Connection health monitoring configuration
|
|
8
|
+
* Detects dead connections by checking libp2p connection state
|
|
9
9
|
*/
|
|
10
10
|
connectionHeartbeat?: {
|
|
11
11
|
enabled?: boolean;
|
|
12
12
|
intervalMs?: number;
|
|
13
|
-
timeoutMs?: number;
|
|
14
13
|
failureThreshold?: number;
|
|
15
14
|
checkChildren?: boolean;
|
|
16
15
|
checkParent?: boolean;
|
|
17
16
|
checkLeader?: boolean;
|
|
18
17
|
};
|
|
19
|
-
/**
|
|
20
|
-
* Automatic reconnection configuration
|
|
21
|
-
* Handles parent connection failures and attempts to reconnect
|
|
22
|
-
*/
|
|
23
|
-
reconnection?: {
|
|
24
|
-
enabled?: boolean;
|
|
25
|
-
maxAttempts?: number;
|
|
26
|
-
baseDelayMs?: number;
|
|
27
|
-
maxDelayMs?: number;
|
|
28
|
-
useLeaderFallback?: boolean;
|
|
29
|
-
parentDiscoveryIntervalMs?: number;
|
|
30
|
-
parentDiscoveryMaxDelayMs?: number;
|
|
31
|
-
};
|
|
32
18
|
/**
|
|
33
19
|
* Connection timeout configuration
|
|
34
20
|
* Controls timeouts for stream read and drain operations in connections
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node.config.d.ts","sourceRoot":"","sources":["../../../src/interfaces/o-node.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5B;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,
|
|
1
|
+
{"version":3,"file":"o-node.config.d.ts","sourceRoot":"","sources":["../../../src/interfaces/o-node.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5B;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IAEF;;;OAGG;IACH,kBAAkB,CAAC,EAAE;QACnB;;;WAGG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB;;;WAGG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC"}
|
|
@@ -4,7 +4,6 @@ import { IHeartbeatableNode } from '../interfaces/i-heartbeatable-node.js';
|
|
|
4
4
|
export interface HeartbeatConfig {
|
|
5
5
|
enabled: boolean;
|
|
6
6
|
intervalMs: number;
|
|
7
|
-
timeoutMs: number;
|
|
8
7
|
failureThreshold: number;
|
|
9
8
|
checkChildren: boolean;
|
|
10
9
|
checkParent: boolean;
|
|
@@ -19,14 +18,15 @@ export interface ConnectionHealth {
|
|
|
19
18
|
status: 'healthy' | 'degraded' | 'dead';
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
|
-
* Connection
|
|
21
|
+
* Connection Health Monitor
|
|
23
22
|
*
|
|
24
|
-
*
|
|
25
|
-
* Continuously
|
|
23
|
+
* Monitors connection health by checking libp2p's connection state directly.
|
|
24
|
+
* Continuously checks parent and children connections to detect failures early.
|
|
26
25
|
*
|
|
27
26
|
* How it works:
|
|
28
|
-
* - Every `intervalMs`,
|
|
29
|
-
* -
|
|
27
|
+
* - Every `intervalMs`, checks connection status of all tracked connections
|
|
28
|
+
* - Uses libp2p's connection state (no network overhead from pings)
|
|
29
|
+
* - If connection is not open, increments failure counter
|
|
30
30
|
* - After `failureThreshold` failures, marks connection as dead
|
|
31
31
|
* - Emits events for degraded/recovered/dead connections
|
|
32
32
|
* - Automatically removes dead children from hierarchy
|
|
@@ -41,9 +41,13 @@ export declare class oConnectionHeartbeatManager extends oObject {
|
|
|
41
41
|
constructor(node: IHeartbeatableNode, config: HeartbeatConfig);
|
|
42
42
|
start(): Promise<void>;
|
|
43
43
|
stop(): Promise<void>;
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
private performHealthCheckCycle;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a connection to the given address is open by examining libp2p's connection state
|
|
47
|
+
* @returns true if an open connection exists, false otherwise
|
|
48
|
+
*/
|
|
49
|
+
private checkConnectionStatus;
|
|
50
|
+
private checkTarget;
|
|
47
51
|
private handleConnectionDead;
|
|
48
52
|
private emitConnectionDegradedEvent;
|
|
49
53
|
private emitConnectionRecoveredEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-connection-heartbeat.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-connection-heartbeat.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAOR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,
|
|
1
|
+
{"version":3,"file":"o-connection-heartbeat.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-connection-heartbeat.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAOR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,2BAA4B,SAAQ,OAAO;IAMpD,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,iBAAiB,CAAC,CAAiB;IAC3C,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,SAAS,CAAS;gBAGhB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,eAAe;IAK3B,KAAK;IAqBL,IAAI;YAQI,uBAAuB;IAgDrC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;YA8Bf,WAAW;IAoEzB,OAAO,CAAC,oBAAoB;IAyD5B,OAAO,CAAC,2BAA2B;IAmBnC,OAAO,CAAC,4BAA4B;IAiBpC;;OAEG;IACH,eAAe,IAAI,gBAAgB,EAAE;IAIrC;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,GAAG,SAAS;IAIxE;;OAEG;IACH,SAAS,IAAI,eAAe;CAG7B"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { oObject, ChildLeftEvent, ParentDisconnectedEvent, LeaderDisconnectedEvent, ConnectionDegradedEvent, ConnectionRecoveredEvent, oAddress, } from '@olane/o-core';
|
|
2
2
|
/**
|
|
3
|
-
* Connection
|
|
3
|
+
* Connection Health Monitor
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* Continuously
|
|
5
|
+
* Monitors connection health by checking libp2p's connection state directly.
|
|
6
|
+
* Continuously checks parent and children connections to detect failures early.
|
|
7
7
|
*
|
|
8
8
|
* How it works:
|
|
9
|
-
* - Every `intervalMs`,
|
|
10
|
-
* -
|
|
9
|
+
* - Every `intervalMs`, checks connection status of all tracked connections
|
|
10
|
+
* - Uses libp2p's connection state (no network overhead from pings)
|
|
11
|
+
* - If connection is not open, increments failure counter
|
|
11
12
|
* - After `failureThreshold` failures, marks connection as dead
|
|
12
13
|
* - Emits events for degraded/recovered/dead connections
|
|
13
14
|
* - Automatically removes dead children from hierarchy
|
|
@@ -23,15 +24,15 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
23
24
|
}
|
|
24
25
|
async start() {
|
|
25
26
|
if (!this.config.enabled) {
|
|
26
|
-
this.logger.debug('Connection
|
|
27
|
+
this.logger.debug('Connection health monitoring disabled');
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
this.logger.info(`Starting connection
|
|
30
|
-
`
|
|
30
|
+
this.logger.info(`Starting connection health monitoring: interval=${this.config.intervalMs}ms, ` +
|
|
31
|
+
`threshold=${this.config.failureThreshold}`);
|
|
31
32
|
// Immediate first check
|
|
32
|
-
await this.
|
|
33
|
+
await this.performHealthCheckCycle();
|
|
33
34
|
// Schedule recurring checks
|
|
34
|
-
this.heartbeatInterval = setInterval(() => this.
|
|
35
|
+
this.heartbeatInterval = setInterval(() => this.performHealthCheckCycle(), this.config.intervalMs);
|
|
35
36
|
}
|
|
36
37
|
async stop() {
|
|
37
38
|
if (this.heartbeatInterval) {
|
|
@@ -40,8 +41,8 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
40
41
|
}
|
|
41
42
|
this.healthMap.clear();
|
|
42
43
|
}
|
|
43
|
-
async
|
|
44
|
-
if (
|
|
44
|
+
async performHealthCheckCycle() {
|
|
45
|
+
if (this.isRunning) {
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
this.isRunning = true;
|
|
@@ -60,7 +61,7 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
60
61
|
// Use this.node.parent getter to get the current parent address with transports
|
|
61
62
|
// rather than getParents() which may have a stale reference
|
|
62
63
|
const parent = this.node.parent;
|
|
63
|
-
// make sure that we don't double
|
|
64
|
+
// make sure that we don't double check the leader
|
|
64
65
|
if (parent && parent?.toString() !== oAddress.leader().toString()) {
|
|
65
66
|
targets.push({ address: parent, role: 'parent' });
|
|
66
67
|
}
|
|
@@ -72,26 +73,38 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
72
73
|
targets.push({ address: child, role: 'child' });
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
|
-
//
|
|
76
|
-
await Promise.allSettled(targets.map((target) => this.
|
|
76
|
+
// Check all targets in parallel
|
|
77
|
+
await Promise.allSettled(targets.map((target) => this.checkTarget(target.address, target.role)));
|
|
77
78
|
this.isRunning = false;
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Check if a connection to the given address is open by examining libp2p's connection state
|
|
82
|
+
* @returns true if an open connection exists, false otherwise
|
|
83
|
+
*/
|
|
84
|
+
checkConnectionStatus(address) {
|
|
80
85
|
if (address.toString() === this.node.address.toString()) {
|
|
81
|
-
return
|
|
86
|
+
return true; // Self-connection is always "open"
|
|
82
87
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
if (!address.libp2pTransports.length) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
// Get peer ID from the address
|
|
93
|
+
const peerIdString = address.libp2pTransports[0].toPeerId();
|
|
94
|
+
// Get all connections to this peer from libp2p
|
|
95
|
+
// Note: Using 'as any' since converting to proper PeerId breaks browser implementation
|
|
96
|
+
const connections = this.node.p2pNode.getConnections(peerIdString);
|
|
97
|
+
// Check if any connection is open
|
|
98
|
+
return connections.some((conn) => conn.status === 'open');
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.logger.debug(`Error checking connection status for ${address}`, error);
|
|
102
|
+
return false;
|
|
89
103
|
}
|
|
90
|
-
return this.node.p2pNode.services.ping.ping(transport);
|
|
91
104
|
}
|
|
92
|
-
async
|
|
105
|
+
async checkTarget(address, role) {
|
|
93
106
|
if (!address.libp2pTransports.length) {
|
|
94
|
-
this.logger.debug(`${role} has no transports, skipping
|
|
107
|
+
this.logger.debug(`${role} has no transports, skipping health check`, address);
|
|
95
108
|
return;
|
|
96
109
|
}
|
|
97
110
|
const key = address.toString();
|
|
@@ -107,36 +120,24 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
107
120
|
};
|
|
108
121
|
this.healthMap.set(key, health);
|
|
109
122
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
//
|
|
114
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
115
|
-
setTimeout(() => reject(new Error('Ping timeout')), this.config.timeoutMs);
|
|
116
|
-
});
|
|
117
|
-
// Race between ping and timeout
|
|
118
|
-
// The ping service accepts PeerId as string or object
|
|
119
|
-
await Promise.race([this.doPing(address), timeoutPromise]);
|
|
120
|
-
const latency = Date.now() - startTime;
|
|
121
|
-
// Success - update health
|
|
123
|
+
// Check connection status using libp2p's connection state
|
|
124
|
+
const isOpen = this.checkConnectionStatus(address);
|
|
125
|
+
if (isOpen) {
|
|
126
|
+
// Connection is open - success
|
|
122
127
|
health.lastSuccessfulPing = Date.now();
|
|
123
128
|
health.consecutiveFailures = 0;
|
|
124
|
-
health.averageLatency =
|
|
125
|
-
health.averageLatency === 0
|
|
126
|
-
? latency
|
|
127
|
-
: health.averageLatency * 0.7 + latency * 0.3; // Exponential moving average
|
|
128
129
|
const previousStatus = health.status;
|
|
129
130
|
health.status = 'healthy';
|
|
130
131
|
// Emit recovery event if was degraded
|
|
131
132
|
if (previousStatus === 'degraded') {
|
|
132
|
-
this.logger.info(`Connection recovered: ${address}
|
|
133
|
+
this.logger.info(`Connection recovered: ${address}`);
|
|
133
134
|
this.emitConnectionRecoveredEvent(address, role);
|
|
134
135
|
}
|
|
135
|
-
// this.logger.debug(`Ping successful: ${address} (${latency}ms)`);
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
else {
|
|
138
|
+
// Connection is not open
|
|
138
139
|
health.consecutiveFailures++;
|
|
139
|
-
this.logger.warn(`
|
|
140
|
+
this.logger.warn(`Connection check failed: ${address} (failures: ${health.consecutiveFailures}/${this.config.failureThreshold})`);
|
|
140
141
|
// Update status based on failure count
|
|
141
142
|
if (health.consecutiveFailures >= this.config.failureThreshold) {
|
|
142
143
|
this.handleConnectionDead(address, role, health);
|
package/dist/src/o-node.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { oNodeConnection } from './connection/o-node-connection.js';
|
|
|
9
9
|
import { oNodeConnectionManager } from './connection/o-node-connection.manager.js';
|
|
10
10
|
import { oToolBase } from '@olane/o-tool';
|
|
11
11
|
import { oConnectionHeartbeatManager } from './managers/o-connection-heartbeat.manager.js';
|
|
12
|
-
import { oReconnectionManager } from './managers/o-reconnection.manager.js';
|
|
13
12
|
import { oNodeConnectionConfig } from './connection/index.js';
|
|
14
13
|
export declare class oNode extends oToolBase {
|
|
15
14
|
peerId: PeerId;
|
|
@@ -19,7 +18,6 @@ export declare class oNode extends oToolBase {
|
|
|
19
18
|
connectionManager: oNodeConnectionManager;
|
|
20
19
|
hierarchyManager: oNodeHierarchyManager;
|
|
21
20
|
connectionHeartbeatManager?: oConnectionHeartbeatManager;
|
|
22
|
-
reconnectionManager?: oReconnectionManager;
|
|
23
21
|
protected didRegister: boolean;
|
|
24
22
|
constructor(config: oNodeConfig);
|
|
25
23
|
get leader(): oNodeAddress | null;
|
|
@@ -32,6 +30,7 @@ export declare class oNode extends oToolBase {
|
|
|
32
30
|
get parentTransports(): oNodeTransport[];
|
|
33
31
|
get transports(): oNodeTransport[];
|
|
34
32
|
unregister(): Promise<void>;
|
|
33
|
+
setKeepAliveTag(address: oNodeAddress): Promise<void>;
|
|
35
34
|
registerParent(): Promise<void>;
|
|
36
35
|
registerLeader(): Promise<void>;
|
|
37
36
|
register(): Promise<void>;
|
|
@@ -46,7 +45,6 @@ export declare class oNode extends oToolBase {
|
|
|
46
45
|
protected createNode(): Promise<Libp2p>;
|
|
47
46
|
connect(config: oNodeConnectionConfig): Promise<oNodeConnection>;
|
|
48
47
|
initConnectionManager(): Promise<void>;
|
|
49
|
-
initReconnectionManager(): Promise<void>;
|
|
50
48
|
hookInitializeFinished(): Promise<void>;
|
|
51
49
|
hookStartFinished(): Promise<void>;
|
|
52
50
|
initialize(): Promise<void>;
|
package/dist/src/o-node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,MAAM,EACN,YAAY,
|
|
1
|
+
{"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
|
package/dist/src/o-node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createNode, defaultLibp2pConfig, } from '@olane/o-config';
|
|
1
|
+
import { createNode, defaultLibp2pConfig, KEEP_ALIVE, } from '@olane/o-config';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
3
|
import { oNodeRouter } from './router/o-node.router.js';
|
|
4
4
|
import { oNodeHierarchyManager } from './o-node.hierarchy-manager.js';
|
|
@@ -11,7 +11,6 @@ import { oMethodResolver, oToolBase } from '@olane/o-tool';
|
|
|
11
11
|
import { oLeaderResolverFallback } from './router/index.js';
|
|
12
12
|
import { oNodeNotificationManager } from './o-node.notification-manager.js';
|
|
13
13
|
import { oConnectionHeartbeatManager } from './managers/o-connection-heartbeat.manager.js';
|
|
14
|
-
import { oReconnectionManager } from './managers/o-reconnection.manager.js';
|
|
15
14
|
export class oNode extends oToolBase {
|
|
16
15
|
constructor(config) {
|
|
17
16
|
super(config);
|
|
@@ -106,6 +105,30 @@ export class oNode extends oToolBase {
|
|
|
106
105
|
this.logger.error('Failed to unregister from network:', error);
|
|
107
106
|
});
|
|
108
107
|
}
|
|
108
|
+
async setKeepAliveTag(address) {
|
|
109
|
+
if (!address || !address.libp2pTransports?.length) {
|
|
110
|
+
this.logger.warn('Address has no transports, skipping keep alive tag!', address);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const peers = await this.p2pNode.peerStore.all();
|
|
115
|
+
// find the peer that is already indexed rather than building the PeerId from the string value to avoid browser issues
|
|
116
|
+
const peer = peers.find((p) => p.id.toString() === address.libp2pTransports[0].toPeerId().toString());
|
|
117
|
+
if (!peer) {
|
|
118
|
+
this.logger.warn('Peer not found, skipping keep alive tag!', address);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
await this.p2pNode.peerStore.merge(peer.id, {
|
|
122
|
+
tags: {
|
|
123
|
+
[KEEP_ALIVE]: { value: 100 },
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
this.logger.debug('Set keep alive tag for peer:', peer.id.toString(), ' with address:', address.toString());
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
this.logger.error('Failed to set keep alive tag:', error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
109
132
|
async registerParent() {
|
|
110
133
|
if (this.type === NodeType.LEADER) {
|
|
111
134
|
this.logger.debug('Skipping parent registration, node is leader');
|
|
@@ -118,7 +141,7 @@ export class oNode extends oToolBase {
|
|
|
118
141
|
}
|
|
119
142
|
else {
|
|
120
143
|
this.logger.debug('Waiting for parent and reconnecting...');
|
|
121
|
-
await this.reconnectionManager?.waitForParentAndReconnect();
|
|
144
|
+
// await this.reconnectionManager?.waitForParentAndReconnect();
|
|
122
145
|
}
|
|
123
146
|
}
|
|
124
147
|
// if no parent transports, register with the parent to get them
|
|
@@ -134,6 +157,7 @@ export class oNode extends oToolBase {
|
|
|
134
157
|
_token: this.config.joinToken,
|
|
135
158
|
},
|
|
136
159
|
});
|
|
160
|
+
this.setKeepAliveTag(this.parent);
|
|
137
161
|
}
|
|
138
162
|
}
|
|
139
163
|
async registerLeader() {
|
|
@@ -149,6 +173,7 @@ export class oNode extends oToolBase {
|
|
|
149
173
|
},
|
|
150
174
|
};
|
|
151
175
|
await this.use(address, params);
|
|
176
|
+
this.setKeepAliveTag(this.leader);
|
|
152
177
|
}
|
|
153
178
|
async register() {
|
|
154
179
|
if (this.type === NodeType.LEADER) {
|
|
@@ -271,6 +296,13 @@ export class oNode extends oToolBase {
|
|
|
271
296
|
...(this.config.network?.connectionGater || {}),
|
|
272
297
|
};
|
|
273
298
|
}
|
|
299
|
+
params.connectionManager = {
|
|
300
|
+
...(params.connectionManager || {}),
|
|
301
|
+
reconnectRetries: 20,
|
|
302
|
+
reconnectRetryInterval: 2000,
|
|
303
|
+
reconnectBackoffFactor: 1.2,
|
|
304
|
+
maxParallelReconnects: 10,
|
|
305
|
+
};
|
|
274
306
|
// handle the address encapsulation
|
|
275
307
|
if (this.config.leader &&
|
|
276
308
|
!this.address.protocol.includes(this.config.leader.protocol)) {
|
|
@@ -311,27 +343,12 @@ export class oNode extends oToolBase {
|
|
|
311
343
|
runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
|
|
312
344
|
});
|
|
313
345
|
}
|
|
314
|
-
async initReconnectionManager() {
|
|
315
|
-
// Initialize reconnection manager
|
|
316
|
-
if (this.config.reconnection?.enabled !== false) {
|
|
317
|
-
this.reconnectionManager = new oReconnectionManager(this, {
|
|
318
|
-
enabled: true,
|
|
319
|
-
maxAttempts: this.config.reconnection?.maxAttempts ?? 10,
|
|
320
|
-
baseDelayMs: this.config.reconnection?.baseDelayMs ?? 5000,
|
|
321
|
-
maxDelayMs: this.config.reconnection?.maxDelayMs ?? 60000,
|
|
322
|
-
useLeaderFallback: this.config.reconnection?.useLeaderFallback ?? true,
|
|
323
|
-
parentDiscoveryIntervalMs: this.config.reconnection?.parentDiscoveryIntervalMs ?? 10000,
|
|
324
|
-
parentDiscoveryMaxDelayMs: this.config.reconnection?.parentDiscoveryMaxDelayMs ?? 60000,
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
346
|
async hookInitializeFinished() { }
|
|
329
347
|
async hookStartFinished() {
|
|
330
|
-
// Initialize connection
|
|
348
|
+
// Initialize connection health monitor
|
|
331
349
|
this.connectionHeartbeatManager = new oConnectionHeartbeatManager(this, {
|
|
332
350
|
enabled: this.config.connectionHeartbeat?.enabled ?? true,
|
|
333
351
|
intervalMs: this.config.connectionHeartbeat?.intervalMs ?? 15000,
|
|
334
|
-
timeoutMs: this.config.connectionHeartbeat?.timeoutMs ?? 15000,
|
|
335
352
|
failureThreshold: this.config.connectionHeartbeat?.failureThreshold ?? 3,
|
|
336
353
|
checkChildren: this.config.connectionHeartbeat?.checkChildren ?? false,
|
|
337
354
|
checkParent: this.config.connectionHeartbeat?.checkParent ?? true,
|
|
@@ -365,8 +382,6 @@ export class oNode extends oToolBase {
|
|
|
365
382
|
this.logger.debug('Adding leader resolver fallback...');
|
|
366
383
|
this.router.addResolver(new oLeaderResolverFallback(this.address));
|
|
367
384
|
}
|
|
368
|
-
// initialize reconnection manager
|
|
369
|
-
await this.initReconnectionManager();
|
|
370
385
|
await this.hookInitializeFinished();
|
|
371
386
|
}
|
|
372
387
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-node",
|
|
3
|
-
"version": "0.7.12-alpha.
|
|
3
|
+
"version": "0.7.12-alpha.68",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
"typescript": "5.4.5"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@olane/o-config": "0.7.12-alpha.
|
|
58
|
-
"@olane/o-core": "0.7.12-alpha.
|
|
59
|
-
"@olane/o-protocol": "0.7.12-alpha.
|
|
60
|
-
"@olane/o-tool": "0.7.12-alpha.
|
|
57
|
+
"@olane/o-config": "0.7.12-alpha.68",
|
|
58
|
+
"@olane/o-core": "0.7.12-alpha.68",
|
|
59
|
+
"@olane/o-protocol": "0.7.12-alpha.68",
|
|
60
|
+
"@olane/o-tool": "0.7.12-alpha.68",
|
|
61
61
|
"debug": "^4.4.1",
|
|
62
62
|
"dotenv": "^16.5.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "3ffe39de1430bed3673c13adc1b144f9016967dc"
|
|
65
65
|
}
|