Vijay Singh Kholiya
Vijay Singh Kholiya

Reputation: 413

How to handle multiple requests for CPU intensive tasks in NodeJS?

In my NodeJS, there is a huge processing task that comprises downloading the audio files from IBM cloud that are around 600MB(8-10 audios each of around 70MB) and then processing those audio files using FFMPEG https://www.npmjs.com/package/ffmpeg. Audio processing takes very huge time for around 5 minutes. This process is asynchronous so my Front-end will be responsive.

How can I handle multiple requests for the same processing of audios but the problem is multiple requests will have different audios to get downloaded and processed, so the race condition might occur while handling multiple requests. By reading other stack overflow answers, I get to know there are approaches like creating child process or worker threads. What will be the appropriate approach to my use-case and how can I make sure race-condition is not met?

Upvotes: 0

Views: 951

Answers (2)

slebetman
slebetman

Reputation: 113866

From the documentation of the ffmpeg module we see this:

This library provides a set of functions and utilities to abstract commands-line usage of ffmpeg.

I had a look at the source code of the ffmpeg module and found the core of the implementation is this:

utils.exec([ffmpeg.bin,'-formats','2>&1'], settings, ...

Where utils.exec is basically this:

child_process.exec(finalCommand, settings, ...

So basically the ffmpeg module is already using a child process to perform CPU intensive tasks. Meaning that node.js is not doing any CPU intensive tasks.

Which means you don't need to do anything extra to handle multiple requests. Any additional thing you do will simply use more RAM without any performance benefits.

How to scale:

Scaling this is the same in any language because your server is essentially already multi-threaded/multi-processing. Just use a CPU with more cores.

Scaling beyond CPU:

Big services such as Netflix and YouTube can process tens of thousands of media in parallel. Obviously you cannot buy a CPU with tens of thousands of cores. How you scale is to load-balance your service across multiple CPUs/servers instead of using ffmpeg directly:

 ┌─────────────────┐           ┌─────────────────────┐
 │ node web server │ --------> │ node ffmpeg servers │┐
 └─────────────────┘           └┬────────────────────┘│┐
                                └┬────────────────────┘│
                                 └─────────────────────┘

Upvotes: 1

Rishabh Chakrabarti
Rishabh Chakrabarti

Reputation: 11

Background

I had a similar experience, but it was with video transformation and processing. I had to use ffmpeg to transform videos into different container and quality formats.

Solution

The best way to go about this, for my scenario was to create a job queue. I used celery and it was able to handle it very well.

The equivalent for your use case would be - https://github.com/mher/node-celery

You would have to spawn up some workers that would get assigned a task from a message queue database like RabbitMQ. After the task is done, they asynchronously send back a response. Hopefully this works for your scenario

Upvotes: 1

Related Questions