@waku/sdk
Version:
A unified SDK for easy creation and management of js-waku nodes.
77 lines • 3.2 kB
JavaScript
import { FilterCodecs, LightPushCodec } from "@waku/core";
import { HealthStatus } from "@waku/interfaces";
import { Logger } from "@waku/utils";
const log = new Logger("health-indicator");
export class HealthIndicator {
libp2p;
events;
value = HealthStatus.Unhealthy;
constructor(params) {
this.libp2p = params.libp2p;
this.events = params.events;
this.onPeerIdentify = this.onPeerIdentify.bind(this);
this.onPeerDisconnected = this.onPeerDisconnected.bind(this);
}
start() {
log.info("start: adding listeners to libp2p");
this.libp2p.addEventListener("peer:identify", this.onPeerIdentify);
this.libp2p.addEventListener("peer:disconnect", this.onPeerDisconnected);
}
stop() {
log.info("stop: removing listeners to libp2p");
this.libp2p.removeEventListener("peer:identify", this.onPeerIdentify);
this.libp2p.removeEventListener("peer:disconnect", this.onPeerDisconnected);
}
toValue() {
return this.value;
}
async onPeerDisconnected(_event) {
log.info(`onPeerDisconnected: received libp2p event`);
const connections = this.libp2p.getConnections();
// we handle only Unhealthy here and onPeerIdentify will cover other cases
if (connections.length > 0) {
log.info("onPeerDisconnected: has connections, ignoring");
}
log.info(`onPeerDisconnected: node identified as ${HealthStatus.Unhealthy}`);
this.updateAndDispatchHealthEvent(HealthStatus.Unhealthy);
}
async onPeerIdentify(_event) {
log.info(`onPeerIdentify: received libp2p event`);
const connections = this.libp2p.getConnections();
const peers = await Promise.all(connections.map(async (c) => {
try {
return await this.libp2p.peerStore.get(c.remotePeer);
}
catch (e) {
return null;
}
}));
const filterPeers = peers.filter((p) => p?.protocols.includes(FilterCodecs.SUBSCRIBE)).length;
const lightPushPeers = peers.filter((p) => p?.protocols.includes(LightPushCodec)).length;
let newValue;
if (filterPeers === 0 || lightPushPeers === 0) {
newValue = HealthStatus.Unhealthy;
}
else if (filterPeers >= 2 && lightPushPeers >= 2) {
newValue = HealthStatus.SufficientlyHealthy;
}
else if (filterPeers === 1 && lightPushPeers === 1) {
newValue = HealthStatus.MinimallyHealthy;
}
else {
log.error(`onPeerIdentify: unexpected state, cannot identify health status of the node: Filter:${filterPeers}; LightPush:${lightPushPeers}`);
newValue = this.value;
}
log.info(`onPeerIdentify: node identified as ${newValue}`);
this.updateAndDispatchHealthEvent(newValue);
}
updateAndDispatchHealthEvent(newValue) {
if (this.value !== newValue) {
this.value = newValue;
this.events.dispatchEvent(new CustomEvent("waku:health", {
detail: this.value
}));
}
}
}
//# sourceMappingURL=health_indicator.js.map