Query length of event loop queue

3,146 views
Skip to first unread message

Chaoran Yang

unread,
Jun 17, 2013, 11:20:50 AM6/17/13
to nod...@googlegroups.com
Dear all,

Is there any way in node.js I can query the length of event loop queue? I assume the event loop has a queue of callbacks. Checking the queue length can be useful to know whether a server is busy or not at a certain time.

-Chaoran

Jorge

unread,
Jun 17, 2013, 4:21:08 PM6/17/13
to nod...@googlegroups.com
On 17/06/2013, at 17:20, Chaoran Yang wrote:

> Dear all,
>
> Is there any way in node.js I can query the length of event loop queue?

No.

> I assume the event loop has a queue of callbacks.

No there's no queue. An event happens -> its handler (if any) is called: it doesn't go through any queue.

> Checking the queue length can be useful to know whether a server is busy or not at a certain time.

The only queue there is is the nextTick queue. Well now it's the setImmediate queue, I think. But IIRC neither the nextTicked functions' [] nor its .length was visible from user code.

--
( Jorge )();

mscdex

unread,
Jun 17, 2013, 4:38:12 PM6/17/13
to nodejs
You might try `process._getActiveRequests();` and/or
`process._getActiveHandles();`

Forrest L Norvell

unread,
Jun 17, 2013, 4:54:04 PM6/17/13
to nod...@googlegroups.com
There are a few things you can do, but this is a simple question with a surprisingly complex answer. The short answer is that knowing the length of a notional "event loop queue" doesn't really do a very good job of telling you how busy your application is. The different kinds of tasks that libuv manages (I/O, deferred execution via setTimeout / setInterval, "asynchronizers" like process.nextTick() and setImmediate(), signal handlers) are handled at different stages and with different priorities.

The first thing is to remember that there are a number of different sources of work feeding into the event queue:
  • there's the process.nextTick() queue, which is processed at a variety of points through each turn of the event loop
  • as Jorge said, there's are tasks set to execute via setImmediate()
  • libuv handles the list of I/O requests with available input and hands those off to turns of the event loop
See this handy graphic for an only somewhat out-of-date (but *very* useful -- it should probably be part of the docs) visualization of how all that happens: https://a248.e.akamai.net/camo.github.com/e0b4108147b3fa603ef6badd805a2f01d73460fc/687474703a2f2f68746d6c352e6f687473752e6f72672f6e65775f736574496d6d6564696174655f73656d616e746963732e706e67

The problem is that turnings of the event loop aren't homogenous, and the event loop queues on their own don't really tell you the most important thing, which is whether your application is getting bogged down (for whatever definition of "bogged down" works well for you). There are modules like node-toobusy that try to monitor the latency of the event loop and tell you if it's taking too long (which can actually be helpful if you're doing a lot with process.nextTick(), or are trying to do something CPU-intensive in single turns of the event loop), but by and large, this kind of information is hard to gather from inside Node and turns out to be of limited use.

There's also DTrace, which can give you much finer-grained (or coarser-grained!) statistics about what's going on with the event loop.

Most of the time, the only time you'll encounter performance problems tied to event loop processing is when you're trying to do too much computation during a single turn of the event loop. I'd generally look pretty much everywhere else first when trying to do performance tuning.

F




--
--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Jorge

unread,
Jun 17, 2013, 5:41:22 PM6/17/13
to nod...@googlegroups.com
On 17/06/2013, at 22:54, Forrest L Norvell wrote:

> See this handy graphic for an only somewhat out-of-date (but *very* useful -- it should probably be part of the docs) visualization of how all that happens: https://a248.e.akamai.net/camo.github.com/e0b4108147b3fa603ef6badd805a2f01d73460fc/687474703a2f2f68746d6c352e6f687473752e6f72672f6e65775f736574496d6d6564696174655f73656d616e746963732e706e67

Wow, that's even beautiful! :-)

--
( Jorge )();

Timothy J Fontaine

unread,
Jun 17, 2013, 6:11:48 PM6/17/13
to nod...@googlegroups.com
Coming up in 0.12 there are first class DTrace probes for libuv in the form of tick-start and tick-end so you'll be able to effectively monitor the event loop "turn".



--
( Jorge )();

Andrey

unread,
Jun 17, 2013, 8:33:19 PM6/17/13
to nod...@googlegroups.com

Chaoran Yang

unread,
Jun 18, 2013, 9:44:35 AM6/18/13
to nod...@googlegroups.com
Thanks you, F. The link you pointed me to is very helpful! 

-Chaoran

Chaoran Yang

unread,
Jun 18, 2013, 9:45:01 AM6/18/13
to nod...@googlegroups.com
The node-toobusy module looks awesome! It solves the exact problem I want to solve!

