From 9050ea9dae8b5f015f2d9ecd12fb4432ab953eef Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 30 Oct 2023 09:42:29 -0700 Subject: [PATCH] grpc-js: Don't repeat fixed resolver results --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/resolver-dns.ts | 25 ++++++++++-------- packages/grpc-js/src/resolver-ip.ts | 32 +++++++++++++----------- packages/grpc-js/test/test-pick-first.ts | 2 +- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 6627b010..56fa0d3f 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.9.8", + "version": "1.9.9", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 149530bb..9431183d 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -99,6 +99,7 @@ class DnsResolver implements Resolver { private nextResolutionTimer: NodeJS.Timeout; private isNextResolutionTimerRunning = false; private isServiceConfigEnabled = true; + private returnedIpResult = false; constructor( private target: GrpcUri, private listener: ResolverListener, @@ -163,16 +164,19 @@ class DnsResolver implements Resolver { */ private startResolution() { if (this.ipResult !== null) { - trace('Returning IP address for target ' + uriToString(this.target)); - setImmediate(() => { - this.listener.onSuccessfulResolution( - this.ipResult!, - null, - null, - null, - {} - ); - }); + if (!this.returnedIpResult) { + trace('Returning IP address for target ' + uriToString(this.target)); + setImmediate(() => { + this.listener.onSuccessfulResolution( + this.ipResult!, + null, + null, + null, + {} + ); + }); + this.returnedIpResult = true; + } this.backoff.stop(); this.backoff.reset(); this.stopNextResolutionTimer(); @@ -380,6 +384,7 @@ class DnsResolver implements Resolver { this.latestLookupResult = null; this.latestServiceConfig = null; this.latestServiceConfigError = null; + this.returnedIpResult = false; } /** diff --git a/packages/grpc-js/src/resolver-ip.ts b/packages/grpc-js/src/resolver-ip.ts index 0704131e..7cf4f564 100644 --- a/packages/grpc-js/src/resolver-ip.ts +++ b/packages/grpc-js/src/resolver-ip.ts @@ -41,6 +41,7 @@ const DEFAULT_PORT = 443; class IpResolver implements Resolver { private addresses: SubchannelAddress[] = []; private error: StatusObject | null = null; + private hasReturnedResult = false; constructor( target: GrpcUri, private listener: ResolverListener, @@ -87,22 +88,25 @@ class IpResolver implements Resolver { trace('Parsed ' + target.scheme + ' address list ' + this.addresses); } updateResolution(): void { - process.nextTick(() => { - if (this.error) { - this.listener.onError(this.error); - } else { - this.listener.onSuccessfulResolution( - this.addresses, - null, - null, - null, - {} - ); - } - }); + if (!this.hasReturnedResult) { + this.hasReturnedResult = true; + process.nextTick(() => { + if (this.error) { + this.listener.onError(this.error); + } else { + this.listener.onSuccessfulResolution( + this.addresses, + null, + null, + null, + {} + ); + } + }); + } } destroy(): void { - // This resolver owns no resources, so we do nothing here. + this.hasReturnedResult = false; } static getDefaultAuthority(target: GrpcUri): string { diff --git a/packages/grpc-js/test/test-pick-first.ts b/packages/grpc-js/test/test-pick-first.ts index a018e7a2..07544888 100644 --- a/packages/grpc-js/test/test-pick-first.ts +++ b/packages/grpc-js/test/test-pick-first.ts @@ -97,7 +97,7 @@ describe('Shuffler', () => { }); }); -describe.only('pick_first load balancing policy', () => { +describe('pick_first load balancing policy', () => { const config = new PickFirstLoadBalancingConfig(false); let subchannels: MockSubchannel[] = []; const baseChannelControlHelper: ChannelControlHelper = {