diff --git a/package-lock.json b/package-lock.json index e50a8d7164..d17408b2ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7536,9 +7536,17 @@ "version": "4.17.18", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.18.tgz", "integrity": "sha512-KJ65INaxqxmU6EoCiJmRPZC9H9RVWCRd349tXM2M3O5NA7cY6YL7c0bHAHQ93NOfTObEQ004kd2QVHs/r0+m4g==", - "dev": true, "license": "MIT" }, + "node_modules/@types/lodash.debounce": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz", + "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/markdown-it": { "version": "14.1.2", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", @@ -37608,12 +37616,14 @@ "@libp2p/ping": "2.0.35", "@libp2p/websockets": "9.2.16", "@noble/hashes": "^1.3.3", + "@types/lodash.debounce": "^4.0.9", "@waku/core": "0.0.38", "@waku/discovery": "0.0.11", "@waku/interfaces": "0.0.33", "@waku/proto": "^0.0.13", "@waku/utils": "0.0.26", - "libp2p": "2.8.11" + "libp2p": "2.8.11", + "lodash.debounce": "^4.0.8" }, "devDependencies": { "@libp2p/interface": "2.10.4", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 01a819032d..dd88c6f350 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -67,20 +67,22 @@ "@libp2p/ping": "2.0.35", "@libp2p/websockets": "9.2.16", "@noble/hashes": "^1.3.3", + "@types/lodash.debounce": "^4.0.9", "@waku/core": "0.0.38", "@waku/discovery": "0.0.11", "@waku/interfaces": "0.0.33", "@waku/proto": "^0.0.13", "@waku/utils": "0.0.26", - "libp2p": "2.8.11" + "libp2p": "2.8.11", + "lodash.debounce": "^4.0.8" }, "devDependencies": { "@libp2p/interface": "2.10.4", - "@types/chai": "^4.3.11", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.5", + "@types/chai": "^4.3.11", "@types/mocha": "^10.0.9", "@waku/build-utils": "*", "chai": "^5.1.1", @@ -104,4 +106,4 @@ "LICENSE", "README.md" ] -} \ No newline at end of file +} diff --git a/packages/sdk/src/health_indicator/health_indicator.ts b/packages/sdk/src/health_indicator/health_indicator.ts index 297d4ba652..1e7888fba6 100644 --- a/packages/sdk/src/health_indicator/health_indicator.ts +++ b/packages/sdk/src/health_indicator/health_indicator.ts @@ -7,6 +7,7 @@ import { WakuEvent } from "@waku/interfaces"; import { Logger } from "@waku/utils"; +import debounce from "lodash.debounce"; type PeerEvent = (_event: CustomEvent) => void; @@ -24,10 +25,13 @@ interface IHealthIndicator { } export class HealthIndicator implements IHealthIndicator { + private isStarted = false; + private readonly libp2p: Libp2p; private readonly events: IWakuEventEmitter; private value: HealthStatus = HealthStatus.Unhealthy; + private readonly debouncedAssessHealth: ReturnType; public constructor(params: HealthIndicatorParams) { this.libp2p = params.libp2p; @@ -35,9 +39,18 @@ export class HealthIndicator implements IHealthIndicator { this.onPeerIdentify = this.onPeerIdentify.bind(this); this.onPeerDisconnected = this.onPeerDisconnected.bind(this); + + this.debouncedAssessHealth = debounce(() => { + void this.assessHealth(); + }, 100); } public start(): void { + if (this.isStarted) { + return; + } + + this.isStarted = true; log.info("start: adding listeners to libp2p"); this.libp2p.addEventListener( @@ -49,10 +62,15 @@ export class HealthIndicator implements IHealthIndicator { this.onPeerDisconnected as PeerEvent ); - void this.assessHealth(); + this.debouncedAssessHealth(); } public stop(): void { + if (!this.isStarted) { + return; + } + + this.isStarted = false; log.info("stop: removing listeners to libp2p"); this.libp2p.removeEventListener( @@ -63,22 +81,22 @@ export class HealthIndicator implements IHealthIndicator { "peer:disconnect", this.onPeerDisconnected as PeerEvent ); + + this.debouncedAssessHealth.cancel(); } public toValue(): HealthStatus { return this.value; } - private async onPeerDisconnected(_event: CustomEvent): Promise { + private onPeerDisconnected(_event: CustomEvent): void { log.info(`onPeerDisconnected: received libp2p event`); - await this.assessHealth(); + this.debouncedAssessHealth(); } - private async onPeerIdentify( - _event: CustomEvent - ): Promise { + private onPeerIdentify(_event: CustomEvent): void { log.info(`onPeerIdentify: received libp2p event`); - await this.assessHealth(); + this.debouncedAssessHealth(); } private async assessHealth(): Promise {