Skip to content

Commit 3950a1c

Browse files
authored
Merge pull request #3007 from murgatroid99/grpc-js_1.13_upmerge
Merge v1.13.x into master
2 parents a7dfb68 + 6e36a69 commit 3950a1c

File tree

9 files changed

+78
-50
lines changed

9 files changed

+78
-50
lines changed

packages/grpc-js-xds/interop/test-client.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/
4242
COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/
4343

4444
ENV GRPC_VERBOSITY="DEBUG"
45-
ENV GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager,cds_balancer,xds_cluster_resolver,xds_cluster_impl,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection,server,server_call,ring_hash,transport,certificate_provider,xds_channel_credentials
45+
ENV GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager,cds_balancer,xds_cluster_resolver,xds_cluster_impl,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection,server,server_call,ring_hash,transport,certificate_provider,xds_channel_credentials,backoff
4646
ENV NODE_XDS_INTEROP_VERBOSITY=1
4747

4848
ENTRYPOINT [ "/nodejs/bin/node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ]

packages/grpc-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@grpc/grpc-js",
3-
"version": "1.13.0",
3+
"version": "1.13.4",
44
"description": "gRPC Library for Node - pure JS implementation",
55
"homepage": "https://grpc.io/",
66
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",

packages/grpc-js/src/backoff-timeout.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
*
1616
*/
1717

18+
import { LogVerbosity } from './constants';
19+
import * as logging from './logging';
20+
21+
const TRACER_NAME = 'backoff';
22+
1823
const INITIAL_BACKOFF_MS = 1000;
1924
const BACKOFF_MULTIPLIER = 1.6;
2025
const MAX_BACKOFF_MS = 120000;
@@ -84,7 +89,12 @@ export class BackoffTimeout {
8489
*/
8590
private endTime: Date = new Date();
8691

92+
private id: number;
93+
94+
private static nextId = 0;
95+
8796
constructor(private callback: () => void, options?: BackoffOptions) {
97+
this.id = BackoffTimeout.getNextId();
8898
if (options) {
8999
if (options.initialDelay) {
90100
this.initialDelay = options.initialDelay;
@@ -99,20 +109,31 @@ export class BackoffTimeout {
99109
this.maxDelay = options.maxDelay;
100110
}
101111
}
112+
this.trace('constructed initialDelay=' + this.initialDelay + ' multiplier=' + this.multiplier + ' jitter=' + this.jitter + ' maxDelay=' + this.maxDelay);
102113
this.nextDelay = this.initialDelay;
103114
this.timerId = setTimeout(() => {}, 0);
104115
clearTimeout(this.timerId);
105116
}
106117

118+
private static getNextId() {
119+
return this.nextId++;
120+
}
121+
122+
private trace(text: string) {
123+
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, '{' + this.id + '} ' + text);
124+
}
125+
107126
private runTimer(delay: number) {
127+
this.trace('runTimer(delay=' + delay + ')');
108128
this.endTime = this.startTime;
109129
this.endTime.setMilliseconds(
110130
this.endTime.getMilliseconds() + delay
111131
);
112132
clearTimeout(this.timerId);
113133
this.timerId = setTimeout(() => {
114-
this.callback();
134+
this.trace('timer fired');
115135
this.running = false;
136+
this.callback();
116137
}, delay);
117138
if (!this.hasRef) {
118139
this.timerId.unref?.();
@@ -123,6 +144,7 @@ export class BackoffTimeout {
123144
* Call the callback after the current amount of delay time
124145
*/
125146
runOnce() {
147+
this.trace('runOnce()');
126148
this.running = true;
127149
this.startTime = new Date();
128150
this.runTimer(this.nextDelay);
@@ -140,6 +162,7 @@ export class BackoffTimeout {
140162
* again.
141163
*/
142164
stop() {
165+
this.trace('stop()');
143166
clearTimeout(this.timerId);
144167
this.running = false;
145168
}
@@ -149,6 +172,7 @@ export class BackoffTimeout {
149172
* retroactively apply that reset to the current timer.
150173
*/
151174
reset() {
175+
this.trace('reset() running=' + this.running);
152176
this.nextDelay = this.initialDelay;
153177
if (this.running) {
154178
const now = new Date();

packages/grpc-js/src/channel-credentials.ts

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,18 @@ function getConnectionOptions(secureContext: SecureContext, verifyOptions: Verif
206206
const connectionOptions: ConnectionOptions = {
207207
secureContext: secureContext
208208
};
209+
let realTarget: GrpcUri = channelTarget;
210+
if ('grpc.http_connect_target' in options) {
211+
const parsedTarget = parseUri(options['grpc.http_connect_target']!);
212+
if (parsedTarget) {
213+
realTarget = parsedTarget;
214+
}
215+
}
216+
const targetPath = getDefaultAuthority(realTarget);
217+
const hostPort = splitHostPort(targetPath);
218+
const remoteHost = hostPort?.host ?? targetPath;
219+
connectionOptions.host = remoteHost;
220+
209221
if (verifyOptions.checkServerIdentity) {
210222
connectionOptions.checkServerIdentity = verifyOptions.checkServerIdentity;
211223
}
@@ -225,36 +237,11 @@ function getConnectionOptions(secureContext: SecureContext, verifyOptions: Verif
225237
};
226238
connectionOptions.servername = sslTargetNameOverride;
227239
} else {
228-
if ('grpc.http_connect_target' in options) {
229-
/* This is more or less how servername will be set in createSession
230-
* if a connection is successfully established through the proxy.
231-
* If the proxy is not used, these connectionOptions are discarded
232-
* anyway */
233-
const targetPath = getDefaultAuthority(
234-
parseUri(options['grpc.http_connect_target'] as string) ?? {
235-
path: 'localhost',
236-
}
237-
);
238-
const hostPort = splitHostPort(targetPath);
239-
connectionOptions.servername = hostPort?.host ?? targetPath;
240-
}
240+
connectionOptions.servername = remoteHost;
241241
}
242242
if (options['grpc-node.tls_enable_trace']) {
243243
connectionOptions.enableTrace = true;
244244
}
245-
246-
let realTarget: GrpcUri = channelTarget;
247-
if ('grpc.http_connect_target' in options) {
248-
const parsedTarget = parseUri(options['grpc.http_connect_target']!);
249-
if (parsedTarget) {
250-
realTarget = parsedTarget;
251-
}
252-
}
253-
const targetPath = getDefaultAuthority(realTarget);
254-
const hostPort = splitHostPort(targetPath);
255-
const remoteHost = hostPort?.host ?? targetPath;
256-
connectionOptions.host = remoteHost;
257-
connectionOptions.servername = remoteHost;
258245
return connectionOptions;
259246
}
260247

@@ -268,7 +255,7 @@ class SecureConnectorImpl implements SecureConnector {
268255
};
269256
return new Promise<SecureConnectResult>((resolve, reject) => {
270257
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
271-
if (!tlsSocket.authorized) {
258+
if ((this.connectionOptions.rejectUnauthorized ?? true) && !tlsSocket.authorized) {
272259
reject(tlsSocket.authorizationError);
273260
return;
274261
}
@@ -364,7 +351,7 @@ class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
364351
const tlsSocket = tlsConnect(tlsConnectOptions, () => {
365352
tlsSocket.removeListener('close', closeCallback);
366353
tlsSocket.removeListener('error', errorCallback);
367-
if (!tlsSocket.authorized) {
354+
if ((this.parent.verifyOptions.rejectUnauthorized ?? true) && !tlsSocket.authorized) {
368355
reject(tlsSocket.authorizationError);
369356
return;
370357
}

packages/grpc-js/src/internal-channel.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,16 +297,16 @@ export class InternalChannel {
297297
/* The global boolean parameter to getSubchannelPool has the inverse meaning to what
298298
* the grpc.use_local_subchannel_pool channel option means. */
299299
this.subchannelPool = getSubchannelPool(
300-
(options['grpc.use_local_subchannel_pool'] ?? 0) === 0
300+
(this.options['grpc.use_local_subchannel_pool'] ?? 0) === 0
301301
);
302302
this.retryBufferTracker = new MessageBufferTracker(
303-
options['grpc.retry_buffer_size'] ?? DEFAULT_RETRY_BUFFER_SIZE_BYTES,
304-
options['grpc.per_rpc_retry_buffer_size'] ??
303+
this.options['grpc.retry_buffer_size'] ?? DEFAULT_RETRY_BUFFER_SIZE_BYTES,
304+
this.options['grpc.per_rpc_retry_buffer_size'] ??
305305
DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES
306306
);
307-
this.keepaliveTime = options['grpc.keepalive_time_ms'] ?? -1;
307+
this.keepaliveTime = this.options['grpc.keepalive_time_ms'] ?? -1;
308308
this.idleTimeoutMs = Math.max(
309-
options['grpc.client_idle_timeout_ms'] ?? DEFAULT_IDLE_TIMEOUT_MS,
309+
this.options['grpc.client_idle_timeout_ms'] ?? DEFAULT_IDLE_TIMEOUT_MS,
310310
MIN_IDLE_TIMEOUT_MS
311311
);
312312
const channelControlHelper: ChannelControlHelper = {
@@ -372,7 +372,7 @@ export class InternalChannel {
372372
this.resolvingLoadBalancer = new ResolvingLoadBalancer(
373373
this.target,
374374
channelControlHelper,
375-
options,
375+
this.options,
376376
(serviceConfig, configSelector) => {
377377
if (serviceConfig.retryThrottling) {
378378
RETRY_THROTTLER_MAP.set(

packages/grpc-js/src/retrying-call.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ export class RetryThrottler {
5858
}
5959

6060
addCallSucceeded() {
61-
this.tokens = Math.max(this.tokens + this.tokenRatio, this.maxTokens);
61+
this.tokens = Math.min(this.tokens + this.tokenRatio, this.maxTokens);
6262
}
6363

6464
addCallFailed() {
65-
this.tokens = Math.min(this.tokens - 1, 0);
65+
this.tokens = Math.max(this.tokens - 1, 0);
6666
}
6767

6868
canRetryCall() {
69-
return this.tokens > this.maxTokens / 2;
69+
return this.tokens > (this.maxTokens / 2);
7070
}
7171
}
7272

@@ -225,7 +225,10 @@ export class RetryingCall implements Call, DeadlineInfoProvider {
225225
const maxAttemptsLimit =
226226
channel.getOptions()['grpc-node.retry_max_attempts_limit'] ??
227227
DEFAULT_MAX_ATTEMPTS_LIMIT;
228-
if (callConfig.methodConfig.retryPolicy) {
228+
if (channel.getOptions()['grpc.enable_retries'] === 0) {
229+
this.state = 'NO_RETRY';
230+
this.maxAttempts = 1;
231+
} else if (callConfig.methodConfig.retryPolicy) {
229232
this.state = 'RETRY';
230233
const retryPolicy = callConfig.methodConfig.retryPolicy;
231234
this.nextRetryBackoffSec = this.initialRetryBackoffSec = Number(
@@ -241,9 +244,6 @@ export class RetryingCall implements Call, DeadlineInfoProvider {
241244
callConfig.methodConfig.hedgingPolicy.maxAttempts,
242245
maxAttemptsLimit
243246
);
244-
} else if (channel.getOptions()['grpc.enable_retries'] === 0) {
245-
this.state = 'NO_RETRY';
246-
this.maxAttempts = 1;
247247
} else {
248248
this.state = 'TRANSPARENT_ONLY';
249249
this.maxAttempts = 1;
@@ -483,6 +483,9 @@ export class RetryingCall implements Call, DeadlineInfoProvider {
483483
callback(true);
484484
this.attempts += 1;
485485
this.startNewAttempt();
486+
} else {
487+
this.trace('Retry attempt denied by throttling policy');
488+
callback(false);
486489
}
487490
}, retryDelayMs);
488491
}

packages/grpc-js/src/transport.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -712,19 +712,19 @@ export class Http2SubchannelConnector implements SubchannelConnector {
712712
reject(`${errorMessage} (${new Date().toISOString()})`);
713713
}
714714
};
715-
const session = http2.connect(`${scheme}://${targetPath}`, {
715+
const sessionOptions: http2.ClientSessionOptions = {
716716
createConnection: (authority, option) => {
717717
return secureConnectResult.socket;
718718
},
719719
settings: {
720720
initialWindowSize:
721721
options['grpc-node.flow_control_window'] ??
722-
http2.getDefaultSettings().initialWindowSize ?? 65535,
722+
http2.getDefaultSettings?.()?.initialWindowSize ?? 65535,
723723
}
724-
});
725-
724+
};
725+
const session = http2.connect(`${scheme}://${targetPath}`, sessionOptions);
726726
// Prepare window size configuration for remoteSettings handler
727-
const defaultWin = http2.getDefaultSettings().initialWindowSize ?? 65535; // 65 535 B
727+
const defaultWin = http2.getDefaultSettings?.()?.initialWindowSize ?? 65535; // 65 535 B
728728
const connWin = options[
729729
'grpc-node.flow_control_window'
730730
] as number | undefined;
@@ -745,7 +745,7 @@ export class Http2SubchannelConnector implements SubchannelConnector {
745745
if (delta > 0) (session as any).incrementWindowSize(delta);
746746
}
747747
}
748-
748+
749749
session.removeAllListeners();
750750
secureConnectResult.socket.removeListener('close', closeHandler);
751751
secureConnectResult.socket.removeListener('error', errorHandler);
@@ -799,6 +799,7 @@ export class Http2SubchannelConnector implements SubchannelConnector {
799799
await secureConnector.waitForReady();
800800
this.trace(addressString + ' secureConnector is ready');
801801
tcpConnection = await this.tcpConnect(address, options);
802+
tcpConnection.setNoDelay();
802803
this.trace(addressString + ' Established TCP connection');
803804
secureConnectResult = await secureConnector.connect(tcpConnection);
804805
this.trace(addressString + ' Established secure connection');

packages/grpc-js/test/test-channel-credentials.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,15 @@ describe('ChannelCredentials usage', () => {
228228
done();
229229
});
230230
})
231+
it('Should accept self-signed certs with acceptUnauthorized', done => {
232+
const client = new echoService(`localhost:${portNum}`, grpc.credentials.createSsl(null, null, null, {rejectUnauthorized: false}));
233+
client.echo({ value: 'test value', value2: 3 }, (error: ServiceError | null, response: any) => {
234+
client.close();
235+
assert.ifError(error);
236+
assert.deepStrictEqual(response, { value: 'test value', value2: 3 });
237+
done();
238+
});
239+
});
231240
});
232241

233242
describe('Channel credentials mtls', () => {

packages/grpc-js/test/test-retry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ describe('Retries', () => {
175175
},
176176
},
177177
],
178+
retryThrottling: {
179+
maxTokens: 1000,
180+
tokenRatio: 0.1,
181+
},
178182
};
179183
client = new EchoService(
180184
`localhost:${port}`,

0 commit comments

Comments
 (0)