mirror of
https://github.com/nodejs/node.git
synced 2024-11-30 07:27:22 +01:00
3e1b1dd4a9
The copyright and license notice is already in the LICENSE file. There is no justifiable reason to also require that it be included in every file, since the individual files are not individually distributed except as part of the entire package.
107 lines
2.4 KiB
JavaScript
107 lines
2.4 KiB
JavaScript
var spawn = require('child_process').spawn;
|
|
var cluster = require('cluster');
|
|
var http = require('http');
|
|
|
|
var options = {
|
|
mode: 'master',
|
|
host: '127.0.0.1',
|
|
port: 22344,
|
|
path: '/',
|
|
servers: 1,
|
|
clients: 1
|
|
};
|
|
|
|
for (var i = 2; i < process.argv.length; ++i) {
|
|
var args = process.argv[i].split('=', 2);
|
|
var key = args[0];
|
|
var val = args[1];
|
|
options[key] = val;
|
|
}
|
|
|
|
switch (options.mode) {
|
|
case 'master': startMaster(); break;
|
|
case 'server': startServer(); break;
|
|
case 'client': startClient(); break;
|
|
default: throw new Error('Bad mode: ' + options.mode);
|
|
}
|
|
|
|
process.title = 'http_bench[' + options.mode + ']';
|
|
|
|
// monkey-patch the log functions so they include name + pid
|
|
console.log = patch(console.log);
|
|
console.trace = patch(console.trace);
|
|
console.error = patch(console.error);
|
|
|
|
function patch(fun) {
|
|
var prefix = process.title + '[' + process.pid + '] ';
|
|
return function() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
args[0] = prefix + args[0];
|
|
return fun.apply(console, args);
|
|
};
|
|
}
|
|
|
|
function startMaster() {
|
|
if (!cluster.isMaster) return startServer();
|
|
|
|
for (var i = ~~options.servers; i > 0; --i) cluster.fork();
|
|
|
|
for (var i = ~~options.clients; i > 0; --i) {
|
|
var cp = spawn(process.execPath, [__filename, 'mode=client']);
|
|
cp.stdout.pipe(process.stdout);
|
|
cp.stderr.pipe(process.stderr);
|
|
}
|
|
}
|
|
|
|
function startServer() {
|
|
http.createServer(onRequest).listen(options.port, options.host);
|
|
|
|
var body = Array(1024).join('x');
|
|
var headers = {'Content-Length': '' + body.length};
|
|
|
|
function onRequest(req, res) {
|
|
req.on('error', onError);
|
|
res.on('error', onError);
|
|
res.writeHead(200, headers);
|
|
res.end(body);
|
|
}
|
|
|
|
function onError(err) {
|
|
console.error(err.stack);
|
|
}
|
|
}
|
|
|
|
function startClient() {
|
|
// send off a bunch of concurrent requests
|
|
// TODO make configurable
|
|
sendRequest();
|
|
sendRequest();
|
|
|
|
function sendRequest() {
|
|
var req = http.request(options, onConnection);
|
|
req.on('error', onError);
|
|
req.end();
|
|
}
|
|
|
|
// add a little back-off to prevent EADDRNOTAVAIL errors, it's pretty easy
|
|
// to exhaust the available port range
|
|
function relaxedSendRequest() {
|
|
setTimeout(sendRequest, 1);
|
|
}
|
|
|
|
function onConnection(res) {
|
|
res.on('error', onError);
|
|
res.on('data', onData);
|
|
res.on('end', relaxedSendRequest);
|
|
}
|
|
|
|
function onError(err) {
|
|
console.error(err.stack);
|
|
relaxedSendRequest();
|
|
}
|
|
|
|
function onData(data) {
|
|
// this space intentionally left blank
|
|
}
|
|
}
|