Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect and measure event loop blocking in node.js?

I'd like to monitor how long each run of the event loop in node.js takes. However I'm uncertain about the best way to measure this. The best way I could come up with looks like this:

var interval = 500;
var interval = setInterval(function() {
    var last = Date.now();        
    setImmediate(function() {
        var delta = Date.now() - last;
        if (delta > blockDelta) {
            report("node.eventloop_blocked", delta);
        }
    });
}, interval);

I basically infer the event loop run time by looking at the delay of a setInterval. I've seen the same approach in the blocked node module but it feels inaccurate and heavy. Is there a better way to get to this information?

Update: Changed the code to use setImmediate as done by hapi.js.

like image 566
Fabian Jakobs Avatar asked Feb 17 '15 14:02

Fabian Jakobs


People also ask

How do I know if event loop is blocking?

The added delay between invocations can be a good indicator of an Event Loop Blocker since concurrent operations that block the Event Loop may delay timers from being fired.

How are event loops blocked?

The Event-loop is single-threaded Also known as the “one instruction to block them all” factor. Indeed in Node. js you can block every request just because one of them had a blocking instruction. A good review of your code should always start with a distinction between blocking and non-blocking code.

Do loops block the event loop?

As long as that while loop is running, the event loop is blocked.

How does event loop work in NodeJS?

Event loop is an endless loop, which waits for tasks, executes them and then sleeps until it receives more tasks. The event loop executes tasks from the event queue only when the call stack is empty i.e. there is no ongoing task. The event loop allows us to use callbacks and promises.


2 Answers

"Is there a better way to get this information?" I don't have a better way to test the eventloop than checking the time delay of SetImmediate, but you can get better precision using node's high resolution timer instead of Date.now()

var interval = 500;
var interval = setInterval(function() {
    var last = process.hrtime();          // replace Date.now()        
    setImmediate(function() {
        var delta = process.hrtime(last); // with process.hrtime()
        if (delta > blockDelta) {
            report("node.eventloop_blocked", delta);
        }
    });
}, interval);

NOTE: delta will be a tuple Array [seconds, nanoseconds].

For more details on process.hrtime(): https://nodejs.org/api/all.html#all_process_hrtime

"The primary use is for measuring performance between intervals."

like image 141
YoungJohn Avatar answered Nov 03 '22 00:11

YoungJohn


Check out this plugin https://github.com/tj/node-blocked I'm using it now and it seems to do what you want.

let blocked = require("blocked");

blocked(ms => {
  console.log("EVENT LOOP Blocked", ms);
});

Will print out how long in ms the event loop is blocked for

like image 23
Joshua Ohana Avatar answered Nov 03 '22 00:11

Joshua Ohana