Hi, Deepal Jayasekara.
Thank you for answering my questions in one of your previous blog posts. Your input was really helpful. I very much appreciate it!
I have a few questions again. It would be great if you could help me clarify some things again.
- I have a question about handles and requests. You wrote about them a few times in your post. For example:
uv__loop_alive— Check whether there are any referenced handlers to be invoked, or any active operations pending
Or:
If there are no active handles or active operations pending, there’s no point of waiting, therefore the timeout is
0.
They are used in some functions. In this one:
And this one:
I don’t understand what uv__has_active_handles and uv__has_active_reqs functions check? What are referenced handlers and active requests / operations (as I can see you’re using requests and operation interchangeably)?
I’ve already read about handles and requests in Libuv’s documentation but I still cannot get it. It is hard to understand without some real word examples. Maybe, handler is something like fs and request / operation is just simple http request? Handlers are invoked in Libuv’s thread pool and any requests / operations are processed on the kernel’s AIO (like epoll in Linux)?
Here is my understanding: the uv__has_active_handles function checks whether there are some unfinished tasks in Libuv’s thread pool (such as reading file’s content with fs). If there are some unfinished tasks this function returns true. As soon as those tasks will be finished, the appropriate events will be fired and their callbacks will be added to the pending_queue. The same logic with requests / operations (but the uv__has_active_reqs checks whether there are some unfinished things on the kernel’s AIO). I am not sure whether I am correct or not.
2. You wrote:
If the
pending_queueis empty, this function will return0. Otherwise, all callbacks inpending_queuewill be executed, and the function will return1.
No questions to this sentence. Perfectly understand it. The question is why does UV_RUN_ONCE mode depend on the result of the uv__run_pending function? You wrote:
If the event loop runs on
UV_RUN_ONCEand ifuv_run_pendingreturns0(i.e,pending_queueis empty),timeoutis calculated usinguv_backend_timeoutmethod.
What’s the difference for the event loop which is running in the UV_RUN_ONCE mode whether there were some callback in the pending_queue or not? If 0 is returned, it means that there were no callbacks. If 1 is returned, it means that there were some callbacks but anyway — they were executed. Why can’t we wait for I/O polling in case if there were some callbacks in the pending_queue before. Anyway, we’ve executed them and pending_queue will be empty.
3. You wrote:
If there are pending idle handles to be executed, waiting for I/O should not be done.
What are these idle handles? Unfortunately, I don’t find any information about this phase in your posts. As I understand, they are running during this phase uv__run_idle. Could you please give us some example from Node.js world? The setImmediate callbacks are executed during the uv__run_check phase… and what callbacks are executed during the uv__run_idle phase?
4. Also, could you please tell us something about uv__run_prepare phase?
5. What is the default mode in which event loop is running? Unfortunately, I don’t find any information about this here. Which of them is the most efficient for the Node.js applications? Or it depends?
Thanks a lot for your time!
