Skip to content

Commit

Permalink
Merge pull request #2571 from murgatroid99/grpc-js_dns_backoff_fixes
Browse files Browse the repository at this point in the history
grpc-js: Make a few improvements to DNS resolving timing
  • Loading branch information
murgatroid99 committed Sep 13, 2023
2 parents e7e199c + 10c4bbd commit c8cbffa
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/grpc-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js",
"version": "1.9.2",
"version": "1.9.3",
"description": "gRPC Library for Node - pure JS implementation",
"homepage": "https://grpc.io/",
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
Expand Down
15 changes: 15 additions & 0 deletions packages/grpc-js/src/backoff-timeout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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();
Expand Down Expand Up @@ -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;
}
}
8 changes: 7 additions & 1 deletion packages/grpc-js/src/resolver-dns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class DnsResolver implements Resolver {
});
this.backoff.stop();
this.backoff.reset();
this.stopNextResolutionTimer();
return;
}
if (this.dnsHostname === null) {
Expand Down Expand Up @@ -339,9 +340,9 @@ class DnsResolver implements Resolver {
private startResolutionWithBackoff() {
if (this.pendingLookupPromise === null) {
this.continueResolving = false;
this.startResolution();
this.backoff.runOnce();
this.startNextResolutionTimer();
this.startResolution();
}
}

Expand All @@ -352,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();
Expand Down
3 changes: 3 additions & 0 deletions packages/grpc-js/src/resolving-load-balancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -247,6 +248,8 @@ export class ResolvingLoadBalancer implements LoadBalancer {
configSelector: ConfigSelector | null,
attributes: { [key: string]: unknown }
) => {
this.backoffTimeout.stop();
this.backoffTimeout.reset();
let workingServiceConfig: ServiceConfig | null = null;
/* This first group of conditionals implements the algorithm described
* in https://github.com/grpc/proposal/blob/master/A21-service-config-error-handling.md
Expand Down

0 comments on commit c8cbffa

Please sign in to comment.