Multithreading: A technique by which a single set of code can be used by several processors at different stages of execution.
Node.js is a single-threaded JavaScript runtime which in the background uses multiple threads to execute asynchronous code.
Node.js has two types of threads: one Event Loop and k Workers. The Event Loop is responsible for JavaScript callbacks and non-blocking I/O, and a Worker executes tasks corresponding to C++ code that completes an asynchronous request, including blocking I/O and CPU-intensive work.
Few operations running in the main process that could block the event loop; then they degrade the performance of the Node.js application
A.K.A.: How well a particular algorithm or data structure could scale.
// REDOS Example
const r = /([a-z]+)+$/
const s = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa!'
console.log('Running regular expression... please wait')
console.time('benchmark')
r.test(s)
console.timeEnd('benchmark')
// JSON DOS
let obj = { a: 1 }
const niter = 20
let before, res, took
for (let i = 0; i < niter; i++) {
obj = { obj1: obj, obj2: obj } // Doubles in size each iter
}
before = process.hrtime()
res = JSON.stringify(obj)
took = process.hrtime(before)
console.log('JSON.stringify took ' + took)
Split operations in different steps using asynchronous methods (like setImmediate) so that each runs on the Event Loop but regularly allow for processing other events.
Create a native C++ addon and move the complex operations out of the main thread. not suitable for many cases.
Launch any type of process and provides an event-emitter interface for it:
Cluster module allows us to create worker processes where all share server ports easily. Also, it magically creates an I.P.C. channel to communicate the master and worker process, passing JavaScript objects.
* Warning: don't create a cluster for your entire server, is preferred to have an external cluster manager and a load balancer for production environments due to performance and debuggability.
Workers (threads) are useful for performing CPU-intensive JavaScript operations. Unlike child_process or cluster, worker_threads can share memory. They do so by transferring ArrayBuffer instances or sharing SharedArrayBuffer instances.
* Warning: Available from Node.js 10, but are still in the experimental phase.