From 85df66511ffc0640173a3098431fe6037698d6a1 Mon Sep 17 00:00:00 2001 From: Rudi Cilibrasi Date: Mon, 29 Dec 2014 22:40:08 -0800 Subject: [PATCH 1/3] benchmark: chunky http client benchmark variation and server --- benchmark/net/chunky_http_client.js | 104 ++++++++++++++++++ .../net/http_server_for_chunky_client.js | 45 ++++++++ 2 files changed, 149 insertions(+) create mode 100644 benchmark/net/chunky_http_client.js create mode 100644 benchmark/net/http_server_for_chunky_client.js diff --git a/benchmark/net/chunky_http_client.js b/benchmark/net/chunky_http_client.js new file mode 100644 index 00000000000000..8713433ce8eb70 --- /dev/null +++ b/benchmark/net/chunky_http_client.js @@ -0,0 +1,104 @@ +"use strict"; +// test HTTP throughput in fragmented header case +var common = require('../common.js'); +var net = require('net'); +var test = require('../../test/common.js'); + +var bench = common.createBenchmark(main, { +// len: [1, 4, 8, 16, 32, 64, 128], + len: [1], + num: [5, 50, 500, 2000], + type: ['send'], +} +) + + +function main(conf) { + var len; + var num; + var type; + num = +conf.num; + len = +conf.len; + type = conf.type; + var todo = []; + var headers = []; + // Chose 7 because 9 showed "Connection error" / "Connection closed" + // An odd number could result in a better length dispersion. + for (var i = 7; i <= 7*7*7; i *= 7) + headers.push(Array(i + 1).join('o')); + + function WriteWithCRLF(line) { + todo.push(line + '\r\n'); + } + + function WriteHTTPHeaders(channel, has_keep_alive, extra_header_count) { + todo = [] + WriteWithCRLF('GET / HTTP/1.1'); + WriteWithCRLF('Host: localhost'); + WriteWithCRLF('Connection: keep-alive'); + WriteWithCRLF('Accept: text/html,application/xhtml+xml,' + + 'application/xml;q=0.9,image/webp,*/*;q=0.8'); + WriteWithCRLF('User-Agent: Mozilla/5.0 (X11; Linux x86_64) ' + + 'AppleWebKit/537.36 (KHTML, like Gecko) ' + + 'Chrome/39.0.2171.71 Safari/537.36'); + WriteWithCRLF('Accept-Encoding: gzip, deflate, sdch'); + WriteWithCRLF('Accept-Language: en-US,en;q=0.8'); + for (var i = 0; i < extra_header_count; i++) { + // Utilize first three powers of a small integer for an odd cycle and + // because the fourth power of some integers overloads the server. + WriteWithCRLF('X-Header-' + i + ': ' + headers[i%3]); + } + WriteWithCRLF(''); + todo = todo.join(''); + // Using odd numbers in many places may increase length coverage. + var chunksize = 37; + for (i = 0; i < todo.length; i+=chunksize) { + var cur = todo.slice(i,i+chunksize); + channel.write(cur); + } + } + + var success = 0, failure = 0, min = 10, size = 0; + var mod = 317, mult = 17, add = 11; + var count = 0; + var PIPE = test.PIPE; + var socket = net.connect(PIPE, function() { + bench.start(); + WriteHTTPHeaders(socket, 1, +conf.len); + socket.setEncoding('utf8') + socket.on('data', function(d) { + var did = false; + var pattern = 'HTTP/1.1 200 OK\r\n'; + if ((d.length === pattern.length && d === pattern) || + (d.length > pattern.length && + d.slice(0, pattern.length) === pattern)) { + success += 1; + did = true; + } else { + pattern = 'HTTP/1.1 ' + if ((d.length === pattern.length && d === pattern) || + (d.length > pattern.length && + d.slice(0, pattern.length) === pattern)) { + failure += 1; + did = true; + } + } + size = (size * mult + add) % mod; + if (did) { + count += 1; + if (count === num) { + bench.end(count); + } else { + WriteHTTPHeaders(socket, 1, min + size); + } + } + }); + socket.on('close', function() { + console.log('Connection closed'); + }); + + socket.on('error', function() { + console.log('Connection error'); + }); + }); +} diff --git a/benchmark/net/http_server_for_chunky_client.js b/benchmark/net/http_server_for_chunky_client.js new file mode 100644 index 00000000000000..d4aa41b221f32e --- /dev/null +++ b/benchmark/net/http_server_for_chunky_client.js @@ -0,0 +1,45 @@ +"use strict"; +var path = require('path'); +var http = require('http'); +var fs = require('fs'); +var spawn = require('child_process').spawn; +var common = require('../common.js') +var test = require('../../test/common.js') +var pep = path.dirname(process.argv[1])+'/chunky_http_client.js'; +var PIPE = test.PIPE; + +var server; + +fs.unlinkSync(PIPE); +server = http.createServer(function(req, res) { + res.writeHead(200, { 'content-type': 'text/plain', + 'content-length': '2' }); + res.end('ok'); +}); + +server.on('error', function(err) { + console.log("Error:"); + console.log(err); +}); + +try { + server.listen(PIPE, 'localhost'); +} catch(e) { + console.log("oops!"); + console.log(e); +} + +var child = spawn(process.execPath, [pep], { }); +child.on('error', function(err) { + console.log('spawn error.'); + console.log(err); +}); + +child.stdout.on('data', function (data) { + process.stdout.write(data); +}); + +child.on('exit', function (exitCode) { + console.log("Child exited with code: " + exitCode); + process.exit(0); +}); From 24d23d316044b2a0b3428c1140739a22495150d7 Mon Sep 17 00:00:00 2001 From: Rudi Cilibrasi Date: Wed, 21 Jan 2015 22:16:46 -0800 Subject: [PATCH 2/3] benchmark: few minor output improvements and exception handling --- benchmark/net/http_server_for_chunky_client.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/benchmark/net/http_server_for_chunky_client.js b/benchmark/net/http_server_for_chunky_client.js index d4aa41b221f32e..419847d3a6055e 100644 --- a/benchmark/net/http_server_for_chunky_client.js +++ b/benchmark/net/http_server_for_chunky_client.js @@ -9,8 +9,10 @@ var pep = path.dirname(process.argv[1])+'/chunky_http_client.js'; var PIPE = test.PIPE; var server; +try { + fs.unlinkSync(PIPE); +} catch (e) { /* ignore */ } -fs.unlinkSync(PIPE); server = http.createServer(function(req, res) { res.writeHead(200, { 'content-type': 'text/plain', 'content-length': '2' }); @@ -18,21 +20,21 @@ server = http.createServer(function(req, res) { }); server.on('error', function(err) { - console.log("Error:"); - console.log(err); + console.error('Error:'); + console.error(err); }); try { server.listen(PIPE, 'localhost'); } catch(e) { - console.log("oops!"); - console.log(e); + console.error('Error:'); + console.error(e); } var child = spawn(process.execPath, [pep], { }); child.on('error', function(err) { - console.log('spawn error.'); - console.log(err); + console.error('spawn error.'); + console.error(err); }); child.stdout.on('data', function (data) { @@ -40,6 +42,6 @@ child.stdout.on('data', function (data) { }); child.on('exit', function (exitCode) { - console.log("Child exited with code: " + exitCode); + console.error('Child exited with code: ' + exitCode); process.exit(0); }); From 74246a04ff48168a1c618d95f326563bad9ce075 Mon Sep 17 00:00:00 2001 From: Rudi Cilibrasi Date: Thu, 22 Jan 2015 22:08:15 -0800 Subject: [PATCH 3/3] benchmark: more formatting improvements and simplification --- benchmark/net/chunky_http_client.js | 76 +++++++++---------- .../net/http_server_for_chunky_client.js | 42 +++++----- 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/benchmark/net/chunky_http_client.js b/benchmark/net/chunky_http_client.js index 8713433ce8eb70..24e14ca2bc9b0e 100644 --- a/benchmark/net/chunky_http_client.js +++ b/benchmark/net/chunky_http_client.js @@ -1,70 +1,68 @@ -"use strict"; +'use strict'; + // test HTTP throughput in fragmented header case var common = require('../common.js'); var net = require('net'); var test = require('../../test/common.js'); var bench = common.createBenchmark(main, { -// len: [1, 4, 8, 16, 32, 64, 128], - len: [1], - num: [5, 50, 500, 2000], + len: [1, 4, 8, 16, 32, 64, 128], + num: [5, 50, 500, 2000], type: ['send'], -} -) +}); function main(conf) { - var len; - var num; - var type; - num = +conf.num; - len = +conf.len; - type = conf.type; + var len = +conf.len; + var num = +conf.num; + var type = conf.type; var todo = []; var headers = []; // Chose 7 because 9 showed "Connection error" / "Connection closed" // An odd number could result in a better length dispersion. - for (var i = 7; i <= 7*7*7; i *= 7) + for (var i = 7; i <= 7 * 7 * 7; i *= 7) headers.push(Array(i + 1).join('o')); - function WriteWithCRLF(line) { - todo.push(line + '\r\n'); - } - function WriteHTTPHeaders(channel, has_keep_alive, extra_header_count) { todo = [] - WriteWithCRLF('GET / HTTP/1.1'); - WriteWithCRLF('Host: localhost'); - WriteWithCRLF('Connection: keep-alive'); - WriteWithCRLF('Accept: text/html,application/xhtml+xml,' + - 'application/xml;q=0.9,image/webp,*/*;q=0.8'); - WriteWithCRLF('User-Agent: Mozilla/5.0 (X11; Linux x86_64) ' + - 'AppleWebKit/537.36 (KHTML, like Gecko) ' + - 'Chrome/39.0.2171.71 Safari/537.36'); - WriteWithCRLF('Accept-Encoding: gzip, deflate, sdch'); - WriteWithCRLF('Accept-Language: en-US,en;q=0.8'); + todo.push('GET / HTTP/1.1'); + todo.push('Host: localhost'); + todo.push('Connection: keep-alive'); + todo.push('Accept: text/html,application/xhtml+xml,' + + 'application/xml;q=0.9,image/webp,*/*;q=0.8'); + todo.push('User-Agent: Mozilla/5.0 (X11; Linux x86_64) ' + + 'AppleWebKit/537.36 (KHTML, like Gecko) ' + + 'Chrome/39.0.2171.71 Safari/537.36'); + todo.push('Accept-Encoding: gzip, deflate, sdch'); + todo.push('Accept-Language: en-US,en;q=0.8'); for (var i = 0; i < extra_header_count; i++) { // Utilize first three powers of a small integer for an odd cycle and // because the fourth power of some integers overloads the server. - WriteWithCRLF('X-Header-' + i + ': ' + headers[i%3]); + todo.push('X-Header-' + i + ': ' + headers[i % 3]); } - WriteWithCRLF(''); - todo = todo.join(''); + todo.push(''); + todo.push(''); + todo = todo.join('\r\n'); // Using odd numbers in many places may increase length coverage. var chunksize = 37; - for (i = 0; i < todo.length; i+=chunksize) { - var cur = todo.slice(i,i+chunksize); + for (i = 0; i < todo.length; i += chunksize) { + var cur = todo.slice(i, i + chunksize); channel.write(cur); } } - var success = 0, failure = 0, min = 10, size = 0; - var mod = 317, mult = 17, add = 11; + var success = 0; + var failure = 0; + var min = 10; + var size = 0; + var mod = 317; + var mult = 17; + var add = 11; var count = 0; var PIPE = test.PIPE; var socket = net.connect(PIPE, function() { bench.start(); - WriteHTTPHeaders(socket, 1, +conf.len); + WriteHTTPHeaders(socket, 1, len); socket.setEncoding('utf8') socket.on('data', function(d) { var did = false; @@ -93,12 +91,12 @@ function main(conf) { } } }); - socket.on('close', function() { - console.log('Connection closed'); + socket.on('close', function() { + console.log('Connection closed'); }); - socket.on('error', function() { - console.log('Connection error'); + socket.on('error', function() { + throw new Error('Connection error'); }); }); } diff --git a/benchmark/net/http_server_for_chunky_client.js b/benchmark/net/http_server_for_chunky_client.js index 419847d3a6055e..5439e7226eef39 100644 --- a/benchmark/net/http_server_for_chunky_client.js +++ b/benchmark/net/http_server_for_chunky_client.js @@ -1,11 +1,12 @@ -"use strict"; +'use strict'; + var path = require('path'); var http = require('http'); var fs = require('fs'); var spawn = require('child_process').spawn; var common = require('../common.js') var test = require('../../test/common.js') -var pep = path.dirname(process.argv[1])+'/chunky_http_client.js'; +var pep = path.dirname(process.argv[1]) + '/chunky_http_client.js'; var PIPE = test.PIPE; var server; @@ -20,28 +21,27 @@ server = http.createServer(function(req, res) { }); server.on('error', function(err) { - console.error('Error:'); - console.error(err); + throw new Error('server error: ' + err); }); try { - server.listen(PIPE, 'localhost'); -} catch(e) { - console.error('Error:'); - console.error(e); -} + var child; -var child = spawn(process.execPath, [pep], { }); -child.on('error', function(err) { - console.error('spawn error.'); - console.error(err); -}); + server.listen(PIPE); -child.stdout.on('data', function (data) { - process.stdout.write(data); -}); + child = spawn(process.execPath, [pep], { }); + + child.on('error', function(err) { + throw new Error('spawn error: ' + err ); + }); + + child.stdout.pipe(process.stdout); + + child.on('exit', function (exitCode) { + console.error('Child exited with code: ' + exitCode); + }); + +} catch(e) { + throw new Error('error: ' + e ); +} -child.on('exit', function (exitCode) { - console.error('Child exited with code: ' + exitCode); - process.exit(0); -});