4

I am new to nodejs, currently learning it. I know nodejs is single-threaded, however I am wondering: if I use non-blocking method, for example, there are 20000 concurrent requests, and there is one request need to take a long time, other threads takes shorter time.

So once we met the longer time request, nodejs will say "hi, please pause, other request need to use", is there a default time for nodejs to detect whether this need to be paused? Correct me if I use the wrong word "puase" (because I think since it is single-thread, so it should stop computing for one request, if another request wants to be processed).

In the situation I assumed, then the longer request need lots of time that it can be processed?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
adiggo
  • 193
  • 1
  • 3
  • 10
  • If the one that takes a long time does a lot of synchronous things, yes, you'll have a problem, but if it's asynchronous, such as reading a file or writing a file, other requests will continue to be processed while waiting for the asynchronous action to complete. javascript runs in an event loop. Because of this, you should avoid using synchronous actions on a node.js application that is serving requests. – Kevin B Oct 17 '14 at 18:24
  • @KevinB yes, i understand others will be processed if i use asynchonous. But my question is that since it is single-thread, if you process other request takes shorter time, during that time the longer-time request is not processed during that time. Correct me if i am wrong. Then there are lots of shorter time request which will cause the longer time request not precessed. And need more time to finish the longer request. Is that right? – adiggo Oct 17 '14 at 18:27
  • 1
    Here's an analogy. Node.js is a King. He sits on his throne, and servants come in with requests looking for responses. The king only hears one request at a time, and only responds once at a time. However, he has many servants to do his work. Servant A comes in immediately followed by servant B. the king listens to servant A, and then sends him to get coffee. He then listens to servant B and sends him to open the window. If servant B gets back before servant A, servant B will be dismissed first, while the king is still waiting on servant A. When servant A gets back, the king will dismiss him 2. – Kevin B Oct 17 '14 at 18:31
  • Many requests can be getting processed at the same time, but only one will be received or responded to at a time. – Kevin B Oct 17 '14 at 18:32
  • @KevinB I see what you mean, the single thread is for the I/o. But not for inner processing. The analogy is great. Thanks – adiggo Oct 17 '14 at 18:36
  • 1
    Why the down votes? The fact that the OP doesn't understand how node.js work is not enough to down vote. It looks like a valid question to me. +1 – Maroshii Oct 17 '14 at 18:49
  • valid to me as well, +1 to @adiggo keep it up! – pedrommuller Oct 17 '14 at 19:40
  • 1
    See also: [What exactly is a Node.js event loop tick](http://stackoverflow.com/a/19823583/201952) – josh3736 Oct 17 '14 at 20:38

1 Answers1

9

It is true that node.js can only receive or respond to a single request at a time, however, it can process multiple requests at the same time.

For example, lets say you have a node.js application that is a rest api, and every request results in a call to the database except for endpoint C. The rest api has 3 endpoints.

Endpoint A: takes 3 seconds to talk to the database

Endpoint B: takes 2 seconds to talk to the database

Endpoint C: does not talk to the database, it just returns static text.

It isn't possible for more than 1 request to happen at the same time. One is always first, regardless of how close the timestamps are.

Now, lets say we have 10 requests happening at the same time, in this order:

ABCBCCAABC

Here's how they will be received and responded to:

REC:A
REC:B
REC:C
RESP:C
REC:B
REC:C
RESP:C
REC:C
RESP:C
REC:A
REC:A
REC:B
REC:C
RESP:C
// 2 seconds later
RESP:B
RESP:B
RESP:B
// 1 second later
RESP:A
RESP:A
RESP:A

C always happens immediately because it doesn't do any asynchronous actions. You then receive all of B, and then all of A because B is faster than A.

The order of B and A may differ though based on database setup, for example, if it's set to only handle x queries at a time.

If we introduced and endpoint D that performs a synchronous action that takes 6 seconds, you'll get this result:

ADABC

REQ:A
REQ:D
// 6 long seconds later...
RESP:D
REQ:A
REQ:B
REQ:C
RESP:C
// 2 seconds later...
RESP:B
// 1 second later...
RESP:A
RESP:A

because D stops all javascript processing while it's synchronous action takes place. 1 endpoint that performs a synchronous action is an easy point of failure for someone to bring your api to a halt.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • Great. I see. But I have a question. What's the advantage over other language's "use a new thread once a new request comes in" I see the difference is in I/O part. But what's the advantage – adiggo Oct 17 '14 at 20:42
  • That i don't think i can really answer, and i doubt it's a "cut and dry" answer anyway, as each method has it's own advantages/disadvantages. – Kevin B Oct 17 '14 at 20:44
  • yes, you are right. But i see lots of people say it will avoid race condition. avoid spending time on deadlocks. But still i think there might be race conditions inside, since inner processing for each request is still concurrent. – adiggo Oct 17 '14 at 20:51
  • there certainly can be race conditions if you don't code properly. From what little experience i have with node.js apis compared to, say, coldfusion, node.js apis are far more verbose, i have to actually code a lot more of the pieces to make it all work (of course, there's modules that do this for you too such as express and loopback.) – Kevin B Oct 17 '14 at 20:55
  • 1
    Also keep in mind that just because node.js is single-threaded doesn't mean you can't use multiple threads for a single app. For example, i run my api in a cluster of 4, one per cpu. The requests get split among the 4 apps automatically, and since i'm using a db table for session management, all 4 can access session data. If your database is on a separate server, you can then easily add more servers (behind a loadbalancer) running more clusters without changing anything. – Kevin B Oct 17 '14 at 20:59
  • @KevinB wow, yes, that's right. I just started learning nodejs , it is really verbose compare to others. Also you example of different clusters is a good example. – adiggo Oct 17 '14 at 21:07