keemahs
keemahs

Reputation: 998

nodejs in cluster mode

const express = require("express");

const app = express();

const doWork = () => {
  const start = Date.now();
  while (Date.now() - start < 5000) {}
};

app.get("/slow", (req, res) => {
  doWork();
  res.send("slow");
});

app.get("/fast", (req, res) => {
  res.send("fast");
});

app.listen(3000);
  1. if i first go to /slow in one tab after that just immediately /fast in another, both take about 5 seconds
  2. if i first go to /slow in one tab after that just immediately /slow in another 1st takes about 5 seconds, 2nd about 10

this is as node is single threaded

now i try the same behavior with the following -

const express = require("express");
const cluster = require("cluster");

if (cluster.isMaster) {
  cluster.fork();
  cluster.fork();
  cluster.fork();
  cluster.fork();
} else {
  const app = express();

  const doWork = () => {
    const start = Date.now();
    while (Date.now() - start < 5000) {}
  };

  app.get("/slow", (req, res) => {
    doWork();
    res.send("slow");
  });

  app.get("/fast", (req, res) => {
    res.send("fast");
  });

  app.listen(3000);
}
  1. if i first go to /slow in one tab after that just immediately /fast in another, 1st takes 5 seconds, 2nd happens immediately
  2. if i first go to /slow in one tab after that just immediately /slow in another 1st takes about 5 seconds, 2nd about 10 (why is this happening)

the above also happens when i try to use pm2 i mean running the first code of the question using pm2

Upvotes: 1

Views: 224

Answers (1)

coagmano
coagmano

Reputation: 5671

I added some more logging:

app.get("/slow", (req, res) => {
    console.log(`${process.pid} GET /slow start`)
    doWork();
    res.send("slow");
    console.log(`${process.pid} GET /slow end`)
  });

and it looks like the same worker is getting all the /slow requests terminal showing all requests to /slow have the same process ID But didn't block /fast for me

So I tried in firefox, and there the first 4 /slow requests were all sent to different workers.

Looking at the connection headers, node is sending the Connection: keep-alive header, so I think that Chrome is trying to re-use the one connection between tabs, which is leading to requests being queued.

You can confirm this by inspecting the Connection ID in chrome's devtools (with "Disable cache" turned off). All the IDs are the same between /slow tabs

This means you might be able to get more concurrency by disabling keep-alive. But since connections will only be re-used by the same user, it might not be a huge issue

Upvotes: 1

Related Questions