aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/node/performance
diff options
context:
space:
mode:
Diffstat (limited to 'src/node/performance')
-rw-r--r--src/node/performance/benchmark_client.js365
-rw-r--r--src/node/performance/benchmark_client_express.js287
-rw-r--r--src/node/performance/benchmark_server.js189
-rw-r--r--src/node/performance/benchmark_server_express.js96
-rw-r--r--src/node/performance/generic_service.js40
-rw-r--r--src/node/performance/histogram.js165
-rw-r--r--src/node/performance/worker.js50
-rw-r--r--src/node/performance/worker_service_impl.js183
8 files changed, 0 insertions, 1375 deletions
diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js
deleted file mode 100644
index 68afb8a633..0000000000
--- a/src/node/performance/benchmark_client.js
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Benchmark client module
- * @module
- */
-
-'use strict';
-
-var fs = require('fs');
-var path = require('path');
-var util = require('util');
-var EventEmitter = require('events');
-
-var async = require('async');
-var _ = require('lodash');
-var PoissonProcess = require('poisson-process');
-var Histogram = require('./histogram');
-
-var genericService = require('./generic_service');
-
-var grpc = require('../../../');
-var serviceProto = grpc.load({
- root: __dirname + '/../../..',
- file: 'src/proto/grpc/testing/services.proto'}).grpc.testing;
-
-/**
- * Create a buffer filled with size zeroes
- * @param {number} size The length of the buffer
- * @return {Buffer} The new buffer
- */
-function zeroBuffer(size) {
- var zeros = new Buffer(size);
- zeros.fill(0);
- return zeros;
-}
-
-/**
- * Convert a time difference, as returned by process.hrtime, to a number of
- * nanoseconds.
- * @param {Array.<number>} time_diff The time diff, represented as
- * [seconds, nanoseconds]
- * @return {number} The total number of nanoseconds
- */
-function timeDiffToNanos(time_diff) {
- return time_diff[0] * 1e9 + time_diff[1];
-}
-
-/**
- * The BenchmarkClient class. Opens channels to servers and makes RPCs based on
- * parameters from the driver, and records statistics about those RPCs.
- * @param {Array.<string>} server_targets List of servers to connect to
- * @param {number} channels The total number of channels to open
- * @param {Object} histogram_params Options for setting up the histogram
- * @param {Object=} security_params Options for TLS setup. If absent, don't use
- * TLS
- */
-function BenchmarkClient(server_targets, channels, histogram_params,
- security_params) {
- var options = {
- "grpc.max_receive_message_length": -1,
- "grpc.max_send_message_length": -1
- };
- var creds;
- if (security_params) {
- var ca_path;
- if (security_params.use_test_ca) {
- ca_path = path.join(__dirname, '../test/data/ca.pem');
- var ca_data = fs.readFileSync(ca_path);
- creds = grpc.credentials.createSsl(ca_data);
- } else {
- creds = grpc.credentials.createSsl();
- }
- if (security_params.server_host_override) {
- var host_override = security_params.server_host_override;
- options['grpc.ssl_target_name_override'] = host_override;
- options['grpc.default_authority'] = host_override;
- }
- } else {
- creds = grpc.credentials.createInsecure();
- }
-
- this.clients = [];
- var GenericClient = grpc.makeGenericClientConstructor(genericService);
- this.genericClients = [];
-
- for (var i = 0; i < channels; i++) {
- this.clients[i] = new serviceProto.BenchmarkService(
- server_targets[i % server_targets.length], creds, options);
- this.genericClients[i] = new GenericClient(
- server_targets[i % server_targets.length], creds, options);
- }
-
- this.histogram = new Histogram(histogram_params.resolution,
- histogram_params.max_possible);
-
- this.running = false;
-
- this.pending_calls = 0;
-};
-
-util.inherits(BenchmarkClient, EventEmitter);
-
-/**
- * Start every client in the list of clients by waiting for each to be ready,
- * then starting outstanding_rpcs_per_channel calls on each of them
- * @param {Array<grpc.Client>} client_list The list of clients
- * @param {Number} outstanding_rpcs_per_channel The number of calls to start
- * on each client
- * @param {function(grpc.Client)} makeCall Function to make a single call on
- * a single client
- * @param {EventEmitter} emitter The event emitter to send errors on, if
- * necessary
- */
-function startAllClients(client_list, outstanding_rpcs_per_channel, makeCall,
- emitter) {
- var ready_wait_funcs = _.map(client_list, function(client) {
- return _.partial(grpc.waitForClientReady, client, Infinity);
- });
- async.parallel(ready_wait_funcs, function(err) {
- if (err) {
- emitter.emit('error', err);
- return;
- }
-
- _.each(client_list, function(client) {
- _.times(outstanding_rpcs_per_channel, function() {
- makeCall(client);
- });
- });
- });
-}
-
-/**
- * Start a closed-loop test. For each channel, start
- * outstanding_rpcs_per_channel RPCs. Then, whenever an RPC finishes, start
- * another one.
- * @param {number} outstanding_rpcs_per_channel Number of RPCs to start per
- * channel
- * @param {string} rpc_type Which method to call. Should be 'UNARY' or
- * 'STREAMING'
- * @param {number} req_size The size of the payload to send with each request
- * @param {number} resp_size The size of payload to request be sent in responses
- * @param {boolean} generic Indicates that the generic (non-proto) clients
- * should be used
- */
-BenchmarkClient.prototype.startClosedLoop = function(
- outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, generic) {
- var self = this;
-
- self.running = true;
-
- self.last_wall_time = process.hrtime();
-
- self.last_usage = process.cpuUsage();
-
- var makeCall;
-
- var argument;
- var client_list;
- if (generic) {
- argument = zeroBuffer(req_size);
- client_list = self.genericClients;
- } else {
- argument = {
- response_size: resp_size,
- payload: {
- body: zeroBuffer(req_size)
- }
- };
- client_list = self.clients;
- }
-
- if (rpc_type == 'UNARY') {
- makeCall = function(client) {
- if (self.running) {
- self.pending_calls++;
- var start_time = process.hrtime();
- client.unaryCall(argument, function(error, response) {
- if (error) {
- self.emit('error', new Error('Client error: ' + error.message));
- self.running = false;
- return;
- }
- var time_diff = process.hrtime(start_time);
- self.histogram.add(timeDiffToNanos(time_diff));
- makeCall(client);
- self.pending_calls--;
- if ((!self.running) && self.pending_calls == 0) {
- self.emit('finished');
- }
- });
- }
- };
- } else {
- makeCall = function(client) {
- if (self.running) {
- self.pending_calls++;
- var call = client.streamingCall();
- var start_time = process.hrtime();
- call.write(argument);
- call.on('data', function() {
- var time_diff = process.hrtime(start_time);
- self.histogram.add(timeDiffToNanos(time_diff));
- self.pending_calls--;
- if (self.running) {
- self.pending_calls++;
- start_time = process.hrtime();
- call.write(argument);
- } else {
- call.end();
- if (self.pending_calls == 0) {
- self.emit('finished');
- }
- }
- });
- call.on('error', function(error) {
- self.emit('error', new Error('Client error: ' + error.message));
- self.running = false;
- });
- }
- };
- }
-
- startAllClients(client_list, outstanding_rpcs_per_channel, makeCall, self);
-};
-
-/**
- * Start a poisson test. For each channel, this initiates a number of Poisson
- * processes equal to outstanding_rpcs_per_channel, where each Poisson process
- * has the load parameter offered_load.
- * @param {number} outstanding_rpcs_per_channel Number of RPCs to start per
- * channel
- * @param {string} rpc_type Which method to call. Should be 'UNARY' or
- * 'STREAMING'
- * @param {number} req_size The size of the payload to send with each request
- * @param {number} resp_size The size of payload to request be sent in responses
- * @param {number} offered_load The load parameter for the Poisson process
- * @param {boolean} generic Indicates that the generic (non-proto) clients
- * should be used
- */
-BenchmarkClient.prototype.startPoisson = function(
- outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, offered_load,
- generic) {
- var self = this;
-
- self.running = true;
-
- self.last_wall_time = process.hrtime();
-
- self.last_usage = process.cpuUsage();
-
- var makeCall;
-
- var argument;
- var client_list;
- if (generic) {
- argument = zeroBuffer(req_size);
- client_list = self.genericClients;
- } else {
- argument = {
- response_size: resp_size,
- payload: {
- body: zeroBuffer(req_size)
- }
- };
- client_list = self.clients;
- }
-
- if (rpc_type == 'UNARY') {
- makeCall = function(client, poisson) {
- if (self.running) {
- self.pending_calls++;
- var start_time = process.hrtime();
- client.unaryCall(argument, function(error, response) {
- if (error) {
- self.emit('error', new Error('Client error: ' + error.message));
- self.running = false;
- return;
- }
- var time_diff = process.hrtime(start_time);
- self.histogram.add(timeDiffToNanos(time_diff));
- self.pending_calls--;
- if ((!self.running) && self.pending_calls == 0) {
- self.emit('finished');
- }
- });
- } else {
- poisson.stop();
- }
- };
- } else {
- self.emit('error', new Error('Streaming Poisson benchmarks not supported'));
- return;
- }
-
- var averageIntervalMs = (1 / offered_load) * 1000;
-
- startAllClients(client_list, outstanding_rpcs_per_channel, function(client){
- var p = PoissonProcess.create(averageIntervalMs, function() {
- makeCall(client, p);
- });
- p.start();
- }, self);
-};
-
-/**
- * Return curent statistics for the client. If reset is set, restart
- * statistic collection.
- * @param {boolean} reset Indicates that statistics should be reset
- * @return {object} Client statistics
- */
-BenchmarkClient.prototype.mark = function(reset) {
- var wall_time_diff = process.hrtime(this.last_wall_time);
- var usage_diff = process.cpuUsage(this.last_usage);
- var histogram = this.histogram;
- if (reset) {
- this.last_wall_time = process.hrtime();
- this.last_usage = process.cpuUsage();
- this.histogram = new Histogram(histogram.resolution,
- histogram.max_possible);
- }
-
- return {
- latencies: {
- bucket: histogram.getContents(),
- min_seen: histogram.minimum(),
- max_seen: histogram.maximum(),
- sum: histogram.getSum(),
- sum_of_squares: histogram.sumOfSquares(),
- count: histogram.getCount()
- },
- time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
- time_user: usage_diff.user / 1000000,
- time_system: usage_diff.system / 1000000
- };
-};
-
-/**
- * Stop the clients.
- * @param {function} callback Called when the clients have finished shutting
- * down
- */
-BenchmarkClient.prototype.stop = function(callback) {
- this.running = false;
- this.on('finished', callback);
-};
-
-module.exports = BenchmarkClient;
diff --git a/src/node/performance/benchmark_client_express.js b/src/node/performance/benchmark_client_express.js
deleted file mode 100644
index 815843fede..0000000000
--- a/src/node/performance/benchmark_client_express.js
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Benchmark client module
- * @module
- */
-
-'use strict';
-
-var fs = require('fs');
-var path = require('path');
-var util = require('util');
-var EventEmitter = require('events');
-var http = require('http');
-var https = require('https');
-
-var async = require('async');
-var _ = require('lodash');
-var PoissonProcess = require('poisson-process');
-var Histogram = require('./histogram');
-
-/**
- * Convert a time difference, as returned by process.hrtime, to a number of
- * nanoseconds.
- * @param {Array.<number>} time_diff The time diff, represented as
- * [seconds, nanoseconds]
- * @return {number} The total number of nanoseconds
- */
-function timeDiffToNanos(time_diff) {
- return time_diff[0] * 1e9 + time_diff[1];
-}
-
-function BenchmarkClient(server_targets, channels, histogram_params,
- security_params) {
- var options = {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json'
- }
- };
- var protocol;
- if (security_params) {
- var ca_path;
- protocol = https;
- this.request = _.bind(https.request, https);
- if (security_params.use_test_ca) {
- ca_path = path.join(__dirname, '../test/data/ca.pem');
- var ca_data = fs.readFileSync(ca_path);
- options.ca = ca_data;
- }
- if (security_params.server_host_override) {
- var host_override = security_params.server_host_override;
- options.servername = host_override;
- }
- } else {
- protocol = http;
- }
-
- this.request = _.bind(protocol.request, protocol);
-
- this.client_options = [];
-
- for (var i = 0; i < channels; i++) {
- var host_port;
- host_port = server_targets[i % server_targets.length].split(':');
- var new_options = _.assign({hostname: host_port[0], port: +host_port[1]}, options);
- this.client_options[i] = new_options;
- }
-
- this.histogram = new Histogram(histogram_params.resolution,
- histogram_params.max_possible);
-
- this.running = false;
-
- this.pending_calls = 0;
-}
-
-util.inherits(BenchmarkClient, EventEmitter);
-
-function startAllClients(client_options_list, outstanding_rpcs_per_channel,
- makeCall, emitter) {
- _.each(client_options_list, function(client_options) {
- _.times(outstanding_rpcs_per_channel, function() {
- makeCall(client_options);
- });
- });
-}
-
-BenchmarkClient.prototype.startClosedLoop = function(
- outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, generic) {
- var self = this;
-
- var options = {};
-
- self.running = true;
-
- if (rpc_type == 'UNARY') {
- options.path = '/serviceProto.BenchmarkService.service/unaryCall';
- } else {
- self.emit('error', new Error('Unsupported rpc_type: ' + rpc_type));
- }
-
- if (generic) {
- self.emit('error', new Error('Generic client not supported'));
- }
-
- self.last_wall_time = process.hrtime();
- self.last_usage = process.cpuUsage();
-
- var argument = {
- response_size: resp_size,
- payload: {
- body: '0'.repeat(req_size)
- }
- };
-
- function makeCall(client_options) {
- if (self.running) {
- self.pending_calls++;
- var start_time = process.hrtime();
- function finishCall(success) {
- if (success) {
- var time_diff = process.hrtime(start_time);
- self.histogram.add(timeDiffToNanos(time_diff));
- }
- makeCall(client_options);
- self.pending_calls--;
- if ((!self.running) && self.pending_calls == 0) {
- self.emit('finished');
- }
- }
- var req = self.request(client_options, function(res) {
- var res_data = '';
- res.on('data', function(data) {
- res_data += data;
- });
- res.on('end', function() {
- JSON.parse(res_data);
- finishCall(true);
- });
- });
- req.write(JSON.stringify(argument));
- req.end();
- req.on('error', function(error) {
- if (error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT') {
- finishCall(false);
- return;
- }
- self.emit('error', new Error('Client error: ' + error.message));
- self.running = false;
- });
- }
- }
-
- startAllClients(_.map(self.client_options, _.partial(_.assign, options)),
- outstanding_rpcs_per_channel, makeCall, self);
-};
-
-BenchmarkClient.prototype.startPoisson = function(
- outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, offered_load,
- generic) {
- var self = this;
-
- var options = {};
-
- self.running = true;
-
- if (rpc_type == 'UNARY') {
- options.path = '/serviceProto.BenchmarkService.service/unaryCall';
- } else {
- self.emit('error', new Error('Unsupported rpc_type: ' + rpc_type));
- }
-
- if (generic) {
- self.emit('error', new Error('Generic client not supported'));
- }
-
- self.last_wall_time = process.hrtime();
- self.last_usage = process.cpuUsage();
-
- var argument = {
- response_size: resp_size,
- payload: {
- body: '0'.repeat(req_size)
- }
- };
-
- function makeCall(client_options, poisson) {
- if (self.running) {
- self.pending_calls++;
- var start_time = process.hrtime();
- var req = self.request(client_options, function(res) {
- var res_data = '';
- res.on('data', function(data) {
- res_data += data;
- });
- res.on('end', function() {
- JSON.parse(res_data);
- var time_diff = process.hrtime(start_time);
- self.histogram.add(timeDiffToNanos(time_diff));
- self.pending_calls--;
- if ((!self.running) && self.pending_calls == 0) {
- self.emit('finished');
- }
- });
- });
- req.write(JSON.stringify(argument));
- req.end();
- req.on('error', function(error) {
- self.emit('error', new Error('Client error: ' + error.message));
- self.running = false;
- });
- } else {
- poisson.stop();
- }
- }
-
- var averageIntervalMs = (1 / offered_load) * 1000;
-
- startAllClients(_.map(self.client_options, _.partial(_.assign, options)),
- outstanding_rpcs_per_channel, function(opts){
- var p = PoissonProcess.create(averageIntervalMs, function() {
- makeCall(opts, p);
- });
- p.start();
- }, self);
-};
-
-/**
- * Return curent statistics for the client. If reset is set, restart
- * statistic collection.
- * @param {boolean} reset Indicates that statistics should be reset
- * @return {object} Client statistics
- */
-BenchmarkClient.prototype.mark = function(reset) {
- var wall_time_diff = process.hrtime(this.last_wall_time);
- var usage_diff = process.cpuUsage(this.last_usage);
- var histogram = this.histogram;
- if (reset) {
- this.last_wall_time = process.hrtime();
- this.last_usage = process.cpuUsage();
- this.histogram = new Histogram(histogram.resolution,
- histogram.max_possible);
- }
-
- return {
- latencies: {
- bucket: histogram.getContents(),
- min_seen: histogram.minimum(),
- max_seen: histogram.maximum(),
- sum: histogram.getSum(),
- sum_of_squares: histogram.sumOfSquares(),
- count: histogram.getCount()
- },
- time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
- time_user: usage_diff.user / 1000000,
- time_system: usage_diff.system / 1000000
- };
-};
-
-/**
- * Stop the clients.
- * @param {function} callback Called when the clients have finished shutting
- * down
- */
-BenchmarkClient.prototype.stop = function(callback) {
- this.running = false;
- this.on('finished', callback);
-};
-
-module.exports = BenchmarkClient;
diff --git a/src/node/performance/benchmark_server.js b/src/node/performance/benchmark_server.js
deleted file mode 100644
index 8d3a2b9049..0000000000
--- a/src/node/performance/benchmark_server.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Benchmark server module
- * @module
- */
-
-'use strict';
-
-var fs = require('fs');
-var path = require('path');
-var EventEmitter = require('events');
-var util = require('util');
-
-var genericService = require('./generic_service');
-
-var grpc = require('../../../');
-var serviceProto = grpc.load({
- root: __dirname + '/../../..',
- file: 'src/proto/grpc/testing/services.proto'}).grpc.testing;
-
-/**
- * Create a buffer filled with size zeroes
- * @param {number} size The length of the buffer
- * @return {Buffer} The new buffer
- */
-function zeroBuffer(size) {
- var zeros = new Buffer(size);
- zeros.fill(0);
- return zeros;
-}
-
-/**
- * Handler for the unary benchmark method. Simply responds with a payload
- * containing the requested number of zero bytes.
- * @param {Call} call The call object to be handled
- * @param {function} callback The callback to call with the response
- */
-function unaryCall(call, callback) {
- var req = call.request;
- var payload = {body: zeroBuffer(req.response_size)};
- callback(null, {payload: payload});
-}
-
-/**
- * Handler for the streaming benchmark method. Simply responds to each request
- * with a payload containing the requested number of zero bytes.
- * @param {Call} call The call object to be handled
- */
-function streamingCall(call) {
- call.on('data', function(value) {
- var payload = {body: zeroBuffer(value.response_size)};
- call.write({payload: payload});
- });
- call.on('end', function() {
- call.end();
- });
-}
-
-function makeUnaryGenericCall(response_size) {
- var response = zeroBuffer(response_size);
- return function unaryGenericCall(call, callback) {
- callback(null, response);
- };
-}
-
-function makeStreamingGenericCall(response_size) {
- var response = zeroBuffer(response_size);
- return function streamingGenericCall(call) {
- call.on('data', function(value) {
- call.write(response);
- });
- call.on('end', function() {
- call.end();
- });
- };
-}
-
-/**
- * BenchmarkServer class. Constructed based on parameters from the driver and
- * stores statistics.
- * @param {string} host The host to serve on
- * @param {number} port The port to listen to
- * @param {boolean} tls Indicates whether TLS should be used
- * @param {boolean} generic Indicates whether to use the generic service
- * @param {number=} response_size The response size for the generic service
- */
-function BenchmarkServer(host, port, tls, generic, response_size) {
- var server_creds;
- var host_override;
- if (tls) {
- var key_path = path.join(__dirname, '../test/data/server1.key');
- var pem_path = path.join(__dirname, '../test/data/server1.pem');
-
- var key_data = fs.readFileSync(key_path);
- var pem_data = fs.readFileSync(pem_path);
- server_creds = grpc.ServerCredentials.createSsl(null,
- [{private_key: key_data,
- cert_chain: pem_data}]);
- } else {
- server_creds = grpc.ServerCredentials.createInsecure();
- }
-
- var options = {
- "grpc.max_receive_message_length": -1,
- "grpc.max_send_message_length": -1
- };
-
- var server = new grpc.Server(options);
- this.port = server.bind(host + ':' + port, server_creds);
- if (generic) {
- server.addService(genericService, {
- unaryCall: makeUnaryGenericCall(response_size),
- streamingCall: makeStreamingGenericCall(response_size)
- });
- } else {
- server.addService(serviceProto.BenchmarkService.service, {
- unaryCall: unaryCall,
- streamingCall: streamingCall
- });
- }
- this.server = server;
-}
-
-util.inherits(BenchmarkServer, EventEmitter);
-
-/**
- * Start the benchmark server.
- */
-BenchmarkServer.prototype.start = function() {
- this.server.start();
- this.last_wall_time = process.hrtime();
- this.last_usage = process.cpuUsage();
- this.emit('started');
-};
-
-/**
- * Return the port number that the server is bound to.
- * @return {Number} The port number
- */
-BenchmarkServer.prototype.getPort = function() {
- return this.port;
-};
-
-/**
- * Return current statistics for the server. If reset is set, restart
- * statistic collection.
- * @param {boolean} reset Indicates that statistics should be reset
- * @return {object} Server statistics
- */
-BenchmarkServer.prototype.mark = function(reset) {
- var wall_time_diff = process.hrtime(this.last_wall_time);
- var usage_diff = process.cpuUsage(this.last_usage);
- if (reset) {
- this.last_wall_time = process.hrtime();
- this.last_usage = process.cpuUsage();
- }
- return {
- time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
- time_user: usage_diff.user / 1000000,
- time_system: usage_diff.system / 1000000
- };
-};
-
-/**
- * Stop the server.
- * @param {function} callback Called when the server has finished shutting down
- */
-BenchmarkServer.prototype.stop = function(callback) {
- this.server.tryShutdown(callback);
-};
-
-module.exports = BenchmarkServer;
diff --git a/src/node/performance/benchmark_server_express.js b/src/node/performance/benchmark_server_express.js
deleted file mode 100644
index 73e54091a4..0000000000
--- a/src/node/performance/benchmark_server_express.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Benchmark server module
- * @module
- */
-
-'use strict';
-
-var fs = require('fs');
-var path = require('path');
-var http = require('http');
-var https = require('https');
-var EventEmitter = require('events');
-var util = require('util');
-
-var express = require('express');
-var bodyParser = require('body-parser');
-
-function unaryCall(req, res) {
- var reqObj = req.body;
- var payload = {body: '0'.repeat(reqObj.response_size)};
- res.json(payload);
-}
-
-function BenchmarkServer(host, port, tls, generic, response_size) {
- var app = express();
- app.use(bodyParser.json());
- app.put('/serviceProto.BenchmarkService.service/unaryCall', unaryCall);
- this.input_host = host;
- this.input_port = port;
- if (tls) {
- var credentials = {};
- var key_path = path.join(__dirname, '../test/data/server1.key');
- var pem_path = path.join(__dirname, '../test/data/server1.pem');
-
- var key_data = fs.readFileSync(key_path);
- var pem_data = fs.readFileSync(pem_path);
- credentials['key'] = key_data;
- credentials['cert'] = pem_data;
- this.server = https.createServer(credentials, app);
- } else {
- this.server = http.createServer(app);
- }
-}
-
-util.inherits(BenchmarkServer, EventEmitter);
-
-BenchmarkServer.prototype.start = function() {
- var self = this;
- this.server.listen(this.input_port, this.input_hostname, function() {
- self.last_wall_time = process.hrtime();
- self.last_usage = process.cpuUsage();
- self.emit('started');
- });
-};
-
-BenchmarkServer.prototype.getPort = function() {
- return this.server.address().port;
-};
-
-BenchmarkServer.prototype.mark = function(reset) {
- var wall_time_diff = process.hrtime(this.last_wall_time);
- var usage_diff = process.cpuUsage(this.last_usage);
- if (reset) {
- this.last_wall_time = process.hrtime();
- this.last_usage = process.cpuUsage();
- }
- return {
- time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
- time_user: usage_diff.user / 1000000,
- time_system: usage_diff.system / 1000000
- };
-};
-
-BenchmarkServer.prototype.stop = function(callback) {
- this.server.close(callback);
-};
-
-module.exports = BenchmarkServer;
diff --git a/src/node/performance/generic_service.js b/src/node/performance/generic_service.js
deleted file mode 100644
index 8e76c50d58..0000000000
--- a/src/node/performance/generic_service.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-var _ = require('lodash');
-
-module.exports = {
- 'unaryCall' : {
- path: '/grpc.testing.BenchmarkService/UnaryCall',
- requestStream: false,
- responseStream: false,
- requestSerialize: _.identity,
- requestDeserialize: _.identity,
- responseSerialize: _.identity,
- responseDeserialize: _.identity
- },
- 'streamingCall' : {
- path: '/grpc.testing.BenchmarkService/StreamingCall',
- requestStream: true,
- responseStream: true,
- requestSerialize: _.identity,
- requestDeserialize: _.identity,
- responseSerialize: _.identity,
- responseDeserialize: _.identity
- }
-};
diff --git a/src/node/performance/histogram.js b/src/node/performance/histogram.js
deleted file mode 100644
index a03f2c13a2..0000000000
--- a/src/node/performance/histogram.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Histogram module. Exports the Histogram class
- * @module
- */
-
-'use strict';
-
-/**
- * Histogram class. Collects data and exposes a histogram and other statistics.
- * This data structure is taken directly from src/core/support/histogram.c, but
- * pared down to the statistics needed for client stats in
- * test/proto/benchmarks/stats.proto.
- * @constructor
- * @param {number} resolution The histogram's bucket resolution. Must be positive
- * @param {number} max_possible The maximum allowed value. Must be greater than 1
- */
-function Histogram(resolution, max_possible) {
- this.resolution = resolution;
- this.max_possible = max_possible;
-
- this.sum = 0;
- this.sum_of_squares = 0;
- this.multiplier = 1 + resolution;
- this.count = 0;
- this.min_seen = max_possible;
- this.max_seen = 0;
- this.buckets = [];
- for (var i = 0; i < this.bucketFor(max_possible) + 1; i++) {
- this.buckets[i] = 0;
- }
-}
-
-/**
- * Get the bucket index for a given value.
- * @param {number} value The value to check
- * @return {number} The bucket index
- */
-Histogram.prototype.bucketFor = function(value) {
- return Math.floor(Math.log(value) / Math.log(this.multiplier));
-};
-
-/**
- * Get the minimum value for a given bucket index
- * @param {number} The bucket index to check
- * @return {number} The minimum value for that bucket
- */
-Histogram.prototype.bucketStart = function(index) {
- return Math.pow(this.multiplier, index);
-};
-
-/**
- * Add a value to the histogram. This updates all statistics with the new
- * value. Those statistics should not be modified except with this function
- * @param {number} value The value to add
- */
-Histogram.prototype.add = function(value) {
- // Ensure value is a number
- value = +value;
- this.sum += value;
- this.sum_of_squares += value * value;
- this.count++;
- if (value < this.min_seen) {
- this.min_seen = value;
- }
- if (value > this.max_seen) {
- this.max_seen = value;
- }
- this.buckets[this.bucketFor(value)]++;
-};
-
-/**
- * Get the mean of all added values
- * @return {number} The mean
- */
-Histogram.prototype.mean = function() {
- return this.sum / this.count;
-};
-
-/**
- * Get the variance of all added values. Used to calulate the standard deviation
- * @return {number} The variance
- */
-Histogram.prototype.variance = function() {
- if (this.count == 0) {
- return 0;
- }
- return (this.sum_of_squares * this.count - this.sum * this.sum) /
- (this.count * this.count);
-};
-
-/**
- * Get the standard deviation of all added values
- * @return {number} The standard deviation
- */
-Histogram.prototype.stddev = function() {
- return Math.sqrt(this.variance);
-};
-
-/**
- * Get the maximum among all added values
- * @return {number} The maximum
- */
-Histogram.prototype.maximum = function() {
- return this.max_seen;
-};
-
-/**
- * Get the minimum among all added values
- * @return {number} The minimum
- */
-Histogram.prototype.minimum = function() {
- return this.min_seen;
-};
-
-/**
- * Get the number of all added values
- * @return {number} The count
- */
-Histogram.prototype.getCount = function() {
- return this.count;
-};
-
-/**
- * Get the sum of all added values
- * @return {number} The sum
- */
-Histogram.prototype.getSum = function() {
- return this.sum;
-};
-
-/**
- * Get the sum of squares of all added values
- * @return {number} The sum of squares
- */
-Histogram.prototype.sumOfSquares = function() {
- return this.sum_of_squares;
-};
-
-/**
- * Get the raw histogram as a list of bucket sizes
- * @return {Array.<number>} The buckets
- */
-Histogram.prototype.getContents = function() {
- return this.buckets;
-};
-
-module.exports = Histogram;
diff --git a/src/node/performance/worker.js b/src/node/performance/worker.js
deleted file mode 100644
index d0fb3bcb28..0000000000
--- a/src/node/performance/worker.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-'use strict';
-
-var console = require('console');
-var WorkerServiceImpl = require('./worker_service_impl');
-
-var grpc = require('../../../');
-var serviceProto = grpc.load({
- root: __dirname + '/../../..',
- file: 'src/proto/grpc/testing/services.proto'}).grpc.testing;
-
-function runServer(port, benchmark_impl) {
- var server_creds = grpc.ServerCredentials.createInsecure();
- var server = new grpc.Server();
- server.addService(serviceProto.WorkerService.service,
- new WorkerServiceImpl(benchmark_impl, server));
- var address = '0.0.0.0:' + port;
- server.bind(address, server_creds);
- server.start();
- console.log('running QPS worker on %s', address);
- return server;
-}
-
-if (require.main === module) {
- Error.stackTraceLimit = Infinity;
- var parseArgs = require('minimist');
- var argv = parseArgs(process.argv, {
- string: ['driver_port', 'benchmark_impl']
- });
- runServer(argv.driver_port, argv.benchmark_impl);
-}
-
-exports.runServer = runServer;
diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js
deleted file mode 100644
index a73d77efc3..0000000000
--- a/src/node/performance/worker_service_impl.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-'use strict';
-
-var os = require('os');
-var console = require('console');
-var BenchmarkClient = require('./benchmark_client');
-var BenchmarkServer = require('./benchmark_server');
-
-module.exports = function WorkerServiceImpl(benchmark_impl, server) {
- var BenchmarkClient;
- var BenchmarkServer;
- switch (benchmark_impl) {
- case 'grpc':
- BenchmarkClient = require('./benchmark_client');
- BenchmarkServer = require('./benchmark_server');
- break;
- case 'express':
- BenchmarkClient = require('./benchmark_client_express');
- BenchmarkServer = require('./benchmark_server_express');
- break;
- default:
- throw new Error('Unrecognized benchmark impl: ' + benchmark_impl);
- }
-
- this.quitWorker = function quitWorker(call, callback) {
- callback(null, {});
- server.tryShutdown(function() {});
- };
-
- this.runClient = function runClient(call) {
- var client;
- call.on('data', function(request) {
- var stats;
- switch (request.argtype) {
- case 'setup':
- var setup = request.setup;
- console.log('ClientConfig %j', setup);
- client = new BenchmarkClient(setup.server_targets,
- setup.client_channels,
- setup.histogram_params,
- setup.security_params);
- client.on('error', function(error) {
- call.emit('error', error);
- });
- var req_size, resp_size, generic;
- switch (setup.payload_config.payload) {
- case 'bytebuf_params':
- req_size = setup.payload_config.bytebuf_params.req_size;
- resp_size = setup.payload_config.bytebuf_params.resp_size;
- generic = true;
- break;
- case 'simple_params':
- req_size = setup.payload_config.simple_params.req_size;
- resp_size = setup.payload_config.simple_params.resp_size;
- generic = false;
- break;
- default:
- call.emit('error', new Error('Unsupported PayloadConfig type' +
- setup.payload_config.payload));
- return;
- }
- switch (setup.load_params.load) {
- case 'closed_loop':
- client.startClosedLoop(setup.outstanding_rpcs_per_channel,
- setup.rpc_type, req_size, resp_size, generic);
- break;
- case 'poisson':
- client.startPoisson(setup.outstanding_rpcs_per_channel,
- setup.rpc_type, req_size, resp_size,
- setup.load_params.poisson.offered_load, generic);
- break;
- default:
- call.emit('error', new Error('Unsupported LoadParams type' +
- setup.load_params.load));
- return;
- }
- stats = client.mark();
- call.write({
- stats: stats
- });
- break;
- case 'mark':
- if (client) {
- stats = client.mark(request.mark.reset);
- call.write({
- stats: stats
- });
- } else {
- call.emit('error', new Error('Got Mark before ClientConfig'));
- }
- break;
- default:
- throw new Error('Nonexistent client argtype option: ' + request.argtype);
- }
- });
- call.on('end', function() {
- client.stop(function() {
- call.end();
- });
- });
- };
-
- this.runServer = function runServer(call) {
- var server;
- call.on('data', function(request) {
- var stats;
- switch (request.argtype) {
- case 'setup':
- console.log('ServerConfig %j', request.setup);
- var setup = request.setup;
- var resp_size, generic;
- if (setup.payload_config) {
- switch (setup.payload_config.payload) {
- case 'bytebuf_params':
- resp_size = setup.payload_config.bytebuf_params.resp_size;
- generic = true;
- break;
- case 'simple_params':
- resp_size = setup.payload_config.simple_params.resp_size;
- generic = false;
- break;
- default:
- call.emit('error', new Error('Unsupported PayloadConfig type' +
- setup.payload_config.payload));
- return;
- }
- }
- server = new BenchmarkServer('[::]', request.setup.port,
- request.setup.security_params,
- generic, resp_size);
- server.on('started', function() {
- stats = server.mark();
- call.write({
- stats: stats,
- port: server.getPort()
- });
- });
- server.start();
- break;
- case 'mark':
- if (server) {
- stats = server.mark(request.mark.reset);
- call.write({
- stats: stats,
- port: server.getPort(),
- cores: 1
- });
- } else {
- call.emit('error', new Error('Got Mark before ServerConfig'));
- }
- break;
- default:
- throw new Error('Nonexistent server argtype option');
- }
- });
- call.on('end', function() {
- server.stop(function() {
- call.end();
- });
- });
- };
-
- this.coreCount = function coreCount(call, callback) {
- callback(null, {cores: os.cpus().length});
- };
-};