Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.2.x' into grpc-js_1.2_upmerge_2

This commit is contained in:
Michael Lumish 2021-04-02 11:19:13 -07:00
commit 66d93c0f65
10 changed files with 84 additions and 19 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js-xds",
"version": "1.2.1",
"version": "1.2.4",
"description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.",
"main": "build/src/index.js",
"scripts": {
@ -47,7 +47,7 @@
"re2-wasm": "^1.0.1"
},
"peerDependencies": {
"@grpc/grpc-js": "~1.2.2"
"@grpc/grpc-js": "~1.2.10"
},
"engines": {
"node": ">=10.10.0"

View File

@ -311,9 +311,11 @@ export class XdsClient {
this.adsBackoff = new BackoffTimeout(() => {
this.maybeStartAdsStream();
});
this.adsBackoff.unref();
this.lrsBackoff = new BackoffTimeout(() => {
this.maybeStartLrsStream();
})
});
this.lrsBackoff.unref();
Promise.all([loadBootstrapInfo(), loadAdsProtos()]).then(
([bootstrapInfo, protoDefinitions]) => {

View File

@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js",
"version": "1.2.5",
"version": "1.2.12",
"description": "gRPC Library for Node - pure JS implementation",
"homepage": "https://grpc.io/",
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
@ -57,7 +57,7 @@
"posttest": "npm run check"
},
"dependencies": {
"@types/node": "^12.12.47",
"@types/node": ">=12.12.47",
"semver": "^6.2.0"
},
"files": [

View File

@ -44,6 +44,7 @@ export class BackoffTimeout {
private nextDelay: number;
private timerId: NodeJS.Timer;
private running = false;
private hasRef = true;
constructor(private callback: () => void, options?: BackoffOptions) {
if (options) {
@ -74,6 +75,9 @@ export class BackoffTimeout {
this.callback();
this.running = false;
}, this.nextDelay);
if (!this.hasRef) {
this.timerId.unref?.();
}
const nextBackoff = Math.min(
this.nextDelay * this.multiplier,
this.maxDelay
@ -102,4 +106,14 @@ export class BackoffTimeout {
isRunning() {
return this.running;
}
ref() {
this.hasRef = true;
this.timerId.ref?.();
}
unref() {
this.hasRef = false;
this.timerId.unref?.();
}
}

View File

@ -21,6 +21,7 @@ import { BaseFilter, Filter, FilterFactory } from './filter';
import { Metadata } from './metadata';
import { Status } from './constants';
import { splitHostPort } from './uri-parser';
import { ServiceError } from './call';
export class CallCredentialsFilter extends BaseFilter implements Filter {
private serviceUrl: string;
@ -51,12 +52,21 @@ export class CallCredentialsFilter extends BaseFilter implements Filter {
service_url: this.serviceUrl,
});
const resultMetadata = await metadata;
resultMetadata.merge(await credsMetadata);
try {
resultMetadata.merge(await credsMetadata);
} catch (error) {
this.stream.cancelWithStatus(
Status.UNAUTHENTICATED,
`Failed to retrieve auth metadata with error: ${error.message}`
);
return Promise.reject<Metadata>('Failed to retrieve auth metadata');
}
if (resultMetadata.get('authorization').length > 1) {
this.stream.cancelWithStatus(
Status.INTERNAL,
'"authorization" metadata cannot have multiple values'
);
return Promise.reject<Metadata>('"authorization" metadata cannot have multiple values');
}
return resultMetadata;
}

View File

@ -16,6 +16,7 @@
*/
import * as http2 from 'http2';
import * as os from 'os';
import { CallCredentials } from './call-credentials';
import { Propagate, Status } from './constants';
@ -37,8 +38,34 @@ const {
NGHTTP2_CANCEL,
} = http2.constants;
interface NodeError extends Error {
/**
* https://nodejs.org/api/errors.html#errors_class_systemerror
*/
interface SystemError extends Error {
address?: string;
code: string;
dest?: string;
errno: number;
info?: object;
message: string;
path?: string;
port?: number;
syscall: string;
}
/**
* Should do approximately the same thing as util.getSystemErrorName but the
* TypeScript types don't have that function for some reason so I just made my
* own.
* @param errno
*/
function getSystemErrorName(errno: number): string {
for (const [name, num] of Object.entries(os.constants.errno)) {
if (num === errno) {
return name;
}
}
return 'Unknown system error ' + errno;
}
export type Deadline = Date | number;
@ -206,7 +233,7 @@ export class Http2CallStream implements Call {
private listener: InterceptingListener | null = null;
private internalErrorMessage: string | null = null;
private internalError: SystemError | null = null;
constructor(
private readonly methodName: string,
@ -554,7 +581,7 @@ export class Http2CallStream implements Call {
break;
case http2.constants.NGHTTP2_INTERNAL_ERROR:
code = Status.INTERNAL;
if (this.internalErrorMessage === null) {
if (this.internalError === null) {
/* This error code was previously handled in the default case, and
* there are several instances of it online, so I wanted to
* preserve the original error message so that people find existing
@ -562,11 +589,16 @@ export class Http2CallStream implements Call {
* "Internal server error" message. */
details = `Received RST_STREAM with code ${stream.rstCode} (Internal server error)`;
} else {
/* The "Received RST_STREAM with code ..." error is preserved
* here for continuity with errors reported online, but the
* error message at the end will probably be more relevant in
* most cases. */
details = `Received RST_STREAM with code ${stream.rstCode} triggered by internal client error: ${this.internalErrorMessage}`;
if (this.internalError.errno === os.constants.errno.ECONNRESET) {
code = Status.UNAVAILABLE;
details = this.internalError.message;
} else {
/* The "Received RST_STREAM with code ..." error is preserved
* here for continuity with errors reported online, but the
* error message at the end will probably be more relevant in
* most cases. */
details = `Received RST_STREAM with code ${stream.rstCode} triggered by internal client error: ${this.internalError.message}`;
}
}
break;
default:
@ -580,7 +612,7 @@ export class Http2CallStream implements Call {
this.endCall({ code, details, metadata: new Metadata() });
});
});
stream.on('error', (err: NodeError) => {
stream.on('error', (err: SystemError) => {
/* We need an error handler here to stop "Uncaught Error" exceptions
* from bubbling up. However, errors here should all correspond to
* "close" events, where we will handle the error more granularly */
@ -589,7 +621,8 @@ export class Http2CallStream implements Call {
* https://github.com/nodejs/node/blob/8b8620d580314050175983402dfddf2674e8e22a/lib/internal/http2/core.js#L2267
*/
if (err.code !== 'ERR_HTTP2_STREAM_ERROR') {
this.internalErrorMessage = err.message;
this.trace('Node error event: message=' + err.message + ' code=' + err.code + ' errno=' + getSystemErrorName(err.errno) + ' syscall=' + err.syscall);
this.internalError = err;
}
});
if (!this.pendingRead) {

View File

@ -419,7 +419,7 @@ export class ChannelImplementation implements Channel {
);
callStream.cancelWithStatus(
Status.INTERNAL,
'Failed to start HTTP/2 stream'
`Failed to start HTTP/2 stream with error: ${(error as Error).message}`
);
}
}
@ -441,7 +441,7 @@ export class ChannelImplementation implements Channel {
(error: Error & { code: number }) => {
// We assume the error code isn't 0 (Status.OK)
callStream.cancelWithStatus(
error.code || Status.UNKNOWN,
(typeof error.code === 'number') ? error.code : Status.UNKNOWN,
`Getting metadata from plugin failed with error: ${error.message}`
);
}
@ -559,6 +559,9 @@ export class ChannelImplementation implements Channel {
deadline: Date | number,
callback: (error?: Error) => void
): void {
if (this.connectivityState === ConnectivityState.SHUTDOWN) {
throw new Error('Channel has been shut down');
}
let timer = null;
if(deadline !== Infinity) {
const deadlineDate: Date =

View File

@ -170,7 +170,7 @@ export class CompressionFilter extends BaseFilter implements Filter {
async sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
const headers: Metadata = await metadata;
headers.set('grpc-accept-encoding', 'identity,deflate,gzip');
headers.set('accept-encoding', 'identity,gzip');
headers.set('accept-encoding', 'identity');
return headers;
}

View File

@ -235,6 +235,7 @@ export class ResolvingLoadBalancer implements LoadBalancer {
this.updateState(this.latestChildState, this.latestChildPicker);
}
});
this.backoffTimeout.unref();
}
private updateResolution() {

View File

@ -618,6 +618,7 @@ export class Subchannel {
if (this.session) {
this.session.ref();
}
this.backoffTimeout.ref();
if (!this.keepaliveWithoutCalls) {
this.startKeepalivePings();
}
@ -638,6 +639,7 @@ export class Subchannel {
if (this.session) {
this.session.unref();
}
this.backoffTimeout.unref();
if (!this.keepaliveWithoutCalls) {
this.stopKeepalivePings();
}