aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/node
diff options
context:
space:
mode:
authorGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2016-04-05 00:30:40 +0200
committerGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2016-04-05 00:30:40 +0200
commit6415043781e0b73008b3db539f18354fe776241a (patch)
tree78fc8db5eb33ac5cdea96b0a743a57c02e9b0109 /src/node
parent1bb17d31cd00d70048c51c99ed5a827ea10389e6 (diff)
parent1b7c0a2c5cf27d7a77d9c3476fe6406a98ca3d76 (diff)
Merge branch 'master' of https://github.com/grpc/grpc into gpr_malloc_is_all
Diffstat (limited to 'src/node')
-rw-r--r--src/node/ext/byte_buffer.cc2
-rw-r--r--src/node/ext/call.cc2
-rw-r--r--src/node/ext/call_credentials.cc2
-rw-r--r--src/node/ext/call_credentials.h2
-rw-r--r--src/node/ext/node_grpc.cc2
-rw-r--r--src/node/ext/timeval.cc2
-rw-r--r--src/node/health_check/health.js2
-rw-r--r--src/node/index.js6
-rw-r--r--src/node/interop/async_delay_queue.js2
-rw-r--r--src/node/interop/interop_client.js14
-rw-r--r--src/node/interop/interop_server.js2
-rw-r--r--src/node/performance/benchmark_client.js2
-rw-r--r--src/node/performance/benchmark_server.js2
-rw-r--r--src/node/performance/worker.js2
-rw-r--r--src/node/performance/worker_service_impl.js2
-rw-r--r--src/node/src/client.js153
-rw-r--r--src/node/src/common.js2
-rw-r--r--src/node/src/credentials.js2
-rw-r--r--src/node/src/metadata.js2
-rw-r--r--src/node/src/server.js2
-rw-r--r--src/node/stress/metrics_client.js61
-rw-r--r--src/node/stress/metrics_server.js87
-rw-r--r--src/node/stress/stress_client.js126
-rw-r--r--src/node/test/call_test.js2
-rw-r--r--src/node/test/channel_test.js2
-rw-r--r--src/node/test/common_test.js2
-rw-r--r--src/node/test/constant_test.js2
-rw-r--r--src/node/test/credentials_test.js25
-rw-r--r--src/node/test/echo_service.proto2
-rw-r--r--src/node/test/end_to_end_test.js2
-rw-r--r--src/node/test/server_test.js2
-rw-r--r--src/node/test/surface_test.js44
-rw-r--r--src/node/test/test_messages.proto2
-rw-r--r--src/node/test/test_service.proto2
34 files changed, 456 insertions, 112 deletions
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index 0f7edada14..8e0b6916e9 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index da312886ce..9f023b5883 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc
index bd2d146bbc..3c8f0c56da 100644
--- a/src/node/ext/call_credentials.cc
+++ b/src/node/ext/call_credentials.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h
index 1f35595f3d..04c852bea1 100644
--- a/src/node/ext/call_credentials.h
+++ b/src/node/ext/call_credentials.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 0c71b2d610..b988f29878 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/timeval.cc b/src/node/ext/timeval.cc
index c8f8534cfa..9284db62ef 100644
--- a/src/node/ext/timeval.cc
+++ b/src/node/ext/timeval.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/health_check/health.js b/src/node/health_check/health.js
index 6ab4157183..5236683088 100644
--- a/src/node/health_check/health.js
+++ b/src/node/health_check/health.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/index.js b/src/node/index.js
index 1c197729d7..d345a5142d 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,10 @@ var loadObject = exports.loadObject;
* Buffers. Defaults to false
* - longsAsStrings: deserialize long values as strings instead of objects.
* Defaults to true
+ * - deprecatedArgumentOrder: Use the beta method argument order for client
+ * methods, with optional arguments after the callback. Defaults to false.
+ * This option is only a temporary stopgap measure to smooth an API breakage.
+ * It is deprecated, and new code should not use it.
* @param {string|{root: string, file: string}} filename The file to load
* @param {string=} format The file format to expect. Must be either 'proto' or
* 'json'. Defaults to 'proto'
diff --git a/src/node/interop/async_delay_queue.js b/src/node/interop/async_delay_queue.js
index df57209637..5df1e00921 100644
--- a/src/node/interop/async_delay_queue.js
+++ b/src/node/interop/async_delay_queue.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index 5602011a8e..e8f2d37bd8 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -286,7 +286,7 @@ function cancelAfterFirstResponse(client, done) {
function timeoutOnSleepingServer(client, done) {
var deadline = new Date();
deadline.setMilliseconds(deadline.getMilliseconds() + 1);
- var call = client.fullDuplexCall(null, {deadline: deadline});
+ var call = client.fullDuplexCall({deadline: deadline});
call.write({
payload: {body: zeroBuffer(27182)}
});
@@ -316,10 +316,10 @@ function customMetadata(client, done) {
body: zeroBuffer(271828)
}
};
- var unary = client.unaryCall(arg, function(err, resp) {
+ var unary = client.unaryCall(arg, metadata, function(err, resp) {
assert.ifError(err);
done();
- }, metadata);
+ });
unary.on('metadata', function(metadata) {
assert.deepEqual(metadata.get(ECHO_INITIAL_KEY),
['test_initial_metadata_value']);
@@ -455,14 +455,14 @@ function perRpcAuthTest(client, done, extra) {
credential = credential.createScoped(scope);
}
var creds = grpc.credentials.createFromGoogleCredential(credential);
- client.unaryCall(arg, function(err, resp) {
+ client.unaryCall(arg, {credentials: creds}, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.username, SERVICE_ACCOUNT_EMAIL);
assert(extra.oauth_scope.indexOf(resp.oauth_scope) > -1);
if (done) {
done();
}
- }, null, {credentials: creds});
+ });
});
}
@@ -545,6 +545,8 @@ var test_cases = {
Client: testProto.TestService}
};
+exports.test_cases = test_cases;
+
/**
* Execute a single test case.
* @param {string} address The address of the server to connect to, in the
diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js
index c09481712a..7280762305 100644
--- a/src/node/interop/interop_server.js
+++ b/src/node/interop/interop_server.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js
index 80bec0b73e..262aa33862 100644
--- a/src/node/performance/benchmark_client.js
+++ b/src/node/performance/benchmark_client.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/performance/benchmark_server.js b/src/node/performance/benchmark_server.js
index b1b0bd12ab..70cee9979b 100644
--- a/src/node/performance/benchmark_server.js
+++ b/src/node/performance/benchmark_server.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/performance/worker.js b/src/node/performance/worker.js
index 7c8ab00026..98577bdbc9 100644
--- a/src/node/performance/worker.js
+++ b/src/node/performance/worker.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js
index 2c4651370f..17458e4b93 100644
--- a/src/node/performance/worker_service_impl.js
+++ b/src/node/performance/worker_service_impl.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/src/client.js b/src/node/src/client.js
index 2459e28321..5e07046fc6 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,7 @@
'use strict';
var _ = require('lodash');
+var arguejs = require('arguejs');
var grpc = require('./grpc_extension');
@@ -353,21 +354,23 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
* @this {Client} Client object. Must have a channel member.
* @param {*} argument The argument to the call. Should be serializable with
* serialize
- * @param {function(?Error, value=)} callback The callback to for when the
- * response is received
* @param {Metadata=} metadata Metadata to add to the call
* @param {Object=} options Options map
+ * @param {function(?Error, value=)} callback The callback to for when the
+ * response is received
* @return {EventEmitter} An event emitter for stream related events
*/
- function makeUnaryRequest(argument, callback, metadata, options) {
+ function makeUnaryRequest(argument, metadata, options, callback) {
/* jshint validthis: true */
+ /* While the arguments are listed in the function signature, those variables
+ * are not used directly. Instead, ArgueJS processes the arguments
+ * object. This allows for simple handling of optional arguments in the
+ * middle of the argument list, and also provides type checking. */
+ var args = arguejs({argument: null, metadata: [Metadata, new Metadata()],
+ options: [Object], callback: Function}, arguments);
var emitter = new EventEmitter();
- var call = getCall(this.$channel, method, options);
- if (metadata === null || metadata === undefined) {
- metadata = new Metadata();
- } else {
- metadata = metadata.clone();
- }
+ var call = getCall(this.$channel, method, args.options);
+ metadata = args.metadata.clone();
emitter.cancel = function cancel() {
call.cancel();
};
@@ -375,9 +378,9 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
return call.getPeer();
};
var client_batch = {};
- var message = serialize(argument);
- if (options) {
- message.grpcWriteFlags = options.flags;
+ var message = serialize(args.argument);
+ if (args.options) {
+ message.grpcWriteFlags = args.options.flags;
}
client_batch[grpc.opType.SEND_INITIAL_METADATA] =
metadata._getCoreRepresentation();
@@ -395,7 +398,7 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
if (status.code === grpc.status.OK) {
if (err) {
// Got a batch error, but OK status. Something went wrong
- callback(err);
+ args.callback(err);
return;
} else {
try {
@@ -414,9 +417,9 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
error = new Error(status.details);
error.code = status.code;
error.metadata = status.metadata;
- callback(error);
+ args.callback(error);
} else {
- callback(null, deserialized);
+ args.callback(null, deserialized);
}
emitter.emit('status', status);
emitter.emit('metadata', Metadata._fromCoreRepresentation(
@@ -440,21 +443,23 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
* Make a client stream request with this method on the given channel with the
* given callback, etc.
* @this {Client} Client object. Must have a channel member.
- * @param {function(?Error, value=)} callback The callback to for when the
- * response is received
* @param {Metadata=} metadata Array of metadata key/value pairs to add to the
* call
* @param {Object=} options Options map
+ * @param {function(?Error, value=)} callback The callback to for when the
+ * response is received
* @return {EventEmitter} An event emitter for stream related events
*/
- function makeClientStreamRequest(callback, metadata, options) {
+ function makeClientStreamRequest(metadata, options, callback) {
/* jshint validthis: true */
- var call = getCall(this.$channel, method, options);
- if (metadata === null || metadata === undefined) {
- metadata = new Metadata();
- } else {
- metadata = metadata.clone();
- }
+ /* While the arguments are listed in the function signature, those variables
+ * are not used directly. Instead, ArgueJS processes the arguments
+ * object. This allows for simple handling of optional arguments in the
+ * middle of the argument list, and also provides type checking. */
+ var args = arguejs({metadata: [Metadata, new Metadata()],
+ options: [Object], callback: Function}, arguments);
+ var call = getCall(this.$channel, method, args.options);
+ metadata = args.metadata.clone();
var stream = new ClientWritableStream(call, serialize);
var metadata_batch = {};
metadata_batch[grpc.opType.SEND_INITIAL_METADATA] =
@@ -481,7 +486,7 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
if (status.code === grpc.status.OK) {
if (err) {
// Got a batch error, but OK status. Something went wrong
- callback(err);
+ args.callback(err);
return;
} else {
try {
@@ -500,9 +505,9 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
error = new Error(response.status.details);
error.code = status.code;
error.metadata = status.metadata;
- callback(error);
+ args.callback(error);
} else {
- callback(null, deserialized);
+ args.callback(null, deserialized);
}
stream.emit('status', status);
});
@@ -533,17 +538,18 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
*/
function makeServerStreamRequest(argument, metadata, options) {
/* jshint validthis: true */
- var call = getCall(this.$channel, method, options);
- if (metadata === null || metadata === undefined) {
- metadata = new Metadata();
- } else {
- metadata = metadata.clone();
- }
+ /* While the arguments are listed in the function signature, those variables
+ * are not used directly. Instead, ArgueJS processes the arguments
+ * object. */
+ var args = arguejs({argument: null, metadata: [Metadata, new Metadata()],
+ options: [Object]}, arguments);
+ var call = getCall(this.$channel, method, args.options);
+ metadata = args.metadata.clone();
var stream = new ClientReadableStream(call, deserialize);
var start_batch = {};
- var message = serialize(argument);
- if (options) {
- message.grpcWriteFlags = options.flags;
+ var message = serialize(args.argument);
+ if (args.options) {
+ message.grpcWriteFlags = args.options.flags;
}
start_batch[grpc.opType.SEND_INITIAL_METADATA] =
metadata._getCoreRepresentation();
@@ -595,12 +601,13 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
*/
function makeBidiStreamRequest(metadata, options) {
/* jshint validthis: true */
- var call = getCall(this.$channel, method, options);
- if (metadata === null || metadata === undefined) {
- metadata = new Metadata();
- } else {
- metadata = metadata.clone();
- }
+ /* While the arguments are listed in the function signature, those variables
+ * are not used directly. Instead, ArgueJS processes the arguments
+ * object. */
+ var args = arguejs({metadata: [Metadata, new Metadata()],
+ options: [Object]}, arguments);
+ var call = getCall(this.$channel, method, args.options);
+ metadata = args.metadata.clone();
var stream = new ClientDuplexStream(call, serialize, deserialize);
var start_batch = {};
start_batch[grpc.opType.SEND_INITIAL_METADATA] =
@@ -643,6 +650,40 @@ var requester_makers = {
bidi: makeBidiStreamRequestFunction
};
+function getDefaultValues(metadata, options) {
+ var res = {};
+ res.metadata = metadata || new Metadata();
+ res.options = options || {};
+ return res;
+}
+
+/**
+ * Map with wrappers for each type of requester function to make it use the old
+ * argument order with optional arguments after the callback.
+ */
+var deprecated_request_wrap = {
+ unary: function(makeUnaryRequest) {
+ return function makeWrappedUnaryRequest(argument, callback,
+ metadata, options) {
+ /* jshint validthis: true */
+ var opt_args = getDefaultValues(metadata, metadata);
+ return makeUnaryRequest.call(this, argument, opt_args.metadata,
+ opt_args.options, callback);
+ };
+ },
+ client_stream: function(makeServerStreamRequest) {
+ return function makeWrappedClientStreamRequest(callback, metadata,
+ options) {
+ /* jshint validthis: true */
+ var opt_args = getDefaultValues(metadata, options);
+ return makeServerStreamRequest.call(this, opt_args.metadata,
+ opt_args.options, callback);
+ };
+ },
+ server_stream: _.identity,
+ bidi: _.identity
+};
+
/**
* Creates a constructor for a client with the given methods. The methods object
* maps method name to an object with the following keys:
@@ -654,9 +695,19 @@ var requester_makers = {
* responseDeserialize: function to deserialize response objects
* @param {Object} methods An object mapping method names to method attributes
* @param {string} serviceName The fully qualified name of the service
+ * @param {Object} class_options An options object. Currently only uses the key
+ * deprecatedArgumentOrder, a boolean that Indicates that the old argument
+ * order should be used for methods, with optional arguments at the end
+ * instead of the callback at the end. Defaults to false. This option is
+ * only a temporary stopgap measure to smooth an API breakage.
+ * It is deprecated, and new code should not use it.
* @return {function(string, Object)} New client constructor
*/
-exports.makeClientConstructor = function(methods, serviceName) {
+exports.makeClientConstructor = function(methods, serviceName,
+ class_options) {
+ if (!class_options) {
+ class_options = {};
+ }
/**
* Create a client with the given methods
* @constructor
@@ -703,8 +754,13 @@ exports.makeClientConstructor = function(methods, serviceName) {
}
var serialize = attrs.requestSerialize;
var deserialize = attrs.responseDeserialize;
- Client.prototype[name] = requester_makers[method_type](
+ var method_func = requester_makers[method_type](
attrs.path, serialize, deserialize);
+ if (class_options.deprecatedArgumentOrder) {
+ Client.prototype[name] = deprecated_request_wrap(method_func);
+ } else {
+ Client.prototype[name] = method_func;
+ }
// Associate all provided attributes with the method
_.assign(Client.prototype[name], attrs);
});
@@ -761,8 +817,13 @@ exports.waitForClientReady = function(client, deadline, callback) {
exports.makeProtobufClientConstructor = function(service, options) {
var method_attrs = common.getProtobufServiceAttrs(service, service.name,
options);
+ var deprecatedArgumentOrder = false;
+ if (options) {
+ deprecatedArgumentOrder = options.deprecatedArgumentOrder;
+ }
var Client = exports.makeClientConstructor(
- method_attrs, common.fullyQualifiedName(service));
+ method_attrs, common.fullyQualifiedName(service),
+ deprecatedArgumentOrder);
Client.service = service;
Client.service.grpc_options = options;
return Client;
diff --git a/src/node/src/common.js b/src/node/src/common.js
index 7705a275fc..8cf43b7a84 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js
index 97c4bd73ac..a12eade4e1 100644
--- a/src/node/src/credentials.js
+++ b/src/node/src/credentials.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/src/metadata.js b/src/node/src/metadata.js
index 33d7ea1cf7..612361b0ea 100644
--- a/src/node/src/metadata.js
+++ b/src/node/src/metadata.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/src/server.js b/src/node/src/server.js
index dd0bc12bc9..22128343a9 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/stress/metrics_client.js b/src/node/stress/metrics_client.js
new file mode 100644
index 0000000000..dc8ef5e711
--- /dev/null
+++ b/src/node/stress/metrics_client.js
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+'use strict';
+
+var grpc = require('../../..');
+
+var proto = grpc.load(__dirname + '/../../proto/grpc/testing/metrics.proto');
+var metrics = proto.grpc.testing;
+
+function main() {
+ var parseArgs = require('minimist');
+ var argv = parseArgs(process.argv, {
+ string: 'metrics_server_address',
+ boolean: 'total_only'
+ });
+ var client = new metrics.MetricsService(argv.metrics_server_address,
+ grpc.credentials.createInsecure());
+ if (argv.total_only) {
+ client.getGauge({name: 'qps'}, function(err, data) {
+ console.log(data.name + ':', data.long_value);
+ });
+ } else {
+ var call = client.getAllGauges({});
+ call.on('data', function(data) {
+ console.log(data.name + ':', data.long_value);
+ });
+ }
+}
+
+main();
diff --git a/src/node/stress/metrics_server.js b/src/node/stress/metrics_server.js
new file mode 100644
index 0000000000..3ab4b4c82d
--- /dev/null
+++ b/src/node/stress/metrics_server.js
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+'use strict';
+
+var _ = require('lodash');
+
+var grpc = require('../../..');
+
+var proto = grpc.load(__dirname + '/../../proto/grpc/testing/metrics.proto');
+var metrics = proto.grpc.testing;
+
+function getGauge(call, callback) {
+ /* jshint validthis: true */
+ // Should be bound to a MetricsServer object
+ var name = call.request.name;
+ if (this.gauges.hasOwnProperty(name)) {
+ callback(null, _.assign({name: name}, this.gauges[name]()));
+ } else {
+ callback({code: grpc.status.NOT_FOUND,
+ details: 'No such gauge: ' + name});
+ }
+}
+
+function getAllGauges(call) {
+ /* jshint validthis: true */
+ // Should be bound to a MetricsServer object
+ _.each(this.gauges, function(getter, name) {
+ call.write(_.assign({name: name}, getter()));
+ });
+ call.end();
+}
+
+function MetricsServer(port) {
+ var server = new grpc.Server();
+ server.addProtoService(metrics.MetricsService.service, {
+ getGauge: _.bind(getGauge, this),
+ getAllGauges: _.bind(getAllGauges, this)
+ });
+ server.bind('localhost:' + port, grpc.ServerCredentials.createInsecure());
+ this.server = server;
+ this.gauges = {};
+}
+
+MetricsServer.prototype.start = function() {
+ this.server.start();
+}
+
+MetricsServer.prototype.registerGauge = function(name, getter) {
+ this.gauges[name] = getter;
+};
+
+MetricsServer.prototype.shutdown = function() {
+ this.server.forceShutdown();
+};
+
+module.exports = MetricsServer;
diff --git a/src/node/stress/stress_client.js b/src/node/stress/stress_client.js
new file mode 100644
index 0000000000..8332652e2a
--- /dev/null
+++ b/src/node/stress/stress_client.js
@@ -0,0 +1,126 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+'use strict';
+
+var _ = require('lodash');
+
+var grpc = require('../../..');
+
+var interop_client = require('../interop/interop_client');
+var MetricsServer = require('./metrics_server');
+
+var running;
+
+var metrics_server;
+
+var start_time;
+var query_count;
+
+function makeCall(client, test_cases) {
+ if (!running) {
+ return;
+ }
+ var test_case = test_cases[_.random(test_cases.length - 1)];
+ interop_client.test_cases[test_case].run(client, function() {
+ query_count += 1;
+ makeCall(client, test_cases);
+ });
+}
+
+function makeCalls(client, test_cases, parallel_calls_per_channel) {
+ _.times(parallel_calls_per_channel, function() {
+ makeCall(client, test_cases);
+ });
+}
+
+function getQps() {
+ var diff = process.hrtime(start_time);
+ var seconds = diff[0] + diff[1] / 1e9;
+ return {long_value: query_count / seconds};
+}
+
+function start(server_addresses, test_cases, channels_per_server,
+ parallel_calls_per_channel, metrics_port) {
+ running = true;
+ /* Assuming that we are not calling unimplemented_method. The client class
+ * used by empty_unary is (currently) the client class used by every interop
+ * test except unimplemented_method */
+ var Client = interop_client.test_cases.empty_unary.Client;
+ /* Make channels_per_server clients connecting to each server address */
+ var channels = _.flatten(_.times(
+ channels_per_server, _.partial(_.map, server_addresses, function(address) {
+ return new Client(address, grpc.credentials.createInsecure());
+ })));
+ metrics_server = new MetricsServer(metrics_port);
+ metrics_server.registerGauge('qps', getQps);
+ start_time = process.hrtime();
+ query_count = 0;
+ _.each(channels, _.partial(makeCalls, _, test_cases,
+ parallel_calls_per_channel));
+ metrics_server.start();
+}
+
+function stop() {
+ running = false;
+ metrics_server.shutdown();
+ console.log('QPS: ' + getQps().long_value);
+}
+
+function main() {
+ var parseArgs = require('minimist');
+ var argv = parseArgs(process.argv, {
+ string: ['server_addresses', 'test_cases', 'metrics_port'],
+ default: {'server_addresses': 'localhost:8080',
+ 'test_duration-secs': -1,
+ 'num_channels_per_server': 1,
+ 'num_stubs_per_channel': 1,
+ 'metrics_port': '8081'}
+ });
+ var server_addresses = argv.server_addresses.split(',');
+ /* Generate an array of test cases, where the number of instances of each name
+ * corresponds to the number given in the argument.
+ * e.g. 'empty_unary:1,large_unary:2' =>
+ * ['empty_unary', 'large_unary', 'large_unary'] */
+ var test_cases = _.flatten(_.map(argv.test_cases.split(','), function(value) {
+ var split = value.split(':');
+ return _.times(split[1], _.constant(split[0]));
+ }));
+ start(server_addresses, test_cases, argv.num_channels_per_server,
+ argv.num_stubs_per_channel, argv.metrics_port);
+ if (argv['test_duration-secs'] > -1) {
+ setTimeout(stop, argv['test_duration-secs'] * 1000);
+ }
+}
+
+main();
diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js
index 2300096d03..eb268603ea 100644
--- a/src/node/test/call_test.js
+++ b/src/node/test/call_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/channel_test.js b/src/node/test/channel_test.js
index c0ae2b769a..0cdb633659 100644
--- a/src/node/test/channel_test.js
+++ b/src/node/test/channel_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/common_test.js b/src/node/test/common_test.js
index 66a4205f82..c57b7388f6 100644
--- a/src/node/test/common_test.js
+++ b/src/node/test/common_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js
index 712c70706d..414b1ac9c0 100644
--- a/src/node/test/constant_test.js
+++ b/src/node/test/constant_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js
index 294600c85a..794215b246 100644
--- a/src/node/test/credentials_test.js
+++ b/src/node/test/credentials_test.js
@@ -398,18 +398,20 @@ describe('client credentials', function() {
metadataUpdater);
});
it('Should update metadata on a unary call', function(done) {
- var call = client.unary({}, function(err, data) {
- assert.ifError(err);
- }, null, {credentials: updater_creds});
+ var call = client.unary({}, {credentials: updater_creds},
+ function(err, data) {
+ assert.ifError(err);
+ });
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
done();
});
});
it('should update metadata on a client streaming call', function(done) {
- var call = client.clientStream(function(err, data) {
- assert.ifError(err);
- }, null, {credentials: updater_creds});
+ var call = client.clientStream({credentials: updater_creds},
+ function(err, data) {
+ assert.ifError(err);
+ });
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
done();
@@ -417,7 +419,7 @@ describe('client credentials', function() {
call.end();
});
it('should update metadata on a server streaming call', function(done) {
- var call = client.serverStream({}, null, {credentials: updater_creds});
+ var call = client.serverStream({}, {credentials: updater_creds});
call.on('data', function() {});
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
@@ -425,7 +427,7 @@ describe('client credentials', function() {
});
});
it('should update metadata on a bidi streaming call', function(done) {
- var call = client.bidiStream(null, {credentials: updater_creds});
+ var call = client.bidiStream({credentials: updater_creds});
call.on('data', function() {});
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
@@ -443,9 +445,10 @@ describe('client credentials', function() {
altMetadataUpdater);
var combined_updater = grpc.credentials.combineCallCredentials(
updater_creds, alt_updater_creds);
- var call = client.unary({}, function(err, data) {
- assert.ifError(err);
- }, null, {credentials: combined_updater});
+ var call = client.unary({}, {credentials: combined_updater},
+ function(err, data) {
+ assert.ifError(err);
+ });
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
assert.deepEqual(metadata.get('other_plugin_key'),
diff --git a/src/node/test/echo_service.proto b/src/node/test/echo_service.proto
index 11b4f18c35..fc941a2904 100644
--- a/src/node/test/echo_service.proto
+++ b/src/node/test/echo_service.proto
@@ -1,4 +1,4 @@
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index 353c6c761d..f127a41de9 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/server_test.js b/src/node/test/server_test.js
index 71a9647184..ed311c8605 100644
--- a/src/node/test/server_test.js
+++ b/src/node/test/server_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index edbfc0a288..b96e8e487c 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -404,18 +404,18 @@ describe('Echo metadata', function() {
server.forceShutdown();
});
it('with unary call', function(done) {
- var call = client.unary({}, function(err, data) {
+ var call = client.unary({}, metadata, function(err, data) {
assert.ifError(err);
- }, metadata);
+ });
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('key'), ['value']);
done();
});
});
it('with client stream call', function(done) {
- var call = client.clientStream(function(err, data) {
+ var call = client.clientStream(metadata, function(err, data) {
assert.ifError(err);
- }, metadata);
+ });
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('key'), ['value']);
done();
@@ -441,8 +441,8 @@ describe('Echo metadata', function() {
});
it('shows the correct user-agent string', function(done) {
var version = require('../../../package.json').version;
- var call = client.unary({}, function(err, data) { assert.ifError(err); },
- metadata);
+ var call = client.unary({}, metadata,
+ function(err, data) { assert.ifError(err); });
call.on('metadata', function(metadata) {
assert(_.startsWith(metadata.get('user-agent')[0],
'grpc-node/' + version));
@@ -452,8 +452,8 @@ describe('Echo metadata', function() {
it('properly handles duplicate values', function(done) {
var dup_metadata = metadata.clone();
dup_metadata.add('key', 'value2');
- var call = client.unary({}, function(err, data) {assert.ifError(err); },
- dup_metadata);
+ var call = client.unary({}, dup_metadata,
+ function(err, data) {assert.ifError(err); });
call.on('metadata', function(resp_metadata) {
// Two arrays are equal iff their symmetric difference is empty
assert.deepEqual(_.xor(dup_metadata.get('key'), resp_metadata.get('key')),
@@ -954,7 +954,7 @@ describe('Call propagation', function() {
done = multiDone(done, 2);
var call;
proxy_impl.unary = function(parent, callback) {
- client.unary(parent.request, function(err, value) {
+ client.unary(parent.request, {parent: parent}, function(err, value) {
try {
assert(err);
assert.strictEqual(err.code, grpc.status.CANCELLED);
@@ -962,7 +962,7 @@ describe('Call propagation', function() {
callback(err, value);
done();
}
- }, null, {parent: parent});
+ });
call.cancel();
};
proxy.addProtoService(test_service, proxy_impl);
@@ -976,7 +976,7 @@ describe('Call propagation', function() {
done = multiDone(done, 2);
var call;
proxy_impl.clientStream = function(parent, callback) {
- client.clientStream(function(err, value) {
+ client.clientStream({parent: parent}, function(err, value) {
try {
assert(err);
assert.strictEqual(err.code, grpc.status.CANCELLED);
@@ -984,7 +984,7 @@ describe('Call propagation', function() {
callback(err, value);
done();
}
- }, null, {parent: parent});
+ });
call.cancel();
};
proxy.addProtoService(test_service, proxy_impl);
@@ -998,8 +998,7 @@ describe('Call propagation', function() {
done = multiDone(done, 2);
var call;
proxy_impl.serverStream = function(parent) {
- var child = client.serverStream(parent.request, null,
- {parent: parent});
+ var child = client.serverStream(parent.request, {parent: parent});
child.on('data', function() {});
child.on('error', function(err) {
assert(err);
@@ -1023,7 +1022,7 @@ describe('Call propagation', function() {
done = multiDone(done, 2);
var call;
proxy_impl.bidiStream = function(parent) {
- var child = client.bidiStream(null, {parent: parent});
+ var child = client.bidiStream({parent: parent});
child.on('data', function() {});
child.on('error', function(err) {
assert(err);
@@ -1051,7 +1050,8 @@ describe('Call propagation', function() {
it('With a client stream call', function(done) {
done = multiDone(done, 2);
proxy_impl.clientStream = function(parent, callback) {
- client.clientStream(function(err, value) {
+ var options = {parent: parent, propagate_flags: deadline_flags};
+ client.clientStream(options, function(err, value) {
try {
assert(err);
assert(err.code === grpc.status.DEADLINE_EXCEEDED ||
@@ -1060,7 +1060,7 @@ describe('Call propagation', function() {
callback(err, value);
done();
}
- }, null, {parent: parent, propagate_flags: deadline_flags});
+ });
};
proxy.addProtoService(test_service, proxy_impl);
var proxy_port = proxy.bind('localhost:0', server_insecure_creds);
@@ -1069,15 +1069,15 @@ describe('Call propagation', function() {
grpc.credentials.createInsecure());
var deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1);
- proxy_client.clientStream(function(err, value) {
+ proxy_client.clientStream({deadline: deadline}, function(err, value) {
done();
- }, null, {deadline: deadline});
+ });
});
it('With a bidi stream call', function(done) {
done = multiDone(done, 2);
proxy_impl.bidiStream = function(parent) {
var child = client.bidiStream(
- null, {parent: parent, propagate_flags: deadline_flags});
+ {parent: parent, propagate_flags: deadline_flags});
child.on('data', function() {});
child.on('error', function(err) {
assert(err);
@@ -1093,7 +1093,7 @@ describe('Call propagation', function() {
grpc.credentials.createInsecure());
var deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1);
- var call = proxy_client.bidiStream(null, {deadline: deadline});
+ var call = proxy_client.bidiStream({deadline: deadline});
call.on('data', function() {});
call.on('error', function(err) {
done();
diff --git a/src/node/test/test_messages.proto b/src/node/test/test_messages.proto
index 9b8cb875ee..a1a6a32833 100644
--- a/src/node/test/test_messages.proto
+++ b/src/node/test/test_messages.proto
@@ -1,4 +1,4 @@
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/node/test/test_service.proto b/src/node/test/test_service.proto
index 0ac2ae79a7..c86ce51d91 100644
--- a/src/node/test/test_service.proto
+++ b/src/node/test/test_service.proto
@@ -1,4 +1,4 @@
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without