Libuv in Node.js
Libuv is a library written in the programming language C that helps nodejs to improve efficiency while running tasks parallelly. However, nodejs already have async API's. It uses Libuvs's thread pools if async API is not available in nodejs and processes are blocking the operations. Libuv doesn't perform the task itself, it only manages the operations.
Consider that we have skills and potential to grow our careers. But we need a mentor to nurture it and we can utilize it well. So, The Libuv is a kind of mentor for nodejs.
Introduction to Libuv
Considering that there is only one main gate to enter an event and there are three categories of people: A, B, and C. Also there are two different venues X and Y. In Venue X,
- People go through the metal detection process
- People show their tickets and they check their categories and tickets.
All of this is happening at the main gate. Hence, It slows down the process, blocking the next person until the previous one is not done.
On the other hand, In Venue Y,
- People go through the metal detection process at the main gate.
- And show their tickets at their respective counter according to category.
In this way, They only check if the user exists in the database instead of checking all the details at once. Hence, it finishes the whole process early because it divides the whole process into small tasks and people are distributed automatically without providing information about their category or booking.
Features of Libuv
The event loop manages the operation and assigns the task according to machine specifications and operating system. And it is called event polling.
TCP and UDP sockets, and child processes are handles that keep the reference of callback. If handles are active, the Event loop allows the callback to run. Thread pools handle tasks in parallel that block I/O operations.
A high-resolution clock is used to track every little moment. Because Date.now is not accurate enough to track the completion time of operations and tasks and Date.now doesn't provide complete information about the date and time.
Inter-Process Communication helps processes to communicate with each other and keep the information synchronized. The following figure and bullet points show the features of Libuv:
- Event loop that supports various operating systems (epoll for LINUX, kqueue for OSX, IOCP for windows, event ports for SunOS)
- TCP sockets: ( net module in nodejs )
- DNS resolver: ( dns module in nodejs )
- UDP sockets: ( dgrammodule in nodejs )
- File I/O which includes writing files, reading files, watching file changes, and other operations (fs module in nodejs )
- Child processes: ( child_process in nodejs )
- Threadpool: ( worker_threads module in nodejs)
- Synchronization primitives: It allows the main thread to wait until the worker thread sends the signal
- High-resolution clock
- Inter-Process Communication using sockets and Unix domain sockets (Windows)
Event or I/O Loop
In Libuv, the Event loop plays an important role to reduce the workload of the nodejs system. The event loop mainly has two parts: Event Queue and Threads
- The event loop listens to the event and adds events to the event queue. Then, The event loop assigns tasks to worker threads that handle the request.
- It tracks the movement like the time to process the request, and whether an operation is completed or terminated.
- Event loop continuously keeps checking the status of assigned tasks and adds/removes the event to the event queue as needed.
File I/O in the libuv divides the big operations into small operations and allows threads to queue the task in a loop. These threads perform the task conditionally based on success/failure notification.
Consider if you perform the following tasks on your PC:
- Task-1: Editing a file in a Notepad
- Task-2: Using chrome browser
- Task-3: Working on excel sheet
So, when you are editing a file in notepad, the PC does not terminate Task-2 and Task-3 but instead adds them to a queue. In the same way, when you work with an excel sheet, the PC adds them to a queue.
Hence, All task-1, task-2, and task-3 are running parallelly. And when you switch tasks, the PC adds the current task to priority and puts all other tasks in the loop.
Libuv Thread Pool
By default, Libuv uses 4 threads to handle the operations and tasks. It reduces the workload of synchronous operations and avoids blocking tasks unnecessarily. We can use any number of threads up to 1024 and it also depends on the performance parameter of the system. We use the UV_THREADPOOL_SIZE variable to set the threads in nodejs.
Physical vs Logical CPU Cores
Consider that an intel i5 processor has 4 CPU cores to handle the operations. And these cores are called physical cores. But if CPU cores are hyper-threaded, then each one of them can perform 2 operations parallelly. Therefore, there are 8 CPU cores and it is called logical cores.
How to Check For Logical Cores?
When we deploy our app on any platform i.e. (web, android/ios, desktop), the app might run on any operating system having different machine specifications. And in that case, we can set the thread pool size dynamically based on the respective operating system as shown below
In the above code block, We use the os module to get the length of the CPU cores and the process module to set the environment variable UV_THREADPOOL_SIZE for the current machine specifications. The cpus().length return the total no of logical cores.
Note: If the CPU cores are not hyper-threaded, The cpus().length return the total no of physical CPU cores.
Your journey to becoming a certified Node.js developer starts here. Enroll in Scaler Topics and set yourself on the path to a rewarding programming career.
- Libuv transfer the process to the system If any operation blocks the process.
- Libuv reduces the workload of operations performed by nodejs.
- Libuv Features help nodejs to handle and manage complex operations in less time as it efficiently distributes the tasks.
- Libuv boosts the operation further if we increase the thread pool size. Also, it depends on the specifications of the system.
- Libuv interrupts only if there is no particular async API available in nodejs.