From ab27e4cf6c22404439a2433eb97c20b536e6e87c Mon Sep 17 00:00:00 2001 From: Sophia Date: Thu, 14 Sep 2023 17:05:15 +0200 Subject: [PATCH] fix(grpc): Memory leak due to open channel references Channels reference themselves with timeout's, meaning that they cannot be garbage collected by v8. This is a workaround that stops us from creating more and more channels; thus fixing a memory leak. Resolves #2329 --- .../microservice/grpc.health.ts | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/health-indicator/microservice/grpc.health.ts b/lib/health-indicator/microservice/grpc.health.ts index 936c18f61..0872e4411 100644 --- a/lib/health-indicator/microservice/grpc.health.ts +++ b/lib/health-indicator/microservice/grpc.health.ts @@ -105,6 +105,12 @@ export class GRPCHealthIndicator extends HealthIndicator { this.checkDependantPackages(); } + /** + * A cache of open channels for the health indicator + * This is used to prevent opening new channels for every health check + */ + private readonly openChannels = new Map(); + /** * Checks if the dependant packages are present */ @@ -185,13 +191,19 @@ export class GRPCHealthIndicator extends HealthIndicator { const settings = { ...defaultOptions, ...options }; - const client = this.createClient(settings); - let healthService: GRPCHealthService; try { - healthService = client.getService( - settings.healthServiceName as string, - ); + if (this.openChannels.has(service)) { + healthService = this.openChannels.get(service)!; + } else { + const client = this.createClient(settings); + + healthService = client.getService( + settings.healthServiceName as string, + ); + + this.openChannels.set(service, healthService); + } } catch (err) { if (err instanceof TypeError) throw err; if (isError(err)) {