@olane/o-node 0.7.12-alpha.3 → 0.7.12-alpha.31
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/o-core/src/connection/o-response.d.ts +12 -0
- package/dist/o-core/src/connection/o-response.d.ts.map +1 -0
- package/dist/o-core/src/connection/o-response.js +18 -0
- package/dist/o-core/src/error/enums/codes.error.d.ts +20 -0
- package/dist/o-core/src/error/enums/codes.error.d.ts.map +1 -0
- package/dist/o-core/src/error/enums/codes.error.js +20 -0
- package/dist/o-core/src/error/interfaces/o-error.interface.d.ts +6 -0
- package/dist/o-core/src/error/interfaces/o-error.interface.d.ts.map +1 -0
- package/dist/o-core/src/error/interfaces/o-error.interface.js +1 -0
- package/dist/o-core/src/error/o-error.d.ts +15 -0
- package/dist/o-core/src/error/o-error.d.ts.map +1 -0
- package/dist/o-core/src/error/o-error.js +27 -0
- package/dist/o-core/src/streaming/index.d.ts +11 -0
- package/dist/o-core/src/streaming/index.d.ts.map +1 -0
- package/dist/o-core/src/streaming/index.js +14 -0
- package/dist/o-core/src/streaming/protocol-builder.d.ts +62 -0
- package/dist/o-core/src/streaming/protocol-builder.d.ts.map +1 -0
- package/dist/o-core/src/streaming/protocol-builder.js +93 -0
- package/dist/o-core/src/streaming/stream-config.d.ts +36 -0
- package/dist/o-core/src/streaming/stream-config.d.ts.map +1 -0
- package/dist/o-core/src/streaming/stream-config.js +19 -0
- package/dist/o-core/src/streaming/stream-handler.base.d.ts +85 -0
- package/dist/o-core/src/streaming/stream-handler.base.d.ts.map +1 -0
- package/dist/o-core/src/streaming/stream-handler.base.js +112 -0
- package/dist/o-core/src/streaming/stream-transport.interface.d.ts +61 -0
- package/dist/o-core/src/streaming/stream-transport.interface.d.ts.map +1 -0
- package/dist/o-core/src/streaming/stream-transport.interface.js +10 -0
- package/dist/o-core/src/utils/streaming.utils.d.ts +22 -0
- package/dist/o-core/src/utils/streaming.utils.d.ts.map +1 -0
- package/dist/o-core/src/utils/streaming.utils.js +45 -0
- package/dist/o-node/src/connection/index.d.ts +5 -0
- package/dist/o-node/src/connection/index.d.ts.map +1 -0
- package/dist/o-node/src/connection/index.js +4 -0
- package/dist/o-node/src/connection/interfaces/o-node-connection-manager.config.d.ts +6 -0
- package/dist/o-node/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -0
- package/dist/o-node/src/connection/interfaces/o-node-connection-manager.config.js +1 -0
- package/dist/o-node/src/connection/interfaces/o-node-connection.config.d.ts +6 -0
- package/dist/o-node/src/connection/interfaces/o-node-connection.config.d.ts.map +1 -0
- package/dist/o-node/src/connection/interfaces/o-node-connection.config.js +1 -0
- package/dist/o-node/src/connection/o-node-connection.d.ts +13 -0
- package/dist/o-node/src/connection/o-node-connection.d.ts.map +1 -0
- package/dist/o-node/src/connection/o-node-connection.js +80 -0
- package/dist/o-node/src/connection/o-node-connection.manager.d.ts +19 -0
- package/dist/o-node/src/connection/o-node-connection.manager.d.ts.map +1 -0
- package/dist/o-node/src/connection/o-node-connection.manager.js +93 -0
- package/dist/o-node/src/connection/o-stream.request.d.ts +11 -0
- package/dist/o-node/src/connection/o-stream.request.d.ts.map +1 -0
- package/dist/o-node/src/connection/o-stream.request.js +7 -0
- package/dist/o-node/src/index.d.ts +11 -0
- package/dist/o-node/src/index.d.ts.map +1 -0
- package/dist/o-node/src/index.js +10 -0
- package/dist/o-node/src/interfaces/i-heartbeatable-node.d.ts +49 -0
- package/dist/o-node/src/interfaces/i-heartbeatable-node.d.ts.map +1 -0
- package/dist/o-node/src/interfaces/i-heartbeatable-node.js +1 -0
- package/dist/o-node/src/interfaces/i-reconnectable-node.d.ts +46 -0
- package/dist/o-node/src/interfaces/i-reconnectable-node.d.ts.map +1 -0
- package/dist/o-node/src/interfaces/i-reconnectable-node.js +1 -0
- package/dist/o-node/src/interfaces/o-node.config.d.ts +66 -0
- package/dist/o-node/src/interfaces/o-node.config.d.ts.map +1 -0
- package/dist/o-node/src/interfaces/o-node.config.js +1 -0
- package/dist/o-node/src/interfaces/o-node.tool-config.d.ts +4 -0
- package/dist/o-node/src/interfaces/o-node.tool-config.d.ts.map +1 -0
- package/dist/o-node/src/interfaces/o-node.tool-config.js +1 -0
- package/dist/o-node/src/lib/network-activity.lib.d.ts +1 -0
- package/dist/o-node/src/lib/network-activity.lib.d.ts.map +1 -0
- package/dist/o-node/src/lib/network-activity.lib.js +34 -0
- package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts +62 -0
- package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -0
- package/dist/o-node/src/managers/o-connection-heartbeat.manager.js +213 -0
- package/dist/o-node/src/managers/o-reconnection.manager.d.ts +51 -0
- package/dist/o-node/src/managers/o-reconnection.manager.d.ts.map +1 -0
- package/dist/o-node/src/managers/o-reconnection.manager.js +266 -0
- package/dist/o-node/src/nodes/client.node.d.ts +7 -0
- package/dist/o-node/src/nodes/client.node.d.ts.map +1 -0
- package/dist/o-node/src/nodes/client.node.js +16 -0
- package/dist/o-node/src/nodes/index.d.ts +4 -0
- package/dist/o-node/src/nodes/index.d.ts.map +1 -0
- package/dist/o-node/src/nodes/index.js +3 -0
- package/dist/o-node/src/nodes/server.node.d.ts +7 -0
- package/dist/o-node/src/nodes/server.node.d.ts.map +1 -0
- package/dist/o-node/src/nodes/server.node.js +20 -0
- package/dist/o-node/src/nodes/websocket.node.d.ts +7 -0
- package/dist/o-node/src/nodes/websocket.node.d.ts.map +1 -0
- package/dist/o-node/src/nodes/websocket.node.js +18 -0
- package/dist/o-node/src/o-node.d.ts +73 -0
- package/dist/o-node/src/o-node.d.ts.map +1 -0
- package/dist/o-node/src/o-node.hierarchy-manager.d.ts +15 -0
- package/dist/o-node/src/o-node.hierarchy-manager.d.ts.map +1 -0
- package/dist/o-node/src/o-node.hierarchy-manager.js +15 -0
- package/dist/o-node/src/o-node.js +414 -0
- package/dist/o-node/src/o-node.notification-manager.d.ts +52 -0
- package/dist/o-node/src/o-node.notification-manager.d.ts.map +1 -0
- package/dist/o-node/src/o-node.notification-manager.js +185 -0
- package/dist/o-node/src/o-node.tool.d.ts +18 -0
- package/dist/o-node/src/o-node.tool.d.ts.map +1 -0
- package/dist/o-node/src/o-node.tool.js +90 -0
- package/dist/o-node/src/router/index.d.ts +6 -0
- package/dist/o-node/src/router/index.d.ts.map +1 -0
- package/dist/o-node/src/router/index.js +5 -0
- package/dist/o-node/src/router/interfaces/o-node-router.config.d.ts +3 -0
- package/dist/o-node/src/router/interfaces/o-node-router.config.d.ts.map +1 -0
- package/dist/o-node/src/router/interfaces/o-node-router.config.js +1 -0
- package/dist/o-node/src/router/interfaces/o-node-router.response.d.ts +8 -0
- package/dist/o-node/src/router/interfaces/o-node-router.response.d.ts.map +1 -0
- package/dist/o-node/src/router/interfaces/o-node-router.response.js +1 -0
- package/dist/o-node/src/router/o-node.address.d.ts +18 -0
- package/dist/o-node/src/router/o-node.address.d.ts.map +1 -0
- package/dist/o-node/src/router/o-node.address.js +29 -0
- package/dist/o-node/src/router/o-node.router.d.ts +45 -0
- package/dist/o-node/src/router/o-node.router.d.ts.map +1 -0
- package/dist/o-node/src/router/o-node.router.js +135 -0
- package/dist/o-node/src/router/o-node.routing-policy.d.ts +30 -0
- package/dist/o-node/src/router/o-node.routing-policy.d.ts.map +1 -0
- package/dist/o-node/src/router/o-node.routing-policy.js +57 -0
- package/dist/o-node/src/router/o-node.transport.d.ts +11 -0
- package/dist/o-node/src/router/o-node.transport.d.ts.map +1 -0
- package/dist/o-node/src/router/o-node.transport.js +18 -0
- package/dist/o-node/src/router/resolvers/index.d.ts +4 -0
- package/dist/o-node/src/router/resolvers/index.d.ts.map +1 -0
- package/dist/o-node/src/router/resolvers/index.js +3 -0
- package/dist/o-node/src/router/resolvers/o-node.leader-resolver-fallback.d.ts +8 -0
- package/dist/o-node/src/router/resolvers/o-node.leader-resolver-fallback.d.ts.map +1 -0
- package/dist/o-node/src/router/resolvers/o-node.leader-resolver-fallback.js +35 -0
- package/dist/{src/router/resolvers/o-node.child-resolver.d.ts → o-node/src/router/resolvers/o-node.resolver.d.ts} +2 -2
- package/dist/o-node/src/router/resolvers/o-node.resolver.d.ts.map +1 -0
- package/dist/o-node/src/router/resolvers/o-node.resolver.js +41 -0
- package/dist/o-node/src/router/resolvers/o-node.search-resolver.d.ts +170 -0
- package/dist/o-node/src/router/resolvers/o-node.search-resolver.d.ts.map +1 -0
- package/dist/o-node/src/router/resolvers/o-node.search-resolver.js +285 -0
- package/dist/o-node/src/router/route.request.d.ts +14 -0
- package/dist/o-node/src/router/route.request.d.ts.map +1 -0
- package/dist/o-node/src/router/route.request.js +1 -0
- package/dist/o-node/src/streaming/index.d.ts +10 -0
- package/dist/o-node/src/streaming/index.d.ts.map +1 -0
- package/dist/o-node/src/streaming/index.js +12 -0
- package/dist/o-node/src/streaming/libp2p-stream-transport.d.ts +50 -0
- package/dist/o-node/src/streaming/libp2p-stream-transport.d.ts.map +1 -0
- package/dist/o-node/src/streaming/libp2p-stream-transport.js +137 -0
- package/dist/o-node/src/streaming/node-stream-handler.d.ts +65 -0
- package/dist/o-node/src/streaming/node-stream-handler.d.ts.map +1 -0
- package/dist/o-node/src/streaming/node-stream-handler.js +101 -0
- package/dist/o-node/src/utils/circuit-breaker.d.ts +107 -0
- package/dist/o-node/src/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/o-node/src/utils/circuit-breaker.js +175 -0
- package/dist/o-node/src/utils/index.d.ts +5 -0
- package/dist/o-node/src/utils/index.d.ts.map +1 -0
- package/dist/o-node/src/utils/index.js +4 -0
- package/dist/o-node/src/utils/leader-request-wrapper.d.ts +66 -0
- package/dist/o-node/src/utils/leader-request-wrapper.d.ts.map +1 -0
- package/dist/o-node/src/utils/leader-request-wrapper.js +160 -0
- package/dist/o-node/src/utils/network.utils.d.ts +20 -0
- package/dist/o-node/src/utils/network.utils.d.ts.map +1 -0
- package/dist/o-node/src/utils/network.utils.js +74 -0
- package/dist/o-node/src/utils/stream.utils.d.ts +6 -0
- package/dist/o-node/src/utils/stream.utils.d.ts.map +1 -0
- package/dist/o-node/src/utils/stream.utils.js +27 -0
- package/dist/o-node/test/circuit-breaker.test.d.ts +2 -0
- package/dist/o-node/test/circuit-breaker.test.d.ts.map +1 -0
- package/dist/o-node/test/circuit-breaker.test.js +262 -0
- package/dist/o-node/test/leader-request-wrapper.test.d.ts +1 -0
- package/dist/o-node/test/leader-request-wrapper.test.d.ts.map +1 -0
- package/dist/o-node/test/leader-request-wrapper.test.js +246 -0
- package/dist/o-node/test/o-node.spec.d.ts +2 -0
- package/dist/o-node/test/o-node.spec.d.ts.map +1 -0
- package/dist/o-node/test/o-node.spec.js +20 -0
- package/dist/o-node/test/search-resolver.spec.d.ts +2 -0
- package/dist/o-node/test/search-resolver.spec.d.ts.map +1 -0
- package/dist/o-node/test/search-resolver.spec.js +693 -0
- package/dist/src/connection/o-node-connection.d.ts +1 -2
- package/dist/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.js +25 -18
- package/dist/src/connection/o-node-connection.manager.d.ts +3 -1
- package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.manager.js +45 -20
- package/dist/src/connection/o-stream.request.d.ts +11 -0
- package/dist/src/connection/o-stream.request.d.ts.map +1 -0
- package/dist/src/connection/o-stream.request.js +7 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/interfaces/i-heartbeatable-node.d.ts +49 -0
- package/dist/src/interfaces/i-heartbeatable-node.d.ts.map +1 -0
- package/dist/src/interfaces/i-heartbeatable-node.js +1 -0
- package/dist/src/interfaces/i-reconnectable-node.d.ts +46 -0
- package/dist/src/interfaces/i-reconnectable-node.d.ts.map +1 -0
- package/dist/src/interfaces/i-reconnectable-node.js +1 -0
- package/dist/src/interfaces/o-node.config.d.ts +42 -0
- package/dist/src/interfaces/o-node.config.d.ts.map +1 -1
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts +62 -0
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -0
- package/dist/src/managers/o-connection-heartbeat.manager.js +213 -0
- package/dist/src/managers/o-reconnection.manager.d.ts +51 -0
- package/dist/src/managers/o-reconnection.manager.d.ts.map +1 -0
- package/dist/src/managers/o-reconnection.manager.js +266 -0
- package/dist/src/o-node.d.ts +20 -2
- package/dist/src/o-node.d.ts.map +1 -1
- package/dist/src/o-node.js +161 -32
- package/dist/src/o-node.notification-manager.d.ts +52 -0
- package/dist/src/o-node.notification-manager.d.ts.map +1 -0
- package/dist/src/o-node.notification-manager.js +185 -0
- package/dist/src/o-node.tool.d.ts.map +1 -1
- package/dist/src/o-node.tool.js +29 -22
- package/dist/src/router/o-node.router.d.ts +1 -0
- package/dist/src/router/o-node.router.d.ts.map +1 -1
- package/dist/src/router/o-node.router.js +61 -5
- package/dist/src/router/o-node.routing-policy.d.ts.map +1 -1
- package/dist/src/router/o-node.routing-policy.js +7 -2
- package/dist/src/router/resolvers/o-node.resolver.d.ts.map +1 -1
- package/dist/src/router/resolvers/o-node.resolver.js +5 -1
- package/dist/src/router/resolvers/o-node.search-resolver.d.ts.map +1 -1
- package/dist/src/router/resolvers/o-node.search-resolver.js +40 -10
- package/dist/src/streaming/index.d.ts +10 -0
- package/dist/src/streaming/index.d.ts.map +1 -0
- package/dist/src/streaming/index.js +12 -0
- package/dist/src/streaming/libp2p-stream-transport.d.ts +50 -0
- package/dist/src/streaming/libp2p-stream-transport.d.ts.map +1 -0
- package/dist/src/streaming/libp2p-stream-transport.js +137 -0
- package/dist/src/streaming/node-stream-handler.d.ts +65 -0
- package/dist/src/streaming/node-stream-handler.d.ts.map +1 -0
- package/dist/src/streaming/node-stream-handler.js +101 -0
- package/dist/src/streaming/o-node-streaming-client.d.ts +33 -0
- package/dist/src/streaming/o-node-streaming-client.d.ts.map +1 -0
- package/dist/src/streaming/o-node-streaming-client.js +130 -0
- package/dist/src/utils/circuit-breaker.d.ts +107 -0
- package/dist/src/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/src/utils/circuit-breaker.js +175 -0
- package/dist/src/utils/circuit-breaker.test.d.ts +2 -0
- package/dist/src/utils/circuit-breaker.test.d.ts.map +1 -0
- package/dist/src/utils/circuit-breaker.test.js +262 -0
- package/dist/src/utils/index.d.ts +3 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +2 -0
- package/dist/src/utils/leader-request-wrapper.d.ts +66 -0
- package/dist/src/utils/leader-request-wrapper.d.ts.map +1 -0
- package/dist/src/utils/leader-request-wrapper.js +160 -0
- package/dist/src/utils/leader-request-wrapper.test.d.ts +1 -0
- package/dist/src/utils/leader-request-wrapper.test.d.ts.map +1 -0
- package/dist/src/utils/leader-request-wrapper.test.js +246 -0
- package/dist/src/utils/stream.utils.d.ts +6 -0
- package/dist/src/utils/stream.utils.d.ts.map +1 -0
- package/dist/src/utils/stream.utils.js +31 -0
- package/dist/test/circuit-breaker.test.d.ts +2 -0
- package/dist/test/circuit-breaker.test.d.ts.map +1 -0
- package/dist/test/circuit-breaker.test.js +262 -0
- package/dist/test/helpers/test-node.tool.d.ts +15 -0
- package/dist/test/helpers/test-node.tool.d.ts.map +1 -0
- package/dist/test/helpers/test-node.tool.js +27 -0
- package/dist/test/leader-request-wrapper.test.d.ts +1 -0
- package/dist/test/leader-request-wrapper.test.d.ts.map +1 -0
- package/dist/test/leader-request-wrapper.test.js +246 -0
- package/dist/test/search-resolver.spec.js +79 -0
- package/package.json +6 -6
- package/dist/src/router/resolvers/o-node.child-resolver.d.ts.map +0 -1
- package/dist/src/router/resolvers/o-node.child-resolver.js +0 -58
package/dist/src/o-node.js
CHANGED
|
@@ -9,6 +9,9 @@ import { oNodeConnectionManager } from './connection/o-node-connection.manager.j
|
|
|
9
9
|
import { oNodeResolver } from './router/resolvers/o-node.resolver.js';
|
|
10
10
|
import { oMethodResolver, oToolBase } from '@olane/o-tool';
|
|
11
11
|
import { oLeaderResolverFallback } from './router/index.js';
|
|
12
|
+
import { oNodeNotificationManager } from './o-node.notification-manager.js';
|
|
13
|
+
import { oConnectionHeartbeatManager } from './managers/o-connection-heartbeat.manager.js';
|
|
14
|
+
import { oReconnectionManager } from './managers/o-reconnection.manager.js';
|
|
12
15
|
export class oNode extends oToolBase {
|
|
13
16
|
constructor(config) {
|
|
14
17
|
super(config);
|
|
@@ -43,6 +46,9 @@ export class oNode extends oToolBase {
|
|
|
43
46
|
});
|
|
44
47
|
this.router = new oNodeRouter();
|
|
45
48
|
}
|
|
49
|
+
createNotificationManager() {
|
|
50
|
+
return new oNodeNotificationManager(this.p2pNode, this.hierarchyManager, this.address);
|
|
51
|
+
}
|
|
46
52
|
get staticAddress() {
|
|
47
53
|
return this.config.address;
|
|
48
54
|
}
|
|
@@ -60,6 +66,30 @@ export class oNode extends oToolBase {
|
|
|
60
66
|
this.logger.debug('Skipping unregistration, node is leader');
|
|
61
67
|
return;
|
|
62
68
|
}
|
|
69
|
+
// Notify parent we're stopping (best-effort, 2s timeout)
|
|
70
|
+
if (this.config.parent) {
|
|
71
|
+
try {
|
|
72
|
+
await Promise.race([
|
|
73
|
+
this.use(this.config.parent, {
|
|
74
|
+
method: 'notify',
|
|
75
|
+
params: {
|
|
76
|
+
eventType: 'node:stopping',
|
|
77
|
+
eventData: {
|
|
78
|
+
address: this.address.toString(),
|
|
79
|
+
reason: 'graceful_shutdown',
|
|
80
|
+
expectedDowntime: null,
|
|
81
|
+
},
|
|
82
|
+
source: this.address.toString(),
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 2000)),
|
|
86
|
+
]);
|
|
87
|
+
this.logger.debug('Notified parent of shutdown');
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.logger.warn('Failed to notify parent (will be detected by heartbeat):', error instanceof Error ? error.message : error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
63
93
|
if (!this.config.leader) {
|
|
64
94
|
this.logger.debug('No leader found, skipping unregistration');
|
|
65
95
|
return;
|
|
@@ -79,11 +109,21 @@ export class oNode extends oToolBase {
|
|
|
79
109
|
this.logger.debug('Skipping parent registration, node is leader');
|
|
80
110
|
return;
|
|
81
111
|
}
|
|
112
|
+
if (!this.parent?.libp2pTransports?.length) {
|
|
113
|
+
this.logger.debug('Parent has no transports, waiting for reconnection & leader ack');
|
|
114
|
+
if (this.parent?.toString() === oAddress.leader().toString()) {
|
|
115
|
+
this.parent.setTransports(this.leader?.libp2pTransports || []);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.logger.debug('Waiting for parent and reconnecting...');
|
|
119
|
+
await this.reconnectionManager?.waitForParentAndReconnect();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
82
122
|
// if no parent transports, register with the parent to get them
|
|
83
123
|
// TODO: should we remove the transports check to make this more consistent?
|
|
84
|
-
if (this.config.parent
|
|
85
|
-
this.logger.debug('Registering node with parent...', this.config.parent);
|
|
86
|
-
|
|
124
|
+
if (this.config.parent) {
|
|
125
|
+
this.logger.debug('Registering node with parent...', this.config.parent?.toString());
|
|
126
|
+
await this.use(this.config.parent, {
|
|
87
127
|
method: 'child_register',
|
|
88
128
|
params: {
|
|
89
129
|
address: this.address.toString(),
|
|
@@ -92,11 +132,22 @@ export class oNode extends oToolBase {
|
|
|
92
132
|
_token: this.config.joinToken,
|
|
93
133
|
},
|
|
94
134
|
});
|
|
95
|
-
const { parentTransports } = parentRegistration.result.data;
|
|
96
|
-
// update the parent transports
|
|
97
|
-
this.config.parent.setTransports(parentTransports.map((t) => new oNodeTransport(t)));
|
|
98
135
|
}
|
|
99
136
|
}
|
|
137
|
+
async registerLeader() {
|
|
138
|
+
const address = oAddress.registry();
|
|
139
|
+
const params = {
|
|
140
|
+
method: 'commit',
|
|
141
|
+
params: {
|
|
142
|
+
peerId: this.peerId.toString(),
|
|
143
|
+
address: this.address.toString(),
|
|
144
|
+
protocols: this.p2pNode.getProtocols(),
|
|
145
|
+
transports: this.transports,
|
|
146
|
+
staticAddress: this.staticAddress.toString(),
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
await this.use(address, params);
|
|
150
|
+
}
|
|
100
151
|
async register() {
|
|
101
152
|
if (this.type === NodeType.LEADER) {
|
|
102
153
|
this.logger.debug('Skipping registration, node is leader');
|
|
@@ -117,18 +168,7 @@ export class oNode extends oToolBase {
|
|
|
117
168
|
this.logger.debug('Registering node with leader...');
|
|
118
169
|
}
|
|
119
170
|
await this.registerParent();
|
|
120
|
-
|
|
121
|
-
const params = {
|
|
122
|
-
method: 'commit',
|
|
123
|
-
params: {
|
|
124
|
-
peerId: this.peerId.toString(),
|
|
125
|
-
address: this.address.toString(),
|
|
126
|
-
protocols: this.p2pNode.getProtocols(),
|
|
127
|
-
transports: this.transports,
|
|
128
|
-
staticAddress: this.staticAddress.toString(),
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
await this.use(address, params);
|
|
171
|
+
await this.registerLeader();
|
|
132
172
|
this.logger.debug('Registration successful');
|
|
133
173
|
}
|
|
134
174
|
extractMethod(address) {
|
|
@@ -136,11 +176,10 @@ export class oNode extends oToolBase {
|
|
|
136
176
|
}
|
|
137
177
|
async start() {
|
|
138
178
|
await super.start();
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// );
|
|
179
|
+
// Start heartbeat after node is running
|
|
180
|
+
if (this.connectionHeartbeatManager) {
|
|
181
|
+
await this.connectionHeartbeatManager.start();
|
|
182
|
+
}
|
|
144
183
|
}
|
|
145
184
|
async validateJoinRequest(request) {
|
|
146
185
|
return true;
|
|
@@ -157,6 +196,7 @@ export class oNode extends oToolBase {
|
|
|
157
196
|
listeners: (this.config.network?.listeners ||
|
|
158
197
|
defaultLibp2pConfig.listeners ||
|
|
159
198
|
[]).concat(`/memory/${uuidv4()}`), // ensure we allow for local in-memory communication
|
|
199
|
+
prometheusRegistry: this.config.network?.prometheusRegistry,
|
|
160
200
|
};
|
|
161
201
|
// if the seed is provided, use it to generate the private key
|
|
162
202
|
if (this.config.seed) {
|
|
@@ -190,12 +230,32 @@ export class oNode extends oToolBase {
|
|
|
190
230
|
// ];
|
|
191
231
|
// // let's make sure we only allow communication through the parent transports
|
|
192
232
|
params.connectionGater = {
|
|
233
|
+
denyDialPeer: (peerId) => {
|
|
234
|
+
// we can call the leader
|
|
235
|
+
if (this.config.leader?.libp2pTransports.some((t) => t.toPeerId() === peerId.toString())) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
// we can call our parent
|
|
239
|
+
if (this.parentPeerId === peerId.toString()) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
// we can call our children
|
|
243
|
+
if (this.hierarchyManager.children.some((c) => c.libp2pTransports.some((t) => t.toPeerId() === peerId.toString()))) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
// check for standalone node
|
|
247
|
+
if (!this.config.parent && !this.config.leader) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
},
|
|
193
252
|
// who can call us?
|
|
194
253
|
denyInboundEncryptedConnection: (peerId, maConn) => {
|
|
195
254
|
// deny all inbound connections unless they are from a parent transport
|
|
196
255
|
if (this.parentPeerId === peerId.toString()) {
|
|
197
256
|
return false;
|
|
198
257
|
}
|
|
258
|
+
// allow connections from children (for ping)
|
|
199
259
|
if (this.hierarchyManager.children.some((c) => c.libp2pTransports.some((t) => t.toPeerId() === peerId.toString()))) {
|
|
200
260
|
return false;
|
|
201
261
|
}
|
|
@@ -223,17 +283,13 @@ export class oNode extends oToolBase {
|
|
|
223
283
|
this.p2pNode = await createNode(params);
|
|
224
284
|
return this.p2pNode;
|
|
225
285
|
}
|
|
226
|
-
async connect(
|
|
286
|
+
async connect(config) {
|
|
227
287
|
if (!this.connectionManager) {
|
|
228
288
|
this.logger.error('Connection manager not initialized');
|
|
229
289
|
throw new Error('Node is not ready to connect to other nodes');
|
|
230
290
|
}
|
|
231
291
|
const connection = await this.connectionManager
|
|
232
|
-
.connect(
|
|
233
|
-
address: targetAddress,
|
|
234
|
-
nextHopAddress,
|
|
235
|
-
callerAddress: this.address,
|
|
236
|
-
})
|
|
292
|
+
.connect(config)
|
|
237
293
|
.catch((error) => {
|
|
238
294
|
// TODO: we need to handle this better and document
|
|
239
295
|
if (error.message === 'Can not dial self') {
|
|
@@ -246,6 +302,42 @@ export class oNode extends oToolBase {
|
|
|
246
302
|
}
|
|
247
303
|
return connection;
|
|
248
304
|
}
|
|
305
|
+
async initConnectionManager() {
|
|
306
|
+
this.connectionManager = new oNodeConnectionManager({
|
|
307
|
+
p2pNode: this.p2pNode,
|
|
308
|
+
defaultReadTimeoutMs: this.config.connectionTimeouts?.readTimeoutMs,
|
|
309
|
+
defaultDrainTimeoutMs: this.config.connectionTimeouts?.drainTimeoutMs,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
async initReconnectionManager() {
|
|
313
|
+
// Initialize reconnection manager
|
|
314
|
+
if (this.config.reconnection?.enabled !== false) {
|
|
315
|
+
this.reconnectionManager = new oReconnectionManager(this, {
|
|
316
|
+
enabled: true,
|
|
317
|
+
maxAttempts: this.config.reconnection?.maxAttempts ?? 10,
|
|
318
|
+
baseDelayMs: this.config.reconnection?.baseDelayMs ?? 5000,
|
|
319
|
+
maxDelayMs: this.config.reconnection?.maxDelayMs ?? 60000,
|
|
320
|
+
useLeaderFallback: this.config.reconnection?.useLeaderFallback ?? true,
|
|
321
|
+
parentDiscoveryIntervalMs: this.config.reconnection?.parentDiscoveryIntervalMs ?? 10000,
|
|
322
|
+
parentDiscoveryMaxDelayMs: this.config.reconnection?.parentDiscoveryMaxDelayMs ?? 60000,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
async hookInitializeFinished() { }
|
|
327
|
+
async hookStartFinished() {
|
|
328
|
+
// Initialize connection heartbeat manager
|
|
329
|
+
this.connectionHeartbeatManager = new oConnectionHeartbeatManager(this, {
|
|
330
|
+
enabled: this.config.connectionHeartbeat?.enabled ?? true,
|
|
331
|
+
intervalMs: this.config.connectionHeartbeat?.intervalMs ?? 15000,
|
|
332
|
+
timeoutMs: this.config.connectionHeartbeat?.timeoutMs ?? 15000,
|
|
333
|
+
failureThreshold: this.config.connectionHeartbeat?.failureThreshold ?? 3,
|
|
334
|
+
checkChildren: this.config.connectionHeartbeat?.checkChildren ?? false,
|
|
335
|
+
checkParent: this.config.connectionHeartbeat?.checkParent ?? true,
|
|
336
|
+
checkLeader: true,
|
|
337
|
+
});
|
|
338
|
+
this.logger.info(`Connection heartbeat config: leader=${this.connectionHeartbeatManager.getConfig().checkLeader}, ` +
|
|
339
|
+
`parent=${this.connectionHeartbeatManager.getConfig().checkParent}`);
|
|
340
|
+
}
|
|
249
341
|
async initialize() {
|
|
250
342
|
this.logger.debug('Initializing node...');
|
|
251
343
|
if (this.p2pNode && this.state !== NodeState.STOPPED) {
|
|
@@ -256,13 +348,13 @@ export class oNode extends oToolBase {
|
|
|
256
348
|
}
|
|
257
349
|
await this.createNode();
|
|
258
350
|
await this.initializeRouter();
|
|
351
|
+
// need to wait until our libpp2 node is initialized before calling super.initialize
|
|
352
|
+
await super.initialize();
|
|
259
353
|
this.logger.debug('Node initialized!', this.transports.map((t) => t.toString()));
|
|
260
354
|
this.address.setTransports(this.transports);
|
|
261
355
|
this.peerId = this.p2pNode.peerId;
|
|
262
356
|
// initialize connection manager
|
|
263
|
-
this.
|
|
264
|
-
p2pNode: this.p2pNode,
|
|
265
|
-
});
|
|
357
|
+
await this.initConnectionManager();
|
|
266
358
|
// initialize address resolution
|
|
267
359
|
this.router.addResolver(new oMethodResolver(this.address));
|
|
268
360
|
this.router.addResolver(new oNodeResolver(this.address));
|
|
@@ -271,12 +363,49 @@ export class oNode extends oToolBase {
|
|
|
271
363
|
this.logger.debug('Adding leader resolver fallback...');
|
|
272
364
|
this.router.addResolver(new oLeaderResolverFallback(this.address));
|
|
273
365
|
}
|
|
366
|
+
// initialize reconnection manager
|
|
367
|
+
await this.initReconnectionManager();
|
|
368
|
+
await this.hookInitializeFinished();
|
|
274
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Override use() to wrap leader/registry requests with retry logic
|
|
372
|
+
*/
|
|
373
|
+
// async use(
|
|
374
|
+
// address: oAddress,
|
|
375
|
+
// data?: {
|
|
376
|
+
// method?: string;
|
|
377
|
+
// params?: { [key: string]: any };
|
|
378
|
+
// id?: string;
|
|
379
|
+
// },
|
|
380
|
+
// options?: UseOptions,
|
|
381
|
+
// ): Promise<any> {
|
|
382
|
+
// // Wrap leader/registry requests with retry logic
|
|
383
|
+
// return super.use(address, data, options),
|
|
384
|
+
// address,
|
|
385
|
+
// data?.method,
|
|
386
|
+
// }
|
|
275
387
|
async teardown() {
|
|
388
|
+
// Stop heartbeat before parent teardown
|
|
389
|
+
if (this.connectionHeartbeatManager) {
|
|
390
|
+
await this.connectionHeartbeatManager.stop();
|
|
391
|
+
}
|
|
276
392
|
await this.unregister();
|
|
277
393
|
await super.teardown();
|
|
278
394
|
if (this.p2pNode) {
|
|
279
395
|
await this.p2pNode.stop();
|
|
280
396
|
}
|
|
281
397
|
}
|
|
398
|
+
// IHeartbeatableNode interface methods
|
|
399
|
+
getLeaders() {
|
|
400
|
+
return [this.leader];
|
|
401
|
+
}
|
|
402
|
+
getParents() {
|
|
403
|
+
return this.hierarchyManager.getParents();
|
|
404
|
+
}
|
|
405
|
+
getChildren() {
|
|
406
|
+
return this.hierarchyManager.getChildren();
|
|
407
|
+
}
|
|
408
|
+
removeChild(childAddress) {
|
|
409
|
+
this.hierarchyManager.removeChild(childAddress);
|
|
410
|
+
}
|
|
282
411
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Libp2p } from '@olane/o-config';
|
|
2
|
+
import { oNotificationManager } from '@olane/o-core';
|
|
3
|
+
import { oNodeAddress } from './router/o-node.address.js';
|
|
4
|
+
import { oNodeHierarchyManager } from './o-node.hierarchy-manager.js';
|
|
5
|
+
/**
|
|
6
|
+
* libp2p-specific implementation of oNotificationManager
|
|
7
|
+
* Wraps libp2p events and enriches them with Olane context
|
|
8
|
+
*/
|
|
9
|
+
export declare class oNodeNotificationManager extends oNotificationManager {
|
|
10
|
+
private p2pNode;
|
|
11
|
+
private hierarchyManager;
|
|
12
|
+
private address;
|
|
13
|
+
constructor(p2pNode: Libp2p, hierarchyManager: oNodeHierarchyManager, address: oNodeAddress);
|
|
14
|
+
/**
|
|
15
|
+
* Wire up libp2p event listeners
|
|
16
|
+
*/
|
|
17
|
+
protected setupListeners(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Handle peer connect event from libp2p
|
|
20
|
+
*/
|
|
21
|
+
private handlePeerConnect;
|
|
22
|
+
/**
|
|
23
|
+
* Handle peer disconnect event from libp2p
|
|
24
|
+
*/
|
|
25
|
+
private handlePeerDisconnect;
|
|
26
|
+
/**
|
|
27
|
+
* Handle peer discovery event from libp2p
|
|
28
|
+
*/
|
|
29
|
+
private handlePeerDiscovery;
|
|
30
|
+
/**
|
|
31
|
+
* Handle connection open event from libp2p
|
|
32
|
+
*/
|
|
33
|
+
private handleConnectionOpen;
|
|
34
|
+
/**
|
|
35
|
+
* Handle connection close event from libp2p
|
|
36
|
+
*/
|
|
37
|
+
private handleConnectionClose;
|
|
38
|
+
/**
|
|
39
|
+
* Try to resolve a libp2p peer ID to an Olane address
|
|
40
|
+
* Checks hierarchy manager for known peers
|
|
41
|
+
*/
|
|
42
|
+
private peerIdToAddress;
|
|
43
|
+
/**
|
|
44
|
+
* Check if an address is a direct child
|
|
45
|
+
*/
|
|
46
|
+
private isChild;
|
|
47
|
+
/**
|
|
48
|
+
* Check if an address is a parent
|
|
49
|
+
*/
|
|
50
|
+
private isParent;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=o-node.notification-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"o-node.notification-manager.d.ts","sourceRoot":"","sources":["../../src/o-node.notification-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EACL,oBAAoB,EAQrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,oBAAoB;IAE9D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,OAAO;gBAFP,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,qBAAqB,EACvC,OAAO,EAAE,YAAY;IAK/B;;OAEG;IACH,SAAS,CAAC,cAAc,IAAI,IAAI;IAgChC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkDzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoD5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAkCvB;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;OAEG;IACH,OAAO,CAAC,QAAQ;CAKjB"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { oNotificationManager, NodeConnectedEvent, NodeDisconnectedEvent, NodeDiscoveredEvent, ChildJoinedEvent, ChildLeftEvent, ParentConnectedEvent, ParentDisconnectedEvent, } from '@olane/o-core';
|
|
2
|
+
/**
|
|
3
|
+
* libp2p-specific implementation of oNotificationManager
|
|
4
|
+
* Wraps libp2p events and enriches them with Olane context
|
|
5
|
+
*/
|
|
6
|
+
export class oNodeNotificationManager extends oNotificationManager {
|
|
7
|
+
constructor(p2pNode, hierarchyManager, address) {
|
|
8
|
+
super();
|
|
9
|
+
this.p2pNode = p2pNode;
|
|
10
|
+
this.hierarchyManager = hierarchyManager;
|
|
11
|
+
this.address = address;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Wire up libp2p event listeners
|
|
15
|
+
*/
|
|
16
|
+
setupListeners() {
|
|
17
|
+
this.logger.debug('Setting up libp2p event listeners...');
|
|
18
|
+
// Peer connection events
|
|
19
|
+
this.p2pNode.addEventListener('peer:connect', this.handlePeerConnect.bind(this));
|
|
20
|
+
this.p2pNode.addEventListener('peer:disconnect', this.handlePeerDisconnect.bind(this));
|
|
21
|
+
// Peer discovery events
|
|
22
|
+
this.p2pNode.addEventListener('peer:discovery', this.handlePeerDiscovery.bind(this));
|
|
23
|
+
// Connection events
|
|
24
|
+
this.p2pNode.addEventListener('connection:open', this.handleConnectionOpen.bind(this));
|
|
25
|
+
this.p2pNode.addEventListener('connection:close', this.handleConnectionClose.bind(this));
|
|
26
|
+
this.logger.debug('libp2p event listeners configured');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Handle peer connect event from libp2p
|
|
30
|
+
*/
|
|
31
|
+
handlePeerConnect(evt) {
|
|
32
|
+
const peerId = evt.detail;
|
|
33
|
+
// this.logger.debug(`Peer connected: ${peerId.toString()}`);
|
|
34
|
+
// Try to resolve peer ID to Olane address
|
|
35
|
+
const nodeAddress = this.peerIdToAddress(peerId.toString());
|
|
36
|
+
if (!nodeAddress) {
|
|
37
|
+
// this.logger.debug(
|
|
38
|
+
// `Could not resolve peer ID ${peerId.toString()} to address`,
|
|
39
|
+
// );
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Emit generic node connected event
|
|
43
|
+
this.emit(new NodeConnectedEvent({
|
|
44
|
+
source: this.address,
|
|
45
|
+
nodeAddress,
|
|
46
|
+
connectionMetadata: {
|
|
47
|
+
peerId: peerId.toString(),
|
|
48
|
+
transport: 'libp2p',
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
// Check if this is a child node
|
|
52
|
+
if (this.isChild(nodeAddress)) {
|
|
53
|
+
// this.logger.debug(`Child node connected: ${nodeAddress.toString()}`);
|
|
54
|
+
this.emit(new ChildJoinedEvent({
|
|
55
|
+
source: this.address,
|
|
56
|
+
childAddress: nodeAddress,
|
|
57
|
+
parentAddress: this.address,
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
// Check if this is a parent node
|
|
61
|
+
if (this.isParent(nodeAddress)) {
|
|
62
|
+
// this.logger.debug(`Parent node connected: ${nodeAddress.toString()}`);
|
|
63
|
+
this.emit(new ParentConnectedEvent({
|
|
64
|
+
source: this.address,
|
|
65
|
+
parentAddress: nodeAddress,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Handle peer disconnect event from libp2p
|
|
71
|
+
*/
|
|
72
|
+
handlePeerDisconnect(evt) {
|
|
73
|
+
const peerId = evt.detail;
|
|
74
|
+
// this.logger.debug(`Peer disconnected: ${peerId.toString()}`);
|
|
75
|
+
// Try to resolve peer ID to Olane address
|
|
76
|
+
const nodeAddress = this.peerIdToAddress(peerId.toString());
|
|
77
|
+
if (!nodeAddress) {
|
|
78
|
+
// this.logger.debug(
|
|
79
|
+
// `Could not resolve peer ID ${peerId.toString()} to address`,
|
|
80
|
+
// );
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Emit generic node disconnected event
|
|
84
|
+
this.emit(new NodeDisconnectedEvent({
|
|
85
|
+
source: this.address,
|
|
86
|
+
nodeAddress,
|
|
87
|
+
reason: 'peer_disconnected',
|
|
88
|
+
}));
|
|
89
|
+
// Check if this is a child node
|
|
90
|
+
if (this.isChild(nodeAddress)) {
|
|
91
|
+
this.logger.debug(`Child node disconnected: ${nodeAddress.toString()}`);
|
|
92
|
+
this.emit(new ChildLeftEvent({
|
|
93
|
+
source: this.address,
|
|
94
|
+
childAddress: nodeAddress,
|
|
95
|
+
parentAddress: this.address,
|
|
96
|
+
reason: 'peer_disconnected',
|
|
97
|
+
}));
|
|
98
|
+
// Optionally remove from hierarchy (auto-cleanup)
|
|
99
|
+
// this.hierarchyManager.removeChild(nodeAddress);
|
|
100
|
+
}
|
|
101
|
+
// Check if this is a parent node
|
|
102
|
+
if (this.isParent(nodeAddress)) {
|
|
103
|
+
this.logger.debug(`Parent node disconnected: ${nodeAddress.toString()}`);
|
|
104
|
+
this.emit(new ParentDisconnectedEvent({
|
|
105
|
+
source: this.address,
|
|
106
|
+
parentAddress: nodeAddress,
|
|
107
|
+
reason: 'peer_disconnected',
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Handle peer discovery event from libp2p
|
|
113
|
+
*/
|
|
114
|
+
handlePeerDiscovery(evt) {
|
|
115
|
+
const peerInfo = evt.detail;
|
|
116
|
+
// this.logger.debug(`Peer discovered: ${peerInfo.id.toString()}`);
|
|
117
|
+
// Try to resolve peer ID to Olane address
|
|
118
|
+
const nodeAddress = this.peerIdToAddress(peerInfo.id.toString());
|
|
119
|
+
if (!nodeAddress) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this.emit(new NodeDiscoveredEvent({
|
|
123
|
+
source: this.address,
|
|
124
|
+
nodeAddress,
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Handle connection open event from libp2p
|
|
129
|
+
*/
|
|
130
|
+
handleConnectionOpen(evt) {
|
|
131
|
+
// do nothing for now
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Handle connection close event from libp2p
|
|
135
|
+
*/
|
|
136
|
+
handleConnectionClose(evt) {
|
|
137
|
+
// do nothing for now
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Try to resolve a libp2p peer ID to an Olane address
|
|
141
|
+
* Checks hierarchy manager for known peers
|
|
142
|
+
*/
|
|
143
|
+
peerIdToAddress(peerId) {
|
|
144
|
+
// Check children
|
|
145
|
+
for (const child of this.hierarchyManager.children) {
|
|
146
|
+
const childTransports = child.transports;
|
|
147
|
+
for (const transport of childTransports) {
|
|
148
|
+
if (transport.toString().includes(peerId)) {
|
|
149
|
+
return child;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Check parents
|
|
154
|
+
for (const parent of this.hierarchyManager.parents) {
|
|
155
|
+
const parentTransports = parent.transports;
|
|
156
|
+
for (const transport of parentTransports) {
|
|
157
|
+
if (transport.toString().includes(peerId)) {
|
|
158
|
+
return parent;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Check leaders
|
|
163
|
+
for (const leader of this.hierarchyManager.leaders) {
|
|
164
|
+
const leaderTransports = leader.transports;
|
|
165
|
+
for (const transport of leaderTransports) {
|
|
166
|
+
if (transport.toString().includes(peerId)) {
|
|
167
|
+
return leader;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check if an address is a direct child
|
|
175
|
+
*/
|
|
176
|
+
isChild(address) {
|
|
177
|
+
return this.hierarchyManager.children.some((child) => child.toString() === address.toString());
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if an address is a parent
|
|
181
|
+
*/
|
|
182
|
+
isParent(address) {
|
|
183
|
+
return this.hierarchyManager.parents.some((parent) => parent.toString() === address.toString());
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAGR,QAAQ,
|
|
1
|
+
{"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAGR,QAAQ,EAIT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;;AAIrD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IACzC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAQhC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCnE,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ9B,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CA2B5D"}
|
package/dist/src/o-node.tool.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { CoreUtils,
|
|
1
|
+
import { CoreUtils, oRequest, ResponseBuilder, ChildJoinedEvent, } from '@olane/o-core';
|
|
2
2
|
import { oTool } from '@olane/o-tool';
|
|
3
3
|
import { oServerNode } from './nodes/server.node.js';
|
|
4
4
|
import { oNodeTransport } from './router/o-node.transport.js';
|
|
5
|
+
import { oNodeAddress } from './router/o-node.address.js';
|
|
5
6
|
/**
|
|
6
7
|
* oTool is a mixin that extends the base class and implements the oTool interface
|
|
7
8
|
* @param Base - The base class to extend
|
|
@@ -24,35 +25,32 @@ export class oNodeTool extends oTool(oServerNode) {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
async handleStream(stream, connection) {
|
|
27
|
-
|
|
28
|
+
// CRITICAL: Attach message listener immediately to prevent buffer overflow (libp2p v3)
|
|
29
|
+
// Per libp2p migration guide: "If no message event handler is added, streams will
|
|
30
|
+
// buffer incoming data until a pre-configured limit is reached, after which the stream will be reset."
|
|
31
|
+
const messageHandler = async (event) => {
|
|
28
32
|
if (!event.data) {
|
|
29
33
|
this.logger.warn('Malformed event data');
|
|
30
34
|
return;
|
|
31
35
|
}
|
|
32
36
|
const requestConfig = await CoreUtils.processStream(event);
|
|
33
37
|
const request = new oRequest(requestConfig);
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
: new oError(oErrorCodes.UNKNOWN, error.message);
|
|
41
|
-
return {
|
|
42
|
-
error: responseError.toJSON(),
|
|
43
|
-
};
|
|
44
|
-
});
|
|
45
|
-
if (success) {
|
|
46
|
-
this.metrics.successCount++;
|
|
38
|
+
// Use ResponseBuilder with automatic error handling and metrics tracking
|
|
39
|
+
const responseBuilder = ResponseBuilder.create().withMetrics(this.metrics);
|
|
40
|
+
let response;
|
|
41
|
+
try {
|
|
42
|
+
const result = await this.execute(request, stream);
|
|
43
|
+
response = await responseBuilder.build(request, result, null);
|
|
47
44
|
}
|
|
48
|
-
|
|
49
|
-
this.
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.logger.error('Error executing tool: ', request.toString(), error, typeof error);
|
|
47
|
+
response = await responseBuilder.buildError(request, error);
|
|
50
48
|
}
|
|
51
|
-
//
|
|
52
|
-
const response = CoreUtils.buildResponse(request, result, result?.error);
|
|
53
|
-
// add the request method to the response
|
|
49
|
+
// Send the response
|
|
54
50
|
await CoreUtils.sendResponse(response, stream);
|
|
55
|
-
}
|
|
51
|
+
};
|
|
52
|
+
// Attach listener synchronously before any async operations
|
|
53
|
+
stream.addEventListener('message', messageHandler);
|
|
56
54
|
}
|
|
57
55
|
async _tool_identify() {
|
|
58
56
|
return {
|
|
@@ -64,8 +62,17 @@ export class oNodeTool extends oTool(oServerNode) {
|
|
|
64
62
|
async _tool_child_register(request) {
|
|
65
63
|
this.logger.debug('Child register: ', request.params);
|
|
66
64
|
const { address, transports } = request.params;
|
|
67
|
-
const childAddress = new
|
|
65
|
+
const childAddress = new oNodeAddress(address, transports.map((t) => new oNodeTransport(t)));
|
|
66
|
+
// Add child to hierarchy
|
|
68
67
|
this.hierarchyManager.addChild(childAddress);
|
|
68
|
+
// Emit child joined event
|
|
69
|
+
if (this.notificationManager) {
|
|
70
|
+
this.notificationManager.emit(new ChildJoinedEvent({
|
|
71
|
+
source: this.address,
|
|
72
|
+
childAddress,
|
|
73
|
+
parentAddress: this.address,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
69
76
|
return {
|
|
70
77
|
message: `Child node registered with parent! ${childAddress.toString()}`,
|
|
71
78
|
parentTransports: this.parentTransports.map((t) => t.toString()),
|
|
@@ -17,6 +17,7 @@ export declare class oNodeRouter extends oToolRouter {
|
|
|
17
17
|
protected forward(address: oNodeAddress, request: oRouterRequest, node: oNode): Promise<any>;
|
|
18
18
|
/**
|
|
19
19
|
* Executes a request locally when routing to self.
|
|
20
|
+
* Now uses ResponseBuilder for consistency with useSelf() behavior.
|
|
20
21
|
*/
|
|
21
22
|
private executeSelfRouting;
|
|
22
23
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node.router.d.ts","sourceRoot":"","sources":["../../../src/router/o-node.router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAML,cAAc,
|
|
1
|
+
{"version":3,"file":"o-node.router.d.ts","sourceRoot":"","sources":["../../../src/router/o-node.router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAML,cAAc,EAGd,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5C,qBAAa,WAAY,SAAQ,WAAW;IAC1C,OAAO,CAAC,aAAa,CAAqB;;IAO1C;;;;;;;;OAQG;cACa,OAAO,CACrB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,KAAK,GACV,OAAO,CAAC,GAAG,CAAC;IA6Bf;;;OAGG;YACW,kBAAkB;IA8DhC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;OAEG;YACW,eAAe;IA2C7B;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB3E;;;OAGG;IACH,UAAU,CAAC,qBAAqB,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO;CAGtE"}
|