Search code examples
node.jsblockingnonblocking

blocking code in non-blocking http server


For example, I have a http server, which is node.js, so is non-blocking.

For each request will do a DB operation.

what I cannot understand is that what is the difference between a blocking DB operation and a non-blocking DB operation?

Since the web server is non-blocking, so a blocking DB operation inside the request makes no difference?


Solution

  • Here's an analogy that might help you understand. Let's suppose you're in sales and you have 50 phone calls to make today.

    In the blocking model, you place a call and, if the person isn't ready to talk to you, you have to sit on the line and you wait and you wait until they are ready to talk to you. When they are finally ready to talk to you, you have your conversation, you hang up and only then can you make your next call and repeat the process. So, the time your phone is busy and you are not able to make calls is the sum of all the time you were waiting for the client to be ready to talk to you plus all the time you talked.

    In the non-blocking model, you place a call and if the person is not immediately available, you leave a quick message and they call you back when they are ready to talk. You hang up from leaving the message and immediately call your next client. The total time your phone is busy is only the time to leave a quick message and then the time you talk when they call back. It doesn't actually matter to you if they call you back in one minute or three hours - it does not affect your overall efficiency at making calls. You can obviously place and complete a lot more calls with the non-blocking model because you aren't wasting a lot of time when you could be doing something else by just waiting for the client to be ready to talk.

    node.js gets its efficiency by using the non-blocking I/O model and not using threads. Implemented appropriately, this non-blocking model is more efficient than having lots of individual threads that are all waiting on their blocking requests.

    So, in node.js if you have a blocking database request, then the entire time that database request is blocking, the node.js web server cannot do anything else. It only has one thread so if that thread is busy with a blocking request that takes awhile to complete the server is basically rendered useless for a significant period of time. This would be a broken implementation of a node.js server process and there would be little point in using node.js that way.

    With a non-blocking database request, the node.js server starts processing an http request. It runs some code, then it gets to the non-blocking database request. That request is started and a callback is registered for completion, but because it's non-blocking, the database call returns immediately. The node.js server returns back to its event loop and can immediately start working on other http requests or other events for the server to process (e.g. the completion of other http requests). Then, sometime later, the database calls finishes and puts an entry in the event queue to trigger its callback. When the nodejs server gets to that event in the event queue, the callback is called and that original request now has the answer from the database server and can finish that original request. Meanwhile, all the time it was waiting for that database request to finish, it was busy processing other things - all with it's one single thread.