node.jsnode-cluster

Unable to get all workers in worker block while using cluster in NodeJS


I need to get all workers id list in worker block. Here is my example which is not working

const cluster = require('cluster');
var a = [];
if (cluster.isMaster) {
  console.log('I am master');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  a.push(cluster.worker.id);
  console.log(`I am worker #${cluster.worker.id}`);
  console.log(a);
}

Output:

I am master
I am worker #1
[ 1 ]
I am worker #2
[ 2 ]

While expected output

I am master
I am worker #1
[ 1 ]
I am worker #2
[ 1, 2 ]

Solution

  • That because your code is executed three times from the very beginning, so every variable is unique for each worker. Think it about like 3 different application are being run, they don't share variable with eachother.

    The variable a on worker 1 is a different variable from a in worker 2.

    If you want to share info you can either use a DB, persistent storage, or try to create a communication channel between the master and the slaves.

    Here's an example to communicate between master, and slaves:

    const cluster = require('cluster');
    var a = [];
    
    function onNewWorker(workers) {
        a = workers;
        console.log(`I am worker #${cluster.worker.id}, all workers = ${a}`);
    }
    
    if (cluster.isMaster) {
        cluster.on("fork", (worker) => {
            a.push(worker);
            a.forEach(w => w.send(a.map(wr => wr.id)));
        });
        console.log('I am master');
        const proc1 = cluster.fork();
        const proc2 = cluster.fork();
    } else if (cluster.isWorker) {
        a.push(cluster.worker.id);
        process.on("message", onNewWorker);
        console.log(`I am worker #${cluster.worker.id}`);
        console.log(a);
    }
    

    Output

    I am master
    I am worker #1
    I am worker #2
    [ 1 ]
    [ 2 ]
    I am worker #1, all workers = 1
    I am worker #1, all workers = 1,2
    I am worker #2, all workers = 1,2
    

    Of course you can improve this code, it's just for example.