Skip to content

Commit

Permalink
Merge pull request #2645 from murgatroid99/master_merge_1.9.x
Browse files Browse the repository at this point in the history
Merge 1.9.x into master
  • Loading branch information
murgatroid99 authored Jan 18, 2024
2 parents 2a7c906 + 3915f57 commit 666a374
Show file tree
Hide file tree
Showing 30 changed files with 544 additions and 161 deletions.
3 changes: 1 addition & 2 deletions doc/environment_variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ can be set.
- `subchannel_internals` - Traces HTTP/2 session state. Includes per-call logs.
- `channel_stacktrace` - Traces channel construction events with stack traces.
- `keepalive` - Traces gRPC keepalive pings
- `index` - Traces module loading
- `outlier_detection` - Traces outlier detection events

The following tracers are added by the `@grpc/grpc-js-xds` library:
Expand All @@ -62,4 +61,4 @@ can be set.
- DEBUG - log all gRPC messages
- INFO - log INFO and ERROR message
- ERROR - log only errors (default)
- NONE - won't log any
- NONE - won't log any
6 changes: 4 additions & 2 deletions packages/grpc-js-xds/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @grpc/grpc-js xDS plugin

This package provides support for the `xds://` URL scheme to the `@grpc/grpc-js` library. The latest version of this package is compatible with `@grpc/grpc-js` version 1.2.x.
This package provides support for the `xds://` URL scheme to the `@grpc/grpc-js` library. The latest version of this package is compatible with `@grpc/grpc-js` version 1.9.x.

## Installation

Expand Down Expand Up @@ -29,4 +29,6 @@ const client = new MyServiceClient('xds:///example.com:123');
- [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md)
- [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md)
- [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md)
- [xDS Retry Support](https://github.com/grpc/proposal/blob/master/A44-xds-retry.md)
- [xDS Retry Support](https://github.com/grpc/proposal/blob/master/A44-xds-retry.md)
- [xDS Aggregate and Logical DNS Clusters](https://github.com/grpc/proposal/blob/master/A37-xds-aggregate-and-logical-dns-clusters.md)'
- [xDS Federation](https://github.com/grpc/proposal/blob/master/A47-xds-federation.md) (Currently experimental, enabled by environment variable `GRPC_EXPERIMENTAL_XDS_FEDERATION`)
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js-xds",
"version": "1.8.2",
"version": "1.9.2",
"description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.",
"main": "build/src/index.js",
"scripts": {
Expand All @@ -9,7 +9,7 @@
"clean": "gts clean",
"compile": "tsc",
"fix": "gts fix",
"prepare": "npm run compile",
"prepare": "npm run generate-types && npm run compile",
"pretest": "npm run compile",
"posttest": "npm run check",
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/xds/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v3/ads.proto envoy/service/load_stats/v3/lrs.proto envoy/config/listener/v3/listener.proto envoy/config/route/v3/route.proto envoy/config/cluster/v3/cluster.proto envoy/config/endpoint/v3/endpoint.proto envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto udpa/type/v1/typed_struct.proto xds/type/v3/typed_struct.proto envoy/extensions/filters/http/fault/v3/fault.proto envoy/service/status/v3/csds.proto envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.proto",
Expand Down Expand Up @@ -50,7 +50,7 @@
"xxhash-wasm": "^1.0.2"
},
"peerDependencies": {
"@grpc/grpc-js": "~1.8.0"
"@grpc/grpc-js": "~1.9.0"
},
"engines": {
"node": ">=10.10.0"
Expand Down
2 changes: 2 additions & 0 deletions packages/grpc-js-xds/src/resolver-xds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,9 +677,11 @@ class XdsResolver implements Resolver {
destroy() {
if (this.listenerResourceName) {
ListenerResourceType.cancelWatch(this.xdsClient, this.listenerResourceName, this.ldsWatcher);
this.isLdsWatcherActive = false;
}
if (this.latestRouteConfigName) {
RouteConfigurationResourceType.cancelWatch(this.xdsClient, this.latestRouteConfigName, this.rdsWatcher);
this.latestRouteConfigName = null;
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/grpc-js-xds/src/xds-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -924,8 +924,8 @@ class XdsSingleServerClient {
}

onLrsStreamReceivedMessage() {
this.adsBackoff.stop();
this.adsBackoff.reset();
this.lrsBackoff.stop();
this.lrsBackoff.reset();
}

handleLrsStreamEnd() {
Expand Down
14 changes: 9 additions & 5 deletions packages/grpc-js-xds/test/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
*/

import { credentials, loadPackageDefinition, ServiceError } from "@grpc/grpc-js";
import { ChannelOptions, credentials, loadPackageDefinition, ServiceError } from "@grpc/grpc-js";
import { loadSync } from "@grpc/proto-loader";
import { ProtoGrpcType } from "./generated/echo";
import { EchoTestServiceClient } from "./generated/grpc/testing/EchoTestService";
Expand Down Expand Up @@ -44,14 +44,14 @@ export class XdsTestClient {
private client: EchoTestServiceClient;
private callInterval: NodeJS.Timer;

constructor(target: string, bootstrapInfo: string) {
this.client = new loadedProtos.grpc.testing.EchoTestService(target, credentials.createInsecure(), {[BOOTSTRAP_CONFIG_KEY]: bootstrapInfo});
constructor(target: string, bootstrapInfo: string, options?: ChannelOptions) {
this.client = new loadedProtos.grpc.testing.EchoTestService(target, credentials.createInsecure(), {...options, [BOOTSTRAP_CONFIG_KEY]: bootstrapInfo});
this.callInterval = setInterval(() => {}, 0);
clearInterval(this.callInterval);
}

static createFromServer(targetName: string, xdsServer: XdsServer) {
return new XdsTestClient(`xds:///${targetName}`, xdsServer.getBootstrapInfoString());
static createFromServer(targetName: string, xdsServer: XdsServer, options?: ChannelOptions) {
return new XdsTestClient(`xds:///${targetName}`, xdsServer.getBootstrapInfoString(), options);
}

startCalls(interval: number) {
Expand Down Expand Up @@ -98,4 +98,8 @@ export class XdsTestClient {
}
sendInner(count, callback);
}

getConnectivityState() {
return this.client.getChannel().getConnectivityState(false);
}
}
31 changes: 31 additions & 0 deletions packages/grpc-js-xds/test/test-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { XdsServer } from "./xds-server";

import { register } from "../src";
import assert = require("assert");
import { connectivityState } from "@grpc/grpc-js";

register();

Expand Down Expand Up @@ -60,4 +61,34 @@ describe('core xDS functionality', () => {
}, reason => done(reason));
}, reason => done(reason));
});
it('should be able to enter and exit idle', function(done) {
this.timeout(5000);
const cluster = new FakeEdsCluster('cluster1', 'endpoint1', [{backends: [new Backend()], locality:{region: 'region1'}}]);
const routeGroup = new FakeRouteGroup('listener1', 'route1', [{cluster: cluster}]);
routeGroup.startAllBackends().then(() => {
xdsServer.setEdsResource(cluster.getEndpointConfig());
xdsServer.setCdsResource(cluster.getClusterConfig());
xdsServer.setRdsResource(routeGroup.getRouteConfiguration());
xdsServer.setLdsResource(routeGroup.getListener());
xdsServer.addResponseListener((typeUrl, responseState) => {
if (responseState.state === 'NACKED') {
client.stopCalls();
assert.fail(`Client NACKED ${typeUrl} resource with message ${responseState.errorMessage}`);
}
})
client = XdsTestClient.createFromServer('listener1', xdsServer, {
'grpc.client_idle_timeout_ms': 1000,
});
client.sendOneCall(error => {
assert.ifError(error);
assert.strictEqual(client.getConnectivityState(), connectivityState.READY);
setTimeout(() => {
assert.strictEqual(client.getConnectivityState(), connectivityState.IDLE);
client.sendOneCall(error => {
done(error);
})
}, 1100);
});
}, reason => done(reason));
});
});
1 change: 1 addition & 0 deletions packages/grpc-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`.
- `grpc.service_config_disable_resolution`
- `grpc.client_idle_timeout_ms`
- `grpc-node.max_session_memory`
- `grpc-node.tls_enable_trace`
- `channelOverride`
- `channelFactoryOverride`

Expand Down
4 changes: 2 additions & 2 deletions 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.8.21",
"version": "1.9.14",
"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 Expand Up @@ -65,7 +65,7 @@
"generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --include-dirs test/fixtures/ -O test/generated/ --grpcLib ../../src/index test_service.proto"
},
"dependencies": {
"@grpc/proto-loader": "^0.7.0",
"@grpc/proto-loader": "^0.7.8",
"@types/node": ">=12.12.47"
},
"files": [
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;
}
}
12 changes: 10 additions & 2 deletions packages/grpc-js/src/http_proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import { ChannelOptions } from './channel-options';
import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser';
import { URL } from 'url';
import { DEFAULT_PORT } from './resolver-dns';

const TRACER_NAME = 'proxy';

Expand Down Expand Up @@ -189,12 +190,19 @@ export function getProxiedConnection(
if (parsedTarget === null) {
return Promise.resolve<ProxyConnectionResult>({});
}
const splitHostPost = splitHostPort(parsedTarget.path);
if (splitHostPost === null) {
return Promise.resolve<ProxyConnectionResult>({});
}
const hostPort = `${splitHostPost.host}:${
splitHostPost.port ?? DEFAULT_PORT
}`;
const options: http.RequestOptions = {
method: 'CONNECT',
path: parsedTarget.path,
path: hostPort,
};
const headers: http.OutgoingHttpHeaders = {
Host: parsedTarget.path,
Host: hostPort,
};
// Connect to the subchannel address as a proxy
if (isTcpSubchannelAddress(address)) {
Expand Down
7 changes: 0 additions & 7 deletions packages/grpc-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,7 @@ import * as load_balancer_outlier_detection from './load-balancer-outlier-detect
import * as channelz from './channelz';
import { Deadline } from './deadline';

const clientVersion = require('../../package.json').version;

(() => {
logging.trace(
LogVerbosity.DEBUG,
'index',
'Loading @grpc/grpc-js version ' + clientVersion
);
resolver_dns.setup();
resolver_uds.setup();
resolver_ip.setup();
Expand Down
Loading

0 comments on commit 666a374

Please sign in to comment.