Skip to content

Instantly share code, notes, and snippets.

@bnoordhuis
Last active December 16, 2015 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bnoordhuis/1f1af0d15986c7ef7683 to your computer and use it in GitHub Desktop.
Save bnoordhuis/1f1af0d15986c7ef7683 to your computer and use it in GitHub Desktop.
net round robin
var cluster = require('cluster');
var assert = require('assert');
var http = require('http');
var N = 4; // # of workers
if (cluster.isWorker)
worker();
else
master();
function master() {
for (var i = 0; i < N; ++i) {
cluster.fork().on('message', onmessage);
}
var times = [];
function onmessage(msg) {
times.push(msg);
if (times.length === N) onexit();
}
function onexit() {
var total = { pid: 0, sys: 0, user: 0 };
for (var i = 0; i < times.length; ++i) {
total.sys += times[i].sys;
total.user += times[i].user;
console.log('%j', times[i]);
}
console.log('%j', total);
}
process.on('SIGUSR2', function() {
// ignore
});
}
function worker() {
var reply = 'ACK from ' + process.pid + '\n';
var headers = { 'Content-Length': '' + reply.length };
var server = http.createServer(function(req, res) {
res.writeHead(200, headers);
res.end(reply);
});
server.listen(8000);
process.on('SIGUSR2', function() {
var u = require('rusage').getrusage();
var user = u.ru_utime.sec * 1e6 + u.ru_utime.usec;
var sys = u.ru_stime.sec * 1e6 + u.ru_stime.usec;
// convert to millis
user /= 1e3;
sys /= 1e3;
process.send({ pid: process.pid, sys: sys, user: user });
process.exit();
});
}
#!/bin/sh
cd `dirname $0`
echo "BASE"
node base.js &
sleep .5
ab -k -c 100 -n 100000 http://127.0.0.1:8000/ | grep -A 3 'Requests per second'
pkill -USR2 node
sleep .5
echo "ROUND ROBIN"
node rr.js &
sleep .5
ab -k -c 100 -n 100000 http://127.0.0.1:8000/ | grep -A 3 'Requests per second'
pkill -USR2 node
{
"dependencies": ["rusage"]
}
var TCP = process.binding('tcp_wrap').TCP;
var fork = require('child_process').fork;
var assert = require('assert');
var events = require('events');
var http = require('http');
var net = require('net');
var L = require('_linklist');
var N = 4; // # of workers
if (process.argv[2] === 'worker')
worker();
else
master();
function master() {
var workers = new events.EventEmitter;
var times = [];
var n = 0;
L.init(workers);
workers.setMaxListeners(9999);
for (var i = 0; i < N; ++i) {
var worker = fork(__filename,
['worker'],
{'stdio': ['ignore','ignore','ignore','ipc']});
L.append(workers, worker);
worker.setMaxListeners(9999);
worker.once('message', function(msg) {
assert.equal(msg, 'ready');
if (++n == N) start();
});
worker.on('message', function(msg) {
if (typeof msg !== 'object') return;
times.push(msg);
if (times.length === N) onexit();
});
}
function start() {
net.createServer(onconnection).listen(8000);
var handles = {}; // Pending (i.e. not yet distributed) handles.
L.init(handles);
function onconnection(conn) {
var handle = conn._handle;
handle.readStop();
conn._handle = null;
conn.destroy();
if (L.isEmpty(workers)) return L.append(handles, handle);
var worker = L.shift(workers);
send(worker, handle);
}
function send(worker, handle) {
worker.once('message', function(msg) {
if (msg !== 'ack') return;
handle.close();
if (L.isEmpty(handles)) return L.append(workers, worker);
var handle_ = L.shift(handles);
send(worker, handle_);
});
worker.send('handle', handle);
}
}
function onexit() {
var total = { pid: 0, sys: 0, user: 0 };
for (var i = 0; i < times.length; ++i) {
total.sys += times[i].sys;
total.user += times[i].user;
console.log('%j', times[i]);
}
console.log('%j', total);
process.exit();
}
process.on('SIGUSR2', function() {
// ignore
});
}
function worker() {
var reply = 'ACK from ' + process.pid + '\n';
var headers = { 'Content-Length': '' + reply.length };
var server = http.createServer(function(req, res) {
res.writeHead(200, headers);
res.end(reply);
});
process.on('message', function(msg, handle) {
assert.equal(msg, 'handle');
var conn = new net.Socket({
'handle': handle,
'readable': true,
'writable': true,
});
assert.equal(conn.readable, true);
assert.equal(conn.writable, true);
server.emit('connection', conn);
process.send('ack');
});
process.send('ready');
process.on('SIGUSR2', function() {
var u = require('rusage').getrusage();
var user = u.ru_utime.sec * 1e6 + u.ru_utime.usec;
var sys = u.ru_stime.sec * 1e6 + u.ru_stime.usec;
// convert to millis
user /= 1e3;
sys /= 1e3;
process.send({ pid: process.pid, sys: sys, user: user });
process.exit();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment