mirror of https://github.com/grpc/grpc-node.git
Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.2.x' into grpc-js_1.2_upmerge_2
This commit is contained in:
commit
66d93c0f65
|
@ -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"
|
||||
|
|
|
@ -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]) => {
|
||||
|
|
|
@ -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": [
|
||||
|
|
|
@ -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?.();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -235,6 +235,7 @@ export class ResolvingLoadBalancer implements LoadBalancer {
|
|||
this.updateState(this.latestChildState, this.latestChildPicker);
|
||||
}
|
||||
});
|
||||
this.backoffTimeout.unref();
|
||||
}
|
||||
|
||||
private updateResolution() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue