mykeels.com

Handling blocking operations in Node

Node Tips and Tricks for faster APIs (2)

Handling blocking operations in Node

Node Tips and Tricks for faster APIs (2)

In the previous part of this article series, we discussed using clusters to scale out your Node APIs, taking advantages of multiple processor cores on a single machine.

Alternate title: using concrete.js to build secure applications

While a cluster fork (hehe) makes a clone of the current process, a child process is a separate process that is started by a Node process.

As long as a program can be executed directly, it can be run as a child process within a parent Node process.

A parent process can listen to events emitted by the child like stdout, stdin, and stderror among others. It can also supply standard input to the child, to control its execution flow.

Example

Let’s take a quick example showing a Node program invoking the ls unix program which lists all the files and folders within the current working directory.

  • Open a terminal (unix)

  • Type node and press ENTER to begin the Node REPL

  • Copy and paste the following script

Using Child Processes for complex tasks

But what do all these have to do with building faster and more efficient Node apps?

What if we could shift our computation of prime numbers to a child process, so our main process is free to handle other requests?

Would this improve our API performance?

To manage our child-processes, we will make use of the node-worker-farm package.

So, create a new branch from our repo called child-process and run

npm i -s node-worker-farm

in the terminal.

Located here.

We define the function that generates the prime numbers in a separate file called worker.js.

  • It takes a max argument which determines the upper limit of the prime numbers our API responds with.

  • It also accepts a callback function with an error as its first parameter, and the result array as its second. We use a try-catch statement to handle errors.

At each request, we spin up a child-process to handle the computation while our main thread (event loop) is free to respond to other requests.

Here are our results …

Benchmark Test result of API (with child processes)

Let’s compare with our results from the previous article.

          (no-clusters) vs  (clusters) vs (child-process)
- min:    13ms          vs  13.5ms     vs 17.7ms
- max:    1443.1ms      vs  1606.5ms   vs 521.6ms
- median: 610.3ms       vs  290.7ms    vs 331.9ms
- p95:    683.7ms       vs  560.6ms    vs 403.3ms
- p99:    1256.4ms      vs  719.5ms    vs 434.5ms

Whoop! Whoop! 🎉🍾🥂

Using child-processes with a single parent process outperforms single-process and clusters modes in our simple prime numbers API.

However, it is worth mentioning that real world applications are hardly ever this simple. Throwing child-processing at a bottleneck may not solve the problem as easily as one would think.

You should leverage child processes when your bottleneck exists because of computation intensity that is guaranteed to block the event loop.

In the next and final article in this series, we will be considering two more ways to improve your API performance.

https://medium.com/@mykeels/interrupts-and-request-memoization-23cfe925b0ec

Related Articles

Tags