UNPKG

@waku/sdk

Version:

A unified SDK for easy creation and management of js-waku nodes.

77 lines 3.2 kB
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