From 10c4bbdbe391bb806d55fe4070af811c79174834 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 13 Sep 2023 10:18:30 -0700 Subject: [PATCH] Add logging for DNS update delays due to rate limit or backoff --- packages/grpc-js/src/backoff-timeout.ts | 15 +++++++++++++++ packages/grpc-js/src/resolver-dns.ts | 5 +++++ packages/grpc-js/src/resolving-load-balancer.ts | 1 + 3 files changed, 21 insertions(+) diff --git a/packages/grpc-js/src/backoff-timeout.ts b/packages/grpc-js/src/backoff-timeout.ts index 3ffd2606..78318d1e 100644 --- a/packages/grpc-js/src/backoff-timeout.ts +++ b/packages/grpc-js/src/backoff-timeout.ts @@ -78,6 +78,11 @@ export class BackoffTimeout { * running is true. */ private startTime: Date = new Date(); + /** + * The approximate time that the currently running timer will end. Only valid + * if running is true. + */ + private endTime: Date = new Date(); constructor(private callback: () => void, options?: BackoffOptions) { if (options) { @@ -100,6 +105,8 @@ export class BackoffTimeout { } private runTimer(delay: number) { + this.endTime = this.startTime; + this.endTime.setMilliseconds(this.endTime.getMilliseconds() + this.nextDelay); clearTimeout(this.timerId); this.timerId = setTimeout(() => { this.callback(); @@ -178,4 +185,12 @@ export class BackoffTimeout { this.hasRef = false; this.timerId.unref?.(); } + + /** + * Get the approximate timestamp of when the timer will fire. Only valid if + * this.isRunning() is true. + */ + getEndTime() { + return this.endTime; + } } diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 6bb31a3a..149530bb 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -353,6 +353,11 @@ class DnsResolver implements Resolver { * fires. Otherwise, start resolving immediately. */ if (this.pendingLookupPromise === null) { if (this.isNextResolutionTimerRunning || this.backoff.isRunning()) { + if (this.isNextResolutionTimerRunning) { + trace('resolution update delayed by "min time between resolutions" rate limit'); + } else { + trace('resolution update delayed by backoff timer until ' + this.backoff.getEndTime().toISOString()); + } this.continueResolving = true; } else { this.startResolutionWithBackoff(); diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 425d1fe2..ceec4b5d 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -222,6 +222,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { * In that case, the backoff timer callback will call * updateResolution */ if (this.backoffTimeout.isRunning()) { + trace('requestReresolution delayed by backoff timer until ' + this.backoffTimeout.getEndTime().toISOString()); this.continueResolving = true; } else { this.updateResolution();