Node.js Cluster not forking anything - node.js

I am trying to implement clustering in my Node.js application.
When I print out how many workers are spawned inside the for-loop with the fork() method, it prints out nothing.
The coreCounter variable also = 0 if I print it out.
Here is my code:
let cluster = require('cluster');
if (cluster.isMaster) {
let coreCounter = require('os').cpus.length;
for (let i = 0; i < coreCounter; i++) {
cluster.fork();
}
cluster.on('exit', function () {
cluster.fork();
});
} else {
require('server.js');
}
I tried to npm install cluster and npm install os, it did not work, do I have to do npm install if I "require" something?

You just need to add () after the cpus.
See here:
let cluster = require('cluster');
if (cluster.isMaster) {
let coreCounter = require('os').cpus().length;
for (let i = 0; i < coreCounter; i++) {
cluster.fork();
}
cluster.on('exit', function () {
cluster.fork();
});
} else {
//require('server.js');
console.log('walla!')
}
You should not npm install NodeJS core modules.
P.S. I suggest you get some practice with NodeJS before implement clustering

Related

Nodejs cluster unable to kill worker running infinite loop

It is possible to kill a cluster worker that is running an infinite loop? I've tried, but unable to kill the worker. I guess the kill command cannot get onto the worker's js event loop. Any ideas on how else I can do this? When the master receives a "start" message, I want it to fork a worker. When the master receives a "stop" message, I want it to kill the worker.
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
const process = require('process');
const { nrpin, nrpout } = require("./helpers/PubSub");
const chalk = require('chalk');
//https://leanpub.com/thenodejsclustermodule/read
//https://gist.github.com/jpoehls/2232358
const arrWorkers = [];
if (cluster.isMaster) {
masterProcess();
} else {
childProcess();
}
function masterProcess() {
console.log(chalk.blueBright(`Master ${process.pid} is running`));
nrpin.on("start", async (bot) => {
console.log("Start:", bot._id);
if (arrWorkers.length == numCPUs){
console.log(chalk.yellowBright("No CPUs available to create worker!"));
}
const worker = cluster.fork();
arrWorkers.push({
workerId: worker.id,
botId: bot._id
})
})
nrpin.on("stop", async (bot) => {
console.log("Stop:", bot._id);
const worker = arrWorkers.find(x => x.botId == bot._id);
if (worker){
console.log("killing worker:", worker.workerId);
cluster.workers[worker.workerId].kill();
}
})
// Be notified when workers die
cluster.on('exit', function(worker, code, signal) {
if (worker.isDead()) {
console.info(`${chalk.redBright('worker dead pid')}: ${worker.process.pid}`);
}
});
}
function childProcess() {
console.log(chalk.green(`Worker ${process.pid} started...`));
while(true){
console.log(Date.now());
}
}
Never mind, I solved this using process.kill
let process_id = cluster.workers[worker.workerId].process.pid;
process.kill(process_id);

NodeJS Cluster how share object array across workers

So I have setup a simple nodejs cluster game, I am new to nodejs. basically players connect to to my worker using socket.io then they get created to a Player Object then added to my PlayerManager.LIST array. Now this causes me some issues as the PlayerManager.LIST is on each of workers and are not sync'd.
So my question is, is there a better way of doing this so that if I connect to worker 2 I see same player list as worker 1's.
Structure at the moment:
app.js
-> worker
->-> PlayerManager (Contains List)
->->-> Player
Git Repo: https://github.com/mrhid6/game_app_v2
NodeJS Clusters are based on Nodejs Child Processes. In child processes you can send data between parent (Master in cluster) and child (worker in cluster) via messages over IPC channel. You can do the same with clusters using message events
var cluster = require('cluster');
var _ = require('lodash');
var http = require('http');
var workers = [];
var workerCount = 4;
if (cluster.isMaster) {
for (var i = 0; i < workerCount; i++) {
var worker = cluster.fork();
worker.on('message', function(msg) {
if (msg.task === 'sync') {
syncPlayerList(msg.data);
}
});
}
workers.push[worker];
} else {
var worker = new Worker();
process.on('message', function(msg) {
if (msg.task === 'sync') {
worker.playerList = msg.data;
}
});
}
function syncPlayerList (playerList) {
_.forEach(workers, function (worker) {
worker.send({
task: 'sync',
data: playerList
});
});
};
// worker class
function Worker() {
this.playerList = [];
}
Worker.prototype.sendSyncEvent = function () {
process.send({
task: 'sync',
data: this.playerList
})
};

Prevent multiple console logging output while clustering

I'm using the cluster module for nodejs.
Here is how I have it set up:
var cluster = require('cluster');
if (cluster.isMaster) {
var numCPUs = require('os').cpus().length;
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
}else{
console.log("Turkey Test");
}
Now, I am forking 6 threads (6 cores) on my PC. So, when debugging my app and reading data from the console, this will appear:
Is there anyway to make console.log output only once regardless of how many clusters are running?
You could use the fact that you can communicate with the workers, and send a message that tells each worker if it should log or not. You'd send it so that only one worker (The first one for example) should log:
var cluster = require('cluster');
if (cluster.isMaster) {
var numCPUs = require('os').cpus().length;
for (var i = 0; i < numCPUs; i++) {
cluster.fork().send({doLog: i == 0});
}
}else{
process.on('message', function(msg) {
if(msg.doLog) {
console.log('Turkey Test');
}
});
}

Cluster in nodejs

I have tried the below piece of code in ubuntu
var cluster = exports.cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died. Trying to respawn...');
cluster.fork();
});
} else {
//spawn express etc
}
How can I check the CPU performance in ubuntu with or without using cluster in nodejs.
Any help on this will be really helpful

node.js fork function and passing arguments to child-process

I pass arguments when create chlid-processes
if (cluster.isMaster) {
for (var i = 0; i < os.cpus().length; i++) {
var new_worker_env = {};
new_worker_env["WORKER_NAME"] = "worker" + i;
var new_worker = cluster.fork(new_worker_env);
}
}
and then try to read it in childs:
if ( process.env["WORKER_NAME"] != undefined ) instance.name = process.env["WORKER_NAME"];
but this var isn't exist, why?
Node v0.8.8
Seems to work for me on Windows, Node.js version 0.8.8
var cluster = require('cluster'),
os = require('os');
if (cluster.isMaster) {
for (var i = 0; i < os.cpus().length; i++) {
var new_worker_env = {};
new_worker_env["WORKER_NAME"] = "worker" + i;
var new_worker = cluster.fork(new_worker_env);
}
} else {
console.log(process.env['WORKER_NAME']);
}
outputs:
worker0
worker1

Resources