-
-
Save bnoordhuis/1f1af0d15986c7ef7683 to your computer and use it in GitHub Desktop.
net round robin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"dependencies": ["rusage"] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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