Skip to content

Commit

Permalink
feat!: use @grpc/grpc-js instead of grpc (#484)
Browse files Browse the repository at this point in the history
BREAKING CHANGE

* feat: use @grpc/grpc-js instead of grpc

* no need to have client libs test since end-to-end exists

* use any instead of ts-ignore

* no need to console.error

* fix windows builds
  • Loading branch information
alexander-fenster committed May 4, 2019
1 parent b0dbafb commit b872f2b
Show file tree
Hide file tree
Showing 18 changed files with 53 additions and 245 deletions.
10 changes: 9 additions & 1 deletion .kokoro/test.bat
Expand Up @@ -17,7 +17,15 @@
cd /d %~dp0
cd ..

call npm install -g npm@latest || goto :error
@rem The image we're currently running has a broken version of Node.js enabled
@rem by nvm (v10.15.3), which has no npm bin. This hack uses the functional
@rem Node v8.9.1 to install npm@latest, it then uses this version of npm to
@rem install npm for v10.15.3.
call nvm use v8.9.1 || goto :error
call node C:\Users\kbuilder\AppData\Roaming\nvm-ps\versions\v8.9.1\node_modules\npm-bootstrap\bin\npm-cli.js i npm -g || goto :error
call nvm use v10.15.3 || goto :error
call node C:\Users\kbuilder\AppData\Roaming\nvm-ps\versions\v8.9.1\node_modules\npm\bin\npm-cli.js i npm -g || goto :error

call npm install || goto :error
call npm run test || goto :error

Expand Down
11 changes: 11 additions & 0 deletions README.md
Expand Up @@ -15,6 +15,17 @@ Application code will rarely need to use most of the classes within this library
$ npm install google-gax
```

## Supporting older version of Node.js

This library uses [grpc-js](https://www.npmjs.com/package/@grpc/grpc-js) package for communicating with API server, and it uses HTTP/2 functionality
that is only available in Node.js v8.13.0 or newer. If you need to use this library with older versions of Node.js, you need to make your code depend
on a legacy gRPC library ([grpc](https://www.npmjs.com/package/grpc)) and pass the instance of gRPC to the client constructor:

```js
const grpc = require('grpc');
const client = new APIClient({ grpc }); // APIClient is the client class you use, e.g. SpeechClient, etc.
```

## Contributing
Contributions to this library are always welcome and highly encouraged. See the [CONTRIBUTING][contributing] documentation for more information on how to get started.

Expand Down
5 changes: 1 addition & 4 deletions package.json
Expand Up @@ -13,8 +13,6 @@
"@grpc/proto-loader": "^0.5.0",
"duplexify": "^3.6.0",
"google-auth-library": "^3.0.0",
"grpc": "^1.20.2",
"grpc-gcp": "^0.1.1",
"is-stream-ended": "^0.1.4",
"lodash.at": "^4.6.0",
"lodash.has": "^4.5.2",
Expand All @@ -41,7 +39,6 @@
"@types/through2": "^2.0.33",
"chai": "*",
"codecov": "^3.1.0",
"cross-env": "^5.2.0",
"eslint": "^5.9.0",
"eslint-config-prettier": "^4.0.0",
"eslint-plugin-node": "^9.0.0",
Expand Down Expand Up @@ -71,7 +68,7 @@
"docs": "compodoc src/",
"gen-parser": "pegjs src/pathTemplateParser.pegjs",
"pretest": "npm run prepare",
"test": "cross-env GOOGLE_CLOUD_USE_GRPC_JS=1 nyc mocha build/test && mocha build/test",
"test": "nyc mocha build/test",
"lint": "gts check && eslint samples/*.js samples/**/*.js",
"clean": "gts clean",
"compile": "tsc -p . && cp src/*.json build/src && cp src/*.js build/src",
Expand Down
2 changes: 1 addition & 1 deletion src/bundlingCalls/bundleExecutor.ts
Expand Up @@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {status} from 'grpc';
import {status} from '@grpc/grpc-js';

import {SimpleCallbackFunction} from '../apitypes';
import {GoogleError} from '../googleError';
Expand Down
2 changes: 1 addition & 1 deletion src/bundlingCalls/task.ts
Expand Up @@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {status} from 'grpc';
import {status} from '@grpc/grpc-js';

import {APICallback, GRPCCallResult, SimpleCallbackFunction} from '../apitypes';
import {GoogleError} from '../googleError';
Expand Down
2 changes: 1 addition & 1 deletion src/call.ts
Expand Up @@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {status} from 'grpc';
import {status} from '@grpc/grpc-js';

import {
APICallback,
Expand Down
2 changes: 1 addition & 1 deletion src/gax.ts
Expand Up @@ -667,7 +667,7 @@ export function constructSettings(
serviceName: string,
clientConfig: ClientConfig,
configOverrides: ClientConfig,
retryNames: {[index: string]: number},
retryNames: {},
otherArgs?: {},
promise?: PromiseConstructor
) {
Expand Down
2 changes: 1 addition & 1 deletion src/googleError.ts
Expand Up @@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {status} from 'grpc';
import {status} from '@grpc/grpc-js';

export class GoogleError extends Error {
code?: status;
Expand Down
52 changes: 18 additions & 34 deletions src/grpc.ts
Expand Up @@ -30,11 +30,10 @@
*
*/

import * as grpcProtoLoaderTypes from '@grpc/proto-loader'; // for types only
import * as grpcProtoLoader from '@grpc/proto-loader';
import * as fs from 'fs';
import {GoogleAuth, GoogleAuthOptions} from 'google-auth-library';
import * as grpcTypes from 'grpc'; // for types only
import * as grpcGcp from 'grpc-gcp';
import * as grpc from '@grpc/grpc-js';
import {OutgoingHttpHeaders} from 'http';
import * as path from 'path';
import * as protobuf from 'protobufjs';
Expand All @@ -56,8 +55,6 @@ const COMMON_PROTO_FILES = walk
.filter(f => path.extname(f) === '.proto')
.map(f => path.normalize(f).substring(googleProtoFilesDir.length + 1));

export {GrpcObject} from 'grpc';

export interface GrpcClientOptions extends GoogleAuthOptions {
auth?: GoogleAuth;
promise?: PromiseConstructor;
Expand All @@ -76,17 +73,17 @@ export interface Metadata {
get: (key: {}) => {};
}

export type GrpcModule = typeof grpcTypes & {
status: {[index: string]: number};
};
export type GrpcModule = typeof grpc;

export interface ClientStubOptions {
servicePath: string;
port: number;
sslCreds?: grpcTypes.ChannelCredentials;
// TODO: use sslCreds?: grpc.ChannelCredentials;
// tslint:disable-next-line no-any
sslCreds?: any;
}

export class ClientStub extends grpcTypes.Client {
export class ClientStub extends grpc.Client {
[name: string]: Function;
}

Expand All @@ -95,7 +92,6 @@ export class GrpcClient {
promise: PromiseConstructor;
grpc: GrpcModule;
grpcVersion: string;
grpcProtoLoader: typeof grpcProtoLoaderTypes;

/**
* A class which keeps the context of gRPC and auth for the gRPC.
Expand All @@ -122,20 +118,16 @@ export class GrpcClient {
this.grpc = options.grpc!;
this.grpcVersion = '';
} else {
// EXPERIMENTAL: If GOOGLE_CLOUD_USE_GRPC_JS is set, use the JS-based
// implementation of the gRPC client instead. Requires http2 (Node 8+).
if (
semver.gte(process.version, '8.13.0') &&
!!process.env.GOOGLE_CLOUD_USE_GRPC_JS
) {
this.grpc = require('@grpc/grpc-js');
if (semver.gte(process.version, '8.13.0')) {
this.grpc = grpc;
this.grpcVersion = require('@grpc/grpc-js/package.json').version;
} else {
this.grpc = require('grpc');
this.grpcVersion = require('grpc/package.json').version;
const errorMessage =
'To use @grpc/grpc-js you must run your code on Node.js v8.13.0 or newer. Please see README if you need to use an older version. ' +
'https://github.com/googleapis/gax-nodejs/blob/master/README.md';
throw new Error(errorMessage);
}
}
this.grpcProtoLoader = require('@grpc/proto-loader');
}

/**
Expand Down Expand Up @@ -166,8 +158,8 @@ export class GrpcClient {
* @param filename The path to the proto file.
* @param options Options for loading the proto file.
*/
loadFromProto(filename: string, options: grpcProtoLoaderTypes.Options) {
const packageDef = grpcProtoLoaderTypes.loadSync(filename, options);
loadFromProto(filename: string, options: grpcProtoLoader.Options) {
const packageDef = grpcProtoLoader.loadSync(filename, options);
return this.grpc.loadPackageDefinition(packageDef);
}

Expand Down Expand Up @@ -289,20 +281,12 @@ export class GrpcClient {
async createStub(CreateStub: typeof ClientStub, options: ClientStubOptions) {
const serviceAddress = options.servicePath + ':' + options.port;
const creds = await this._getCredentials(options);
const grpcOptions: {[index: string]: {}} = {};
const grpcOptions: {[index: string]: string} = {};
Object.keys(options).forEach(key => {
if (key.indexOf('grpc.') === 0) {
grpcOptions[key] = options[key];
if (key.startsWith('grpc.')) {
grpcOptions[key.replace(/^grpc\./, '')] = options[key];
}
});
const apiConfigDefinition = options['grpc_gcp.apiConfig'];
if (apiConfigDefinition) {
const apiConfig = grpcGcp.createGcpApiConfig(apiConfigDefinition);
grpcOptions['channelFactoryOverride'] = grpcGcp.gcpChannelFactoryOverride;
grpcOptions['callInvocationTransformer'] =
grpcGcp.gcpCallInvocationTransformer;
grpcOptions['gcpApiConfig'] = apiConfig;
}
const stub = new CreateStub(serviceAddress, creds, grpcOptions);
return stub;
}
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Expand Up @@ -57,7 +57,6 @@ export {
GrpcClient,
GrpcClientOptions,
GrpcModule,
GrpcObject,
Metadata,
MetadataValue,
} from './grpc';
Expand Down
2 changes: 1 addition & 1 deletion src/longRunningCalls/longrunning.ts
Expand Up @@ -30,7 +30,7 @@
*/

import {EventEmitter} from 'events';
import {status} from 'grpc';
import {status} from '@grpc/grpc-js';

import {GaxCallPromise, ResultTuple} from '../apitypes';
import {CancellablePromise} from '../call';
Expand Down
2 changes: 1 addition & 1 deletion src/normalCalls/retries.ts
Expand Up @@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import {status} from 'grpc';
import {status} from '@grpc/grpc-js';

import {
APICallback,
Expand Down
Expand Up @@ -15,13 +15,7 @@
'use strict';

const assert = require('assert');

let grpc;
if (process.env['GOOGLE_CLOUD_USE_GRPC_JS']) {
grpc = require('@grpc/grpc-js');
} else {
grpc = require('grpc');
}
const grpc = require('@grpc/grpc-js');

// Import the clients for each version supported by this package.
const gapic = Object.freeze({
Expand Down

0 comments on commit b872f2b

Please sign in to comment.