Thanks,
-Chaoran

TJ Marbois

unread,
Sep 8, 2013, 11:07:42 AM9/8/13
to nod...@googlegroups.com
Is it possible for you to explain a little more detail about these two undocumented functions? is there a reason why they remain undocumented?

process._getActiveHandles()
process._getActiveRequests()

cheers

Tj

Ben Noordhuis

unread,
Sep 8, 2013, 2:37:28 PM9/8/13
to nod...@googlegroups.com
On Sun, Sep 8, 2013 at 5:07 PM, TJ Marbois <tmar...@gmail.com> wrote:
> Is it possible for you to explain a little more detail about these two
> undocumented functions? is there a reason why they remain undocumented?
>
> process._getActiveHandles()
> process._getActiveRequests()
>
> cheers
>
> Tj

They're debugging tools I added to make my life a little easier. I
didn't document them back then because they:

a) rely heavily on implementation details, i.e. I may have to remove
them again someday, and

b) probably don't work the way most people would expect them to
(returns internal wrap objects only, timers don't show up except for
the master timer, etc.)

TJ Marbois

unread,
Sep 8, 2013, 2:43:10 PM9/8/13
to nod...@googlegroups.com
Ben

ok thanks.. yea I was tinkering with them and saw some strange returns - and wasn't sure how to interpret them... ie:  some functions being tracked and others ignored - I figured it must be some internal info that is not available to the regular node user.

I was hoping to find a way to examine the event cue - at least enough to see whats been placed there from my running program and in what order those things will be executed once the cue is started.

Is there any way to do this at all? Or are there plans in the future to allow something like this?

cheers

TJ

Ben Noordhuis

unread,
Sep 8, 2013, 5:49:28 PM9/8/13
to nod...@googlegroups.com
On Sun, Sep 8, 2013 at 8:43 PM, TJ Marbois <tmar...@gmail.com> wrote:
> Ben
>
> ok thanks.. yea I was tinkering with them and saw some strange returns - and
> wasn't sure how to interpret them... ie: some functions being tracked and
> others ignored - I figured it must be some internal info that is not
> available to the regular node user.
>
> I was hoping to find a way to examine the event cue - at least enough to see
> whats been placed there from my running program and in what order those
> things will be executed once the cue is started.

If we're talking asynchronous I/O here, then there is usually no clear
order of events.

> Is there any way to do this at all? Or are there plans in the future to
> allow something like this?

Right now not easily but things may get better in v0.12. There is an
in-progress pull request[1] that adds a kind of AOP interceptor API
that makes it easy to track callbacks into JS land.

Completion callbacks are only half the story though. The other half
is tracking asynchronous I/O requests but that's something you can do
with good old monkey-patching. I expect to see npm modules show up
for that minutes after the PR lands.

[1] https://github.com/joyent/node/pull/6011

TJ Marbois

unread,
Sep 9, 2013, 12:37:07 AM9/9/13
to nod...@googlegroups.com
Thanks Ben...

I'll be looking forwards to the completion callbacks in v.12 -- thanks for the explains. 

( and to the monkey patch npm jungle coming soon... haha )

Yuhao Zhu

unread,
Jan 14, 2015, 12:51:54 AM1/14/15
to nod...@googlegroups.com
It's generally hard to inspect the event loop info in node.js itself. Node.js internally uses libuv to implement the event queue. libuv in turn uses epoll (if you are on Linux) to implement events, etc. Both node.js and libuv hide a lot of details of epoll. So if you want to really understand the event loop of node.js, you need to understand epoll.

Just a quick tour. in src/node.cc, 'uv_run(env->event_loop(), UV_RUN_ONCE)' is called. uv_run is the main event loop of libuv, and is implemented in deps/uv/src/unix/core.c. If you look at uv_run()'s implementation, the most important part is 'uv__io_poll(loop, timeout);'. uv__io_poll is what actually listens to I/O events. It is implemented in deps/uv/src/unix/linux-core.c. Basically uv__io_poll is using the epoll system call to listen to events. (For more understanding of epoll, this post might help. For a thorough understanding of epoll, I recommend the book 'The Linux Programming Interface').

Eventually uv__io_poll calls 'nfds = uv__epoll_wait(loop->backend_fd, events, ARRAY_SIZE(events), timeout);'. The return value nfds indicates how many file descriptors (could be file I/O or socket, etc.) have events triggered and therefore are ready to execute their corresponding event handlers. That value is *roughly* how many events that are queued in the event queue. Again, a good understanding of epoll is required.
Reply all
Reply to author
Forward
0 new messages