From 6acc5f757479d3603c01978d1a93de0d92b7a4eb Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 7 Dec 2015 14:56:32 -0800 Subject: [PATCH] Fixed up the Node benchmark implementation --- src/node/performance/benchmark_client.js | 41 +++++++++++++++++---- src/node/performance/histogram.js | 2 + src/node/performance/worker_service_impl.js | 12 ++++-- test/cpp/qps/single_run_localhost.sh | 9 ++--- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js index cc5fe21ebd5..d97bdbbcaf7 100644 --- a/src/node/performance/benchmark_client.js +++ b/src/node/performance/benchmark_client.js @@ -61,6 +61,17 @@ function zeroBuffer(size) { return zeros; } +/** + * Convert a time difference, as returned by process.hrtime, to a number of + * nanoseconds. + * @param {Array.} 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. @@ -143,9 +154,13 @@ BenchmarkClient.prototype.startClosedLoop = function( self.pending_calls++; var start_time = process.hrtime(); client.unaryCall(argument, function(error, response) { - // Ignoring error for now + 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(time_diff); + self.histogram.add(timeDiffToNanos(time_diff)); makeCall(client); self.pending_calls--; if ((!self.running) && self.pending_calls == 0) { @@ -165,13 +180,17 @@ BenchmarkClient.prototype.startClosedLoop = function( }); call.on('end', function() { var time_diff = process.hrtime(start_time); - self.histogram.add(time_diff); + self.histogram.add(timeDiffToNanos(time_diff)); makeCall(client); self.pending_calls--; if ((!self.running) && self.pending_calls == 0) { self.emit('finished'); } }); + call.on('error', function(error) { + self.emit('error', new Error('Client error: ' + error.message)); + self.running = false; + }); } }; } @@ -218,9 +237,13 @@ BenchmarkClient.prototype.startPoisson = function( self.pending_calls++; var start_time = process.hrtime(); client.unaryCall(argument, function(error, response) { - // Ignoring error for now + 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(time_diff); + self.histogram.add(timeDiffToNanos(time_diff)); self.pending_calls--; if ((!self.running) && self.pending_calls == 0) { self.emit('finished'); @@ -241,12 +264,16 @@ BenchmarkClient.prototype.startPoisson = function( }); call.on('end', function() { var time_diff = process.hrtime(start_time); - self.histogram.add(time_diff); + self.histogram.add(timeDiffToNanos(time_diff)); self.pending_calls--; if ((!self.running) && self.pending_calls == 0) { self.emit('finished'); } }); + call.on('error', function(error) { + self.emit('error', new Error('Client error: ' + error.message)); + self.running = false; + }); } else { poisson.stop(); } @@ -303,7 +330,7 @@ BenchmarkClient.prototype.mark = function(reset) { */ BenchmarkClient.prototype.stop = function(callback) { this.running = false; - self.on('finished', callback); + this.on('finished', callback); }; module.exports = BenchmarkClient; diff --git a/src/node/performance/histogram.js b/src/node/performance/histogram.js index 45e1c23a90f..204d7d47daf 100644 --- a/src/node/performance/histogram.js +++ b/src/node/performance/histogram.js @@ -87,6 +87,8 @@ Histogram.prototype.bucketStart = function(index) { * @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++; diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js index 6de6e7fca53..8841ae13c3e 100644 --- a/src/node/performance/worker_service_impl.js +++ b/src/node/performance/worker_service_impl.js @@ -47,6 +47,9 @@ exports.runClient = function runClient(call) { setup.client_channels, setup.histogram_params, setup.security_params); + client.on('error', function(error) { + call.emit('error', error); + }); switch (setup.load_params.load) { case 'closed_loop': client.startClosedLoop(setup.outstanding_rpcs_per_channel, @@ -65,7 +68,6 @@ exports.runClient = function runClient(call) { setup.load_params.load)); } stats = client.mark(); - console.log(stats); call.write({ stats: stats }); @@ -79,8 +81,9 @@ exports.runClient = function runClient(call) { } else { call.emit('error', new Error('Got Mark before ClientConfig')); } + break; default: - throw new Error('Nonexistent client argtype option'); + throw new Error('Nonexistent client argtype option: ' + request.argtype); } }); call.on('end', function() { @@ -110,10 +113,11 @@ exports.runServer = function runServer(call) { stats = server.mark(request.mark.reset); call.write({ stats: stats, - port: server.getPort() + port: server.getPort(), + cores: 1 }); } else { - call.emit('error', new Error('Got Mark befor ServerConfig')); + call.emit('error', new Error('Got Mark before ServerConfig')); } break; default: diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index f5356f18343..9e70aa68e2d 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -34,17 +34,15 @@ set -ex cd $(dirname $0)/../../.. -killall qps_worker || true - config=opt NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'` -make CONFIG=$config qps_worker qps_driver -j$NUMCPUS +make CONFIG=$config qps_driver -j$NUMCPUS -bins/$config/qps_worker -driver_port 10000 & +node src/node/performance/worker_server.js --driver_port=10000 & PID1=$! -bins/$config/qps_worker -driver_port 10010 & +node src/node/performance/worker_server.js --driver_port=10010 & PID2=$! export QPS_WORKERS="localhost:10000,localhost:10010" @@ -53,4 +51,3 @@ bins/$config/qps_driver $* kill -2 $PID1 $PID2 wait -