I have working (stock) script from node
var cluster = require('cluster');
var http = require('http');
var numReqs = 0;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < 2; i++) {
var worker = cluster.fork();
worker.on('message', function(msg) {
if (msg.cmd && msg.cmd == 'notifyRequest') {
numReqs++;
}
});
}
setInterval(function() {
console.log("numReqs =", numReqs);
}, 1000);
} else {
// Worker processes have a http server.
http.Server(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
// Send message to master process
process.send({ cmd: 'notifyRequest' });
}).listen(8000);
}
In the above script I can send data from worker to master process with ease. But how to send data from master to the worker/workers? With examples, if it possible.
Because cluster.fork is implemented on top of child_process.fork, you can send messages from a master to the worker by using worker.send({ msg: 'test' })
, and from a worker to a master by process.send({ msg: 'test' });
. You receive the messages like so: worker.on('message', callback)
(from worker to master) and process.on('message', callback);
(from master to worker).
Here's my full example, you can test it by browsing http://localhost:8000/ Then the worker will send a message to the master and the master will reply:
var cluster = require('cluster');
var http = require('http');
var numReqs = 0;
var worker;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < 2; i++) {
worker = cluster.fork();
worker.on('message', function(msg) {
// we only want to intercept messages that have a chat property
if (msg.chat) {
console.log('Worker to master: ', msg.chat);
worker.send({ chat: 'Ok worker, Master got the message! Over and out!' });
}
});
}
} else {
process.on('message', function(msg) {
// we only want to intercept messages that have a chat property
if (msg.chat) {
console.log('Master to worker: ', msg.chat);
}
});
// Worker processes have a http server.
http.Server(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
// Send message to master process
process.send({ chat: 'Hey master, I got a new request!' });
}).listen(8000);
}
I found this thread while looking for a way to send a message to all child processes and was thankfully able to figure it out thanks to the comments about arrays. Just wanted to illustrate a potential solution for sending a message to all child processes utilizing this approach.
var cluster = require('cluster');
var http = require('http');
var numReqs = 0;
var workers = [];
if (cluster.isMaster) {
// Broadcast a message to all workers
var broadcast = function() {
for (var i in workers) {
var worker = workers[i];
worker.send({ cmd: 'broadcast', numReqs: numReqs });
}
}
// Fork workers.
for (var i = 0; i < 2; i++) {
var worker = cluster.fork();
worker.on('message', function(msg) {
if (msg.cmd) {
switch (msg.cmd) {
case 'notifyRequest':
numReqs++;
break;
case 'broadcast':
broadcast();
break;
}
});
// Add the worker to an array of known workers
workers.push(worker);
}
setInterval(function() {
console.log("numReqs =", numReqs);
}, 1000);
} else {
// React to messages received from master
process.on('message', function(msg) {
switch(msg.cmd) {
case 'broadcast':
if (msg.numReqs) console.log('Number of requests: ' + msg.numReqs);
break;
}
});
// Worker processes have a http server.
http.Server(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
// Send message to master process
process.send({ cmd: 'notifyRequest' });
process.send({ cmd: 'broadcast' });
}).listen(8000);
}