node/lib/internal/perf/event_loop_delay.js
Pablo Erhard c5635b82c9
perf_hooks: sample delay per event loop iteration
Add a samplePerIteration option to monitorEventLoopDelay that records
event loop delay from libuv event loop iterations instead of the timer
interval sampler. The default remains interval-based; existing uses of
monitorEventLoopDelay() keep behaving the same unless the
samplePerIteration option is passed through.

Signed-off-by: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
PR-URL: https://github.com/nodejs/node/pull/62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-06-24 23:50:06 +00:00

99 lines
1.9 KiB
JavaScript

'use strict';
const {
ReflectConstruct,
SafeMap,
Symbol,
SymbolDispose,
} = primordials;
const {
codes: {
ERR_ILLEGAL_CONSTRUCTOR,
ERR_INVALID_THIS,
},
} = require('internal/errors');
const {
createELDHistogram,
} = internalBinding('performance');
const {
validateBoolean,
validateInteger,
validateObject,
} = require('internal/validators');
const {
Histogram,
kHandle,
kMap,
} = require('internal/histogram');
const {
kEmptyObject,
} = require('internal/util');
const {
markTransferMode,
} = require('internal/worker/js_transferable');
const kEnabled = Symbol('kEnabled');
class ELDHistogram extends Histogram {
constructor() {
throw new ERR_ILLEGAL_CONSTRUCTOR();
}
/**
* @returns {boolean}
*/
enable() {
if (this[kEnabled] === undefined)
throw new ERR_INVALID_THIS('ELDHistogram');
if (this[kEnabled]) return false;
this[kEnabled] = true;
this[kHandle].start();
return true;
}
/**
* @returns {boolean}
*/
disable() {
if (this[kEnabled] === undefined)
throw new ERR_INVALID_THIS('ELDHistogram');
if (!this[kEnabled]) return false;
this[kEnabled] = false;
this[kHandle].stop();
return true;
}
[SymbolDispose]() {
this.disable();
}
}
/**
* @param {{
* samplePerIteration : boolean,
* resolution : number
* }} [options]
* @returns {ELDHistogram}
*/
function monitorEventLoopDelay(options = kEmptyObject) {
validateObject(options, 'options');
const { samplePerIteration = false, resolution = 10 } = options;
validateBoolean(samplePerIteration, 'options.samplePerIteration');
validateInteger(resolution, 'options.resolution', 1);
return ReflectConstruct(
function() {
markTransferMode(this, true, false);
this[kEnabled] = false;
this[kHandle] = createELDHistogram(resolution, samplePerIteration);
this[kMap] = new SafeMap();
}, [], ELDHistogram);
}
module.exports = monitorEventLoopDelay;