What is Node Js process structured?
One process:- One process is a global object that can be accessed anywhere and has information about what’s being executed at a time.
One thread:- One thread means that only one set of instructions is executed at a time in a given process.
One event loop:- One event loop is one of the most important conditions to understand about Node. It allows Node to be asynchronous and have non-blocking I/O operation and even though JavaScript is single-threaded.
One JS Engine Instance:- JS engine is a computer program that executes JavaScript code.
One Node.js Instance:- Its computer program that executes Node.js code.
JavaScript and Node.js will never have threads
Some people think that adding a new node module in node js core will allow us to create and sync threads, thus solving the problem of CPU through operations.
It's not, If new threads are added, the nature of the language itself will change. It's not possible to add a new thread as a new set of available classes or functions.
Worker Thread
In node, the worker thread module enables the use of threads that executes Javascript in parallel.
const worker = require('worker_threads');
Worker Threads have:
Worker threads have been available in node js 10 or < 10, but are still in the experimental phase.
What is the goal of the worker thread, you have multiple node js instance inside the same process. With help of a worker thread, a thread can end at some point and it does not require the end of the root process. It's not a best practice for allocated resources by a worker thread to hang around when the worker is gone, that's a memory leak, and we don't want that. When we embed node js into itself, node js gives the ability to create a new thread and then create a new node js instance inside that thread. It means instance running independent threads inside the same process.
Worker thread specialty
ArrayBuffers:- It's transfer memory from one thread to another thread.
SharedArrayBuffers:- It will be accessible from either thread. it used to share memory between threads.
Atomics:- Atomic is available, It allows you to implement conditions variables more efficiently in javascript.
MessagePort:- MessagePort is used for communicating between different threads and it can be used to transfer structured data, memory regions, and other MessagePort between different workers.
MessageChannel:- It specified an asynchronous, two-way communications channel used for communicating between different threads.
WorkerData:- Worker data used to passing startup data. An irresponsible JavaScript value that contains a clone of the data passed to this thread’s worker constructor. if you are using postMessage() then data is cloned.
API
const { worker, parent port } = require(‘worker_threads’)
The worker class represents an independent javascript execution thread and the parent port is an instance of the message port.
new Worker(filename) or new Worker(code, { eval: true })
There are two main ways of starting a worker.
worker.on(‘message’), worker/postMessage(data)
This methods for listening to message and sending them between the differents threads.
parentPort.on(‘message’), parentPort.postMessage(data)
parentPort.postMessage() will be available in the parent thread using worker.on('messages'), and sent message from the parent thread using worker.postMessage() will be available in this thread using parentPort.on('message').
Example:
const { Worker } = require('worker_threads');
const worker = new Worker(`
const { parentPort } = require('worker_threads');
parentPort.once('message',
message => parentPort.postMessage({ pong: message }));
`, { eval: true });
worker.on('message', message => console.log(message));
worker.postMessage('ping');
Output:
$ node --experimental-worker test.js
{ pong: ‘ping’ }
Now this constant function creating a new worker thread and the parent port message is active or listening inside the code or in the worker thread and once it executes and received the message & after that, it sends the response to the main worker thread.
Example:
const {
Worker, isMainThread, parentPort, workerData
} = require('worker_threads');
if (isMainThread) {
module.exports = function parseJSAsync(script) {
return new Promise((resolve, reject) => {
const worker = new Worker(filename, {
workerData: script
});
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
};
} else {
const { parse } = require('some-js-parsing-library');
const script = workerData;
parentPort.postMessage(parse(script));
}
It requires
Worker:- In the worker class that represents an independent JavaScript execution thread.
is the main thread:- If the code is not running inside of a Worker thread it means main thread Boolean that is true.
parent port:- Its message port() allowing communication with the parent thread If this thread was spawned as a Worker.
worker data:- The thread worker constructor contains a clone of the data passed by the arbitrary javascript value.
Thanks for reading!