mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-09 01:03:11 +00:00
implement peer-store re-bootstrapping
This commit is contained in:
parent
8f09f5fa5a
commit
8d773c4620
100
packages/core/src/lib/connection_manager/bootstrap_trigger.ts
Normal file
100
packages/core/src/lib/connection_manager/bootstrap_trigger.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { PeerId } from "@libp2p/interface";
|
||||
import { Libp2p } from "@waku/interfaces";
|
||||
import { Logger } from "@waku/utils";
|
||||
|
||||
type BootstrapTriggerConstructorOptions = {
|
||||
libp2p: Libp2p;
|
||||
};
|
||||
|
||||
interface IBootstrapTrigger {
|
||||
start(): void;
|
||||
stop(): void;
|
||||
}
|
||||
|
||||
const log = new Logger("bootstrap-trigger");
|
||||
|
||||
const DEFAULT_BOOTSTRAP_TIMEOUT_MS = 1000;
|
||||
|
||||
export class BootstrapTrigger implements IBootstrapTrigger {
|
||||
private readonly libp2p: Libp2p;
|
||||
private bootstrapTimeout: NodeJS.Timeout | null = null;
|
||||
|
||||
public constructor(options: BootstrapTriggerConstructorOptions) {
|
||||
this.libp2p = options.libp2p;
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
log.info("Starting bootstrap trigger");
|
||||
this.libp2p.addEventListener("peer:disconnect", this.onPeerDisconnectEvent);
|
||||
}
|
||||
|
||||
public stop(): void {
|
||||
log.info("Stopping bootstrap trigger");
|
||||
this.libp2p.removeEventListener(
|
||||
"peer:disconnect",
|
||||
this.onPeerDisconnectEvent
|
||||
);
|
||||
|
||||
if (this.bootstrapTimeout) {
|
||||
clearTimeout(this.bootstrapTimeout);
|
||||
this.bootstrapTimeout = null;
|
||||
log.info("Cleared pending bootstrap timeout");
|
||||
}
|
||||
}
|
||||
|
||||
private onPeerDisconnectEvent = (event: CustomEvent<PeerId>): void => {
|
||||
const peerId = event.detail;
|
||||
const connections = this.libp2p.getConnections();
|
||||
log.info(
|
||||
`Peer disconnected: ${peerId.toString()}, remaining connections: ${connections.length}`
|
||||
);
|
||||
|
||||
if (connections.length !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(
|
||||
`Last peer disconnected, scheduling bootstrap in ${DEFAULT_BOOTSTRAP_TIMEOUT_MS} milliseconds`
|
||||
);
|
||||
|
||||
if (this.bootstrapTimeout) {
|
||||
clearTimeout(this.bootstrapTimeout);
|
||||
}
|
||||
|
||||
this.bootstrapTimeout = setTimeout(() => {
|
||||
log.info("Triggering bootstrap after timeout");
|
||||
this.triggerBootstrap();
|
||||
this.bootstrapTimeout = null;
|
||||
}, DEFAULT_BOOTSTRAP_TIMEOUT_MS);
|
||||
};
|
||||
|
||||
private triggerBootstrap(): void {
|
||||
log.info("Triggering bootstrap discovery");
|
||||
|
||||
const bootstrapComponents = Object.values(this.libp2p.components.components)
|
||||
.filter((c) => !!c)
|
||||
.filter(
|
||||
(c: unknown) =>
|
||||
(c as { [Symbol.toStringTag]: string })[Symbol.toStringTag] ===
|
||||
"@waku/bootstrap"
|
||||
);
|
||||
|
||||
if (bootstrapComponents.length === 0) {
|
||||
log.warn("No bootstrap components found to trigger");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(
|
||||
`Found ${bootstrapComponents.length} bootstrap components, starting them`
|
||||
);
|
||||
|
||||
bootstrapComponents.forEach((component) => {
|
||||
try {
|
||||
(component as { start: () => void }).start();
|
||||
log.info("Successfully started bootstrap component");
|
||||
} catch (error) {
|
||||
log.error("Failed to start bootstrap component", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ import {
|
||||
import { Libp2p } from "@waku/interfaces";
|
||||
import { Logger } from "@waku/utils";
|
||||
|
||||
import { BootstrapTrigger } from "./bootstrap_trigger.js";
|
||||
import { ConnectionLimiter } from "./connection_limiter.js";
|
||||
import { Dialer } from "./dialer.js";
|
||||
import { DiscoveryDialer } from "./discovery_dialer.js";
|
||||
@ -45,6 +46,7 @@ export class ConnectionManager implements IConnectionManager {
|
||||
private readonly shardReader: ShardReader;
|
||||
private readonly networkMonitor: NetworkMonitor;
|
||||
private readonly connectionLimiter: ConnectionLimiter;
|
||||
private readonly bootstrapTrigger: BootstrapTrigger;
|
||||
|
||||
private readonly options: ConnectionManagerOptions;
|
||||
private libp2p: Libp2p;
|
||||
@ -64,6 +66,10 @@ export class ConnectionManager implements IConnectionManager {
|
||||
...options.config
|
||||
};
|
||||
|
||||
this.bootstrapTrigger = new BootstrapTrigger({
|
||||
libp2p: options.libp2p
|
||||
});
|
||||
|
||||
this.keepAliveManager = new KeepAliveManager({
|
||||
relay: options.relay,
|
||||
libp2p: options.libp2p,
|
||||
@ -110,6 +116,7 @@ export class ConnectionManager implements IConnectionManager {
|
||||
this.discoveryDialer.start();
|
||||
this.keepAliveManager.start();
|
||||
this.connectionLimiter.start();
|
||||
this.bootstrapTrigger.start();
|
||||
}
|
||||
|
||||
public stop(): void {
|
||||
@ -118,6 +125,7 @@ export class ConnectionManager implements IConnectionManager {
|
||||
this.discoveryDialer.stop();
|
||||
this.keepAliveManager.stop();
|
||||
this.connectionLimiter.stop();
|
||||
this.bootstrapTrigger.stop();
|
||||
}
|
||||
|
||||
public isConnected(): boolean {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user