-1

Imagine a simple express web app like below.

const express = require('express')                                                                                                                                                                                                                                                                                                                 

const app = express()                                                                                                                                                                                                                                                                                                                              
const port = 3000                                                                                                                                                                                                                                                                                                                                  

app.get('/', (req, res) => {
  takeTimePlain()                                                                                                                                                                                                                                                                                                          
  res.send('Hello World!')                                                                                                                                                                                                                                                                                                                         
})  

app.listen(port, () => {                                                                                                                                                                                                                                                                                                                           
  console.log(`Example app listening at http://localhost:${port}`)                                                                                                                                                                                                                                                                                 
})  

function takeTimePlain () {                                                                                                                                                                                                                                                                                                                     
  /* Long Job Operation Simulation */                                                                                                                                                                                                                                                                                                              

  let date = Date.now();                                                                                                                                                                                                                                                                                                                           
  let end = Date.now() + 5000;                                                                                                                                                                                                                                                                                                                     

  while (date < end ) {                                                                                                                                                                                                                                                                                                                            
    console.log ("Iterating through while loop")                                                                                                                                                                                                                                                                                                   
    date = Date.now()                                                                                                                                                                                                                                                                                                                              
  }                                                                                                                                                                                                                                                                                                                                                
  return                                                                                                                                                                                                                                                                                                                                           
} 

Then I'm calling http://localhost:3000 3 times concurrently. If I inspect the latency or some call it server waiting time,

  • If latency for the first request is x
  • then for the second request it takes 2x time
  • and for the third request it takes 3x time to get completed

If we assume 10 client's connect to endpoint at the same time, then the 10th client should wait 10x time to get a response. Imaging a few thousand requests per second.

Why Nodejs being praise for it's scalability, event driven and single threaded nature even it can't handle common scenario like above without help of out side solutions like running multiple instances of the same service?

Is there any non-blocking alternative to takeTimePlain() ? I'm aware about setTimeout(cb, 5000), However my intention here isn't about waiting 5 seconds. This takeTimePlain() can be anything like sorting through and array, ordering, find, etc. Its a common coding solution to replicate a process which takes cpu time.

Edit: This question isn't about skepticism or suggestions. This is about clarifying facts after showing actual benchmarks. Feel free to edit the title if it doesn't fit the content.

inckka
  • 345
  • 7
  • 21
  • Yes, your benchmark is correct. if you block execution for 3 seconds it will be blocked for 3 seconds. – adrianj98 May 02 '20 at 15:39
  • @adrianj98 It is. However the argument is, when making a common programmatic solution isn't this very common? If it is... then check the OP title again. – inckka May 03 '20 at 03:20

1 Answers1

1

There are a few parts to this answer.

First node is not multithreaded, by nature it does all its work asynchronous. The reason callbacks and promises are everywhere. You takeTimePlain is intentionally not asynchronous so is not very common. Your example is inherently going against the paradigm.

But if it does happen there are a few options:

A) spawn another process to run long blocking code.

B) use cluster.

Cluster will allow you to open as many node https processes as you like on the same port. https://nodejs.org/api/cluster.html There are a lot of solutions like cluster but cluster is the build it one.

For fixing takeTimePlain you could instead of a loop use setInterval with a time of 0. Then clear it once you hit the end. Though that would be very slow.

One last thing node/express is no more scalable than any other solution.

adrianj98
  • 584
  • 2
  • 9