Question

I'm learning NodeJS and just wanted to clarify something. In several introductory tutorials and books so far, very early on they've described Node's "non-blocking" architecture - or rather that it's possible (and recommended, the entire point) to code in a non-blocking manner.

So for example, this example was given in a book I'm reading of an asynchronous way to get data from a database.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

What happens (as I understand it) is Node makes the call to the database, then continues processing whatever may be next on the call stack. When the database request is complete, the data variable in the anonymous callback function will be populated and that function added to the call stack (and subsequently executed when Node gets to it).

My question is, what exactly is processing the database request? Surely Node has to block whilst it does that? What is taking care of the database request? Or if Node is waiting on an asynchronous HTTP GET request to an external resource, what is taking care of that request that allows Node to continue processing the call stack and be "non-blocking"?

Was it helpful?

Solution

When Node.js is described as "non-blocking", that specifically means that its IO is non-blocking. Node uses libuv to handle its IO in a platform-agnostic way. On Windows, it uses IO completion ports, on Unix, it uses epoll/kqueue/select/etc. So, it makes a non-blocking IO request (which may have a background thread monitoring, but this is never exposed to JavaScript) and upon a result, it queues it within the event loop which calls the JavaScript callback on the main (read: only) JavaScript thread.

For databases, it depends on how the library is written. If it uses HTTP to communicate (as some NoSQL databases do), then it could be easily written in pure JavaScript using the standard node http library. If it does it another way, well, that's up to the library. It could be written in C/C++ and use background threads as long as that abstraction is never exposed to the JavaScript.

As for your question of what is "processing" the database request, ideally all that should be done is sending a simple message to a library (e.g. a SQL statement or some other query or a request to connect), and at that point your JavaScript keeps on chugging. When the library is ready to send a message back, it sends a message back to node's event queue which runs the callback, allowing that snippet of code to run.

Licensed under: CC-BY-SA with attribution
scroll top