TiMoch
TiMoch

Reputation: 1058

NodeJS process.send stops working

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

Answers (1)

alessioalex
alessioalex

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

Related Questions