3

I was reading about clusters in Node js i came across with a simple example, whereas the main file creates four childs processes and each of them listens to 8080 port.

The code runs well but i dont get:

How its possible to have multiple child processes to listen to the same port?

I was expecting to get a message like

Error: listen EADDRINUSE: address already in use :::8080

const cluster = require("cluster");

if (cluster.isMaster) {
  for (let i = 0; i <= 4; i++) cluster.fork();
} else {
  require("./test.js");
}

test.js

const http1 = require("http");
http1
  .createServer((req, res) => {
    console.log("request1");
    res.write("hello1");
    res.end();
  })
  .listen(8080, () => {
    console.log("begin");
  });
George Paouris
  • 525
  • 4
  • 16

2 Answers2

12

I wondered this myself awhile ago and went digging.

The child processes aren't listening to the same port. Incoming socket connections to the master process are being delegated to the child processes.

What's actually going on is deceiving here because you certainly see the server.listen() in each child process. But, inside of .listen() is some magic that knows about the fact that this process is meant to be a clustered process so instead of actually listening in the traditional sense (which would indeed cause the error you cite), they are listening for delegated sockets from their parent.

If I were designing this, I probably wouldn't have hidden this functionality inside of .listen() and caused this confusion. I would have provided a different method to be used in this circumstance that carried this special behavior.

If you want to see more about it here are some resources:

Source code for server.listen() where you can see that it calls listenInCluster() in some circumstances.

In the Net doc for server.listen(), there are references to the special handling when clustered.

The listenInCluster() source code itself where the deed is carried out here:

  // Get the master's server handle, and listen on it
  cluster._getServer(server, serverQuery, listenOnMasterHandle);
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • It seems that clustering was a big feature in the original design but was not used as much as originally intended. That's just my assumption of course ... – Mike M Aug 12 '22 at 11:00
  • @MikeM - Before nodejs had WorkerThreads, clustering or just running specialized code in a child process was needed to be able to run CPU-heavy code and not interfere with prompt event loop processing in the main thread. And, of course clustering of some kind is a classic ingredient in scaling a server beyond what one process can handle. But, I think you're right that many applications don't need to use it. – jfriend00 Aug 12 '22 at 15:05
0

child process share the parents fd, so they ended up on listening on same port. this answer might clear the confusion

Moazzam Arif
  • 298
  • 1
  • 5