Reputation: 1058
I am experimenting a bit with NodeJS. I come across an issue with the following code. After a while the messages being sent from a worker to the master in a cluster just don't appear to be processed anymore.
This is a variant of one of the cluster example on the NodeJS website.
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log("Starting cluster ...");
for (var i = 0; i < numCPUs; i++) {
var worker = cluster.fork();
worker.on('death', function(worker) {
console.log('worker ' + worker.pid + ' died. restart...');
cluster.fork();
});
worker.on('message', function(msg) {
if (msg.cmd == 'reached') {
console.log('Worker %d reached another 10000', msg.workerId);
}
});
}
} else {
console.log("Started worker %d ...", process.env.NODE_WORKER_ID);
var i = 0;
while (true) {
if (i++ % 10000 == 9999) {
process.send({ cmd: 'reached' , workerId: process.env.NODE_WORKER_ID });
console.log('haha');
}
}
}
When the code is run, the intended message "Worker 1 reached another 10000" is well printed. But after only a few seconds, it stops and only the "haha" that follows process.send is printed.
What am I doing wrong ?
I am using NodeJS 0.6.6
Upvotes: 1
Views: 3137
Reputation: 63673
Your problem is using while(true)
, which blocks the event loop. You should never-ever use such a thing (again). Instead you should use setTimeout
or process.nextTick
. Here's a corrected example that works perfectly:
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log("Starting cluster ...");
for (var i = 0; i < numCPUs; i++) {
var worker = cluster.fork();
worker.on('death', function(worker) {
console.log('worker ' + worker.pid + ' died. restart...');
cluster.fork();
});
worker.on('message', function(msg) {
if (msg.cmd == 'reached') {
console.log('Worker %d reached another 10000', msg.workerId);
}
});
}
} else {
console.log("Started worker %d ...", process.env.NODE_WORKER_ID);
function repeatable(i) {
if (i++ % 10000 == 9999) {
process.send({ cmd: 'reached' , workerId: process.env.NODE_WORKER_ID });
console.log('haha');
}
setTimeout(function() {
repeatable(i);
}, 1);
}
var i = 0;
repeatable(i);
}
Upvotes: 4