mirror of https://github.com/grpc/grpc-node.git
Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.6.x' into grpc-js-xds_ads_stream_delay
This commit is contained in:
commit
d8ce665fd8
|
@ -58,6 +58,7 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`.
|
|||
- `grpc.enable_http_proxy`
|
||||
- `grpc.default_compression_algorithm`
|
||||
- `grpc.enable_channelz`
|
||||
- `grpc.dns_min_time_between_resolutions_ms`
|
||||
- `grpc-node.max_session_memory`
|
||||
- `channelOverride`
|
||||
- `channelFactoryOverride`
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@grpc/grpc-js",
|
||||
"version": "1.6.0",
|
||||
"version": "1.6.1",
|
||||
"description": "gRPC Library for Node - pure JS implementation",
|
||||
"homepage": "https://grpc.io/",
|
||||
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
|
||||
|
|
|
@ -43,6 +43,7 @@ export interface ChannelOptions {
|
|||
'grpc.http_connect_creds'?: string;
|
||||
'grpc.default_compression_algorithm'?: CompressionAlgorithms;
|
||||
'grpc.enable_channelz'?: number;
|
||||
'grpc.dns_min_time_between_resolutions_ms'?: number;
|
||||
'grpc-node.max_session_memory'?: number;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
|
@ -69,6 +70,7 @@ export const recognizedOptions = {
|
|||
'grpc.max_receive_message_length': true,
|
||||
'grpc.enable_http_proxy': true,
|
||||
'grpc.enable_channelz': true,
|
||||
'grpc.dns_min_time_between_resolutions_ms': true,
|
||||
'grpc-node.max_session_memory': true,
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ function trace(text: string): void {
|
|||
*/
|
||||
const DEFAULT_PORT = 443;
|
||||
|
||||
const DEFAULT_MIN_TIME_BETWEEN_RESOLUTIONS_MS = 30_000;
|
||||
|
||||
const resolveTxtPromise = util.promisify(dns.resolveTxt);
|
||||
const dnsLookupPromise = util.promisify(dns.lookup);
|
||||
|
||||
|
@ -79,6 +81,12 @@ class DnsResolver implements Resolver {
|
|||
private readonly ipResult: SubchannelAddress[] | null;
|
||||
private readonly dnsHostname: string | null;
|
||||
private readonly port: number | null;
|
||||
/**
|
||||
* Minimum time between resolutions, measured as the time between starting
|
||||
* successive resolution requests. Only applies to successful resolutions.
|
||||
* Failures are handled by the backoff timer.
|
||||
*/
|
||||
private readonly minTimeBetweenResolutionsMs: number;
|
||||
private pendingLookupPromise: Promise<dns.LookupAddress[]> | null = null;
|
||||
private pendingTxtPromise: Promise<string[][]> | null = null;
|
||||
private latestLookupResult: TcpSubchannelAddress[] | null = null;
|
||||
|
@ -88,6 +96,8 @@ class DnsResolver implements Resolver {
|
|||
private defaultResolutionError: StatusObject;
|
||||
private backoff: BackoffTimeout;
|
||||
private continueResolving = false;
|
||||
private nextResolutionTimer: NodeJS.Timer;
|
||||
private isNextResolutionTimerRunning = false;
|
||||
constructor(
|
||||
private target: GrpcUri,
|
||||
private listener: ResolverListener,
|
||||
|
@ -134,6 +144,10 @@ class DnsResolver implements Resolver {
|
|||
}
|
||||
}, backoffOptions);
|
||||
this.backoff.unref();
|
||||
|
||||
this.minTimeBetweenResolutionsMs = channelOptions['grpc.dns_min_time_between_resolutions_ms'] ?? DEFAULT_MIN_TIME_BETWEEN_RESOLUTIONS_MS;
|
||||
this.nextResolutionTimer = setTimeout(() => {}, 0);
|
||||
clearTimeout(this.nextResolutionTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,6 +197,7 @@ class DnsResolver implements Resolver {
|
|||
(addressList) => {
|
||||
this.pendingLookupPromise = null;
|
||||
this.backoff.reset();
|
||||
this.backoff.stop();
|
||||
const ip4Addresses: dns.LookupAddress[] = addressList.filter(
|
||||
(addr) => addr.family === 4
|
||||
);
|
||||
|
@ -229,6 +244,7 @@ class DnsResolver implements Resolver {
|
|||
(err as Error).message
|
||||
);
|
||||
this.pendingLookupPromise = null;
|
||||
this.stopNextResolutionTimer();
|
||||
this.listener.onError(this.defaultResolutionError);
|
||||
}
|
||||
);
|
||||
|
@ -282,17 +298,34 @@ class DnsResolver implements Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
private startNextResolutionTimer() {
|
||||
this.nextResolutionTimer = setTimeout(() => {
|
||||
this.stopNextResolutionTimer();
|
||||
if (this.continueResolving) {
|
||||
this.startResolutionWithBackoff();
|
||||
}
|
||||
}, this.minTimeBetweenResolutionsMs).unref?.();
|
||||
this.isNextResolutionTimerRunning = true;
|
||||
}
|
||||
|
||||
private stopNextResolutionTimer() {
|
||||
clearTimeout(this.nextResolutionTimer);
|
||||
this.isNextResolutionTimerRunning = false;
|
||||
}
|
||||
|
||||
private startResolutionWithBackoff() {
|
||||
this.startResolution();
|
||||
this.backoff.runOnce();
|
||||
this.startNextResolutionTimer();
|
||||
}
|
||||
|
||||
updateResolution() {
|
||||
/* If there is a pending lookup, just let it finish. Otherwise, if the
|
||||
* backoff timer is running, do another lookup when it ends, and if not,
|
||||
* do another lookup immeidately. */
|
||||
* nextResolutionTimer or backoff timer is running, set the
|
||||
* continueResolving flag to resolve when whichever of those timers
|
||||
* fires. Otherwise, start resolving immediately. */
|
||||
if (this.pendingLookupPromise === null) {
|
||||
if (this.backoff.isRunning()) {
|
||||
if (this.isNextResolutionTimerRunning || this.backoff.isRunning()) {
|
||||
this.continueResolving = true;
|
||||
} else {
|
||||
this.startResolutionWithBackoff();
|
||||
|
@ -301,9 +334,9 @@ class DnsResolver implements Resolver {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
/* Do nothing. There is not a practical way to cancel in-flight DNS
|
||||
* requests, and after this function is called we can expect that
|
||||
* updateResolution will not be called again. */
|
||||
this.continueResolving = false;
|
||||
this.backoff.stop();
|
||||
this.stopNextResolutionTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue