docs: add note about default padding in crypto
[platform/upstream/nodejs.git] / benchmark / http_bench.js
1 var spawn = require('child_process').spawn;
2 var cluster = require('cluster');
3 var http = require('http');
4
5 var options = {
6   mode: 'master',
7   host: '127.0.0.1',
8   port: 22344,
9   path: '/',
10   servers: 1,
11   clients: 1
12 };
13
14 for (var i = 2; i < process.argv.length; ++i) {
15   var args = process.argv[i].split('=', 2);
16   var key = args[0];
17   var val = args[1];
18   options[key] = val;
19 }
20
21 switch (options.mode) {
22 case 'master': startMaster(); break;
23 case 'server': startServer(); break;
24 case 'client': startClient(); break;
25 default: throw new Error('Bad mode: ' + options.mode);
26 }
27
28 process.title = 'http_bench[' + options.mode + ']';
29
30 // monkey-patch the log functions so they include name + pid
31 console.log = patch(console.log);
32 console.trace = patch(console.trace);
33 console.error = patch(console.error);
34
35 function patch(fun) {
36   var prefix = process.title + '[' + process.pid + '] ';
37   return function() {
38     var args = Array.prototype.slice.call(arguments);
39     args[0] = prefix + args[0];
40     return fun.apply(console, args);
41   };
42 }
43
44 function startMaster() {
45   if (!cluster.isMaster) return startServer();
46
47   for (var i = ~~options.servers; i > 0; --i) cluster.fork();
48
49   for (var i = ~~options.clients; i > 0; --i) {
50     var cp = spawn(process.execPath, [__filename, 'mode=client']);
51     cp.stdout.pipe(process.stdout);
52     cp.stderr.pipe(process.stderr);
53   }
54 }
55
56 function startServer() {
57   http.createServer(onRequest).listen(options.port, options.host);
58
59   var body = Array(1024).join('x');
60   var headers = {'Content-Length': '' + body.length};
61
62   function onRequest(req, res) {
63     req.on('error', onError);
64     res.on('error', onError);
65     res.writeHead(200, headers);
66     res.end(body);
67   }
68
69   function onError(err) {
70     console.error(err.stack);
71   }
72 }
73
74 function startClient() {
75   // send off a bunch of concurrent requests
76   // TODO make configurable
77   sendRequest();
78   sendRequest();
79
80   function sendRequest() {
81     var req = http.request(options, onConnection);
82     req.on('error', onError);
83     req.end();
84   }
85
86   // add a little back-off to prevent EADDRNOTAVAIL errors, it's pretty easy
87   // to exhaust the available port range
88   function relaxedSendRequest() {
89     setTimeout(sendRequest, 1);
90   }
91
92   function onConnection(res) {
93     res.on('error', onError);
94     res.on('data', onData);
95     res.on('end', relaxedSendRequest);
96   }
97
98   function onError(err) {
99     console.error(err.stack);
100     relaxedSendRequest();
101   }
102
103   function onData(data) {
104     // this space intentionally left blank
105   }
106 }