user8997599
user8997599

Reputation:

Express.js with Node.js, multiple clients

I have not found an good answer on Google, so I try here.

My application consists of: Express.js, node.js and a MySQL database. However, this application needs to serve multiple clients.

In my code I need to use callbacks so that the program waits for the db query to be done before moving on. Will this affect the others users that wants to access the db simultaneously?

Upvotes: 2

Views: 1719

Answers (1)

AlexanderGriffin
AlexanderGriffin

Reputation: 515

To explicitly answer this question, I think some deeper understanding of the Node.js async event loop is required.

JavaScript is single threaded, and using this async event loop allows Node.js to perform non-blocking I/O operations on this single thread.

The way it achieves this is by offloading operations to the kernel when it needs to (such as when there are a lot of requests or I/O operations), and then picking the result back up at a later time in the event loop, in the 'poll' phase.

To give some further clarification, I've included the diagram presented in the Node.js documentation:

   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

These phases can be read about in much more detail at: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

In short summary:

  • timers: scheduled callbacks and anything set on timers will execute here, such as setInterval() or setTimeout(). The reason that this is first, is these are simply a guarantee that the amount of time specified is the minimum amount of time it can take for these to fire. This time is padded by the time for event loop cycles to complete as well. Having them here is the way to keep them most accurate to what the developer has specified within the interval or timeout functions.
  • pending callbacks: executes I/O callbacks deferred to the next loop iteration. If the maximum callback number is reached in any event loop, the rest of the callbacks that need to be executed are deferred to the next loop ( which can be achieved manually though process.nextTick() ), so - after timers, these should execute next
  • idle: only used internally. If there is nothing left in the event loop to process, the loop will stop deferring anything to the kernel until necessary
  • prepare: only used internally. Prepares for the next event loop cycle if one or more will be required
  • poll: retrieve new I/O events; execute I/O related callbacks (almost all with the exception of close callbacks, the ones scheduled by timers, and setImmediate()); node will block here when appropriate. This poll phase is what allows anything that was deferred to continue.
  • check: setImmediate() callbacks are invoked here
  • close callbacks: some close callbacks, e.g. socket.on('close', ...), and other 'close' events are called here

Again, most of this is from the Node.js documentation but I have elaborated a bit on some of the details to provide a bit of understanding in this context.

In your case, your database operations would not 'block' other users, they would just have to wait until their callbacks were processed through the loop. If there were many operations at the same time, more would be offloaded to the kernel and then picked back up as soon as possible which may provide some slight additional delay (1).

Another good graphic that will help to visualize this process comes from this article: https://webapplog.com/you-dont-know-node/

Node Async Event Loop Graphic

On a side note -

There are places where Node.js' event loop is a good solution, and other places where a more robust multi threaded solution might be a better approach. Making sure you do the research required to intelligently make this decision related to the specifics of your project is never a bad idea.

(1) There are several articles out there that are just a google search away about performance differences, expected delay with heavy network loads, and various solutions to this concern.

I hope this helps!

Upvotes: 8

Related Questions