DEV Community

loading...
Cover image for Utilizing machine capability in NodeJS using the cluster module 1

Utilizing machine capability in NodeJS using the cluster module 1

ajahso4 profile image Ajah Chukwuemeka ・3 min read

Humans naturally want to live to their full potential. We always believe that we have untapped potential welled within us with the conviction that our genes and nurturing has equipped us enough to be able to live above subpar lives. In building apps with NodeJS, the machines we utilize have different capabilities bearing in mind the number of cores possessed by the machine as well as the power of individual cores.

A single instance of NodeJS doesn't utilize all the machine capabilities since it is single-threaded and you can't afford to let your app suffer from overload when it has dormant server resources that can be utilized to bear the weight of client-server communication. In light of this, NodeJS makes provision for the the cluster module which helps fork multiple processes of a NodeJS app. For a web server, the cluster module helps spun multiple child processes that share a port with their parent process. Ehhh, not like a port can be shared by web servers. Technically, the parent module receives requests and efficiently distributes it to the client processes (just like the great Xavi and Iniesta did for Messi in their heydays). The cluster module is particularly useful for networking applications but it can still shine in other processes where we want to carryout CPU-intensive tasks across multiple workers.

According to the NodeJS official documentation, the child processes (worker processes) are spawned using the child_process.fork() method, so that they can communicate with the parent via IPC (Inter-Process Communication) and pass server handles back and forth.

In distributing incoming connections to the child processes, there are two methods adopted by the cluster module and they are platform related. The first one (and default on all platforms except Windows), is the round-robin approach (turn-based allocation without priority), where the master process listens on a port, accepts new connections and distributes them across the workers in a round-robin fashion, with some built-in smarts to avoid overloading a worker process. The second approach is where the master process creates the listen socket and sends it to interested workers. The workers then accept incoming connections directly.

The workers are all separate processes implying that they can be killed or re-spawned depending on program needs without affecting other workers. As long as there are still hale and hearty workers, the master process would still be accepting connections. NodeJS doesn't bear the responsibility of managing the number of available workers and so, it is the application's responsibility to manage the worker pool based on its own needs.

Now, lets dive into a use case of the cluster module. Remember we said the cluster module shines bright in networking applications? We would use a networking application for our example. We would prop up an http server and distribute requests across child processes based on the number of CPU cores our operating machine has.

const cluster = require('cluster');
const http = require('http');
const number_of_cpus = require('os').cpus().length;

if(cluster.isMaster){
    console.log(`Master with id ${process.pid} is running`);

    // setting up the workers
    for (let i = 0; i < number_of_cpus; i++){
        cluster.fork();
    }

    cluster.on('exit',(worker, code, signal) => {
        console.log(` Worker with process id ${worker.process.pid} died`);
    });
}
else{
    http.createServer((req,res) => {
        res.writeHead(200);
        res.end(`Hello world from ${process.pid}`)
    }).listen(80);
    console.log(`Worker with ${process.pid} started`)

}

Since NodeJS is event-driven, both the master process and the worker processes listen for events and act accordingly (that's if there is provision for handling the events in the code.) We would talk about the events, methods and properties on both sides (worker and master) associated with the cluster module in the follow-up article on this topic. Thanks for your time.

Discussion

pic
Editor guide
Collapse
anduser96 profile image
Andrei Gatej

Great article. Thanks!
Keep up the good work!