Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1f2cc2f

Browse filesBrowse files
committed
src,lib: add performance.uvMetricsInfo
This commit exposes a new API to the perf_hooks.performance module. This wraps uv_metrics_info into performance.uvMetricsInfo() function. PR-URL: #54413 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent f67cdf8 commit 1f2cc2f
Copy full SHA for 1f2cc2f

File tree

Expand file treeCollapse file tree

6 files changed

+137
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+137
-0
lines changed
Open diff view settings
Collapse file

‎doc/api/perf_hooks.md‎

Copy file name to clipboardExpand all lines: doc/api/perf_hooks.md
+34Lines changed: 34 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,40 @@ added: v8.5.0
887887
The high resolution millisecond timestamp at which the Node.js process was
888888
initialized.
889889

890+
### `performanceNodeTiming.uvMetricsInfo`
891+
892+
<!-- YAML
893+
added: REPLACEME
894+
-->
895+
896+
* Returns: {Object}
897+
* `loopCount` {number} Number of event loop iterations.
898+
* `events` {number} Number of events that have been processed by the event handler.
899+
* `eventsWaiting` {number} Number of events that were waiting to be processed when the event provider was called.
900+
901+
This is a wrapper to the `uv_metrics_info` function.
902+
It returns the current set of event loop metrics.
903+
904+
It is recommended to use this property inside a function whose execution was
905+
scheduled using `setImmediate` to avoid collecting metrics before finishing all
906+
operations scheduled during the current loop iteration.
907+
908+
```cjs
909+
const { performance } = require('node:perf_hooks');
910+
911+
setImmediate(() => {
912+
console.log(performance.nodeTiming.uvMetricsInfo);
913+
});
914+
```
915+
916+
```mjs
917+
import { performance } from 'node:perf_hooks';
918+
919+
setImmediate(() => {
920+
console.log(performance.nodeTiming.uvMetricsInfo);
921+
});
922+
```
923+
890924
### `performanceNodeTiming.v8Start`
891925

892926
<!-- YAML
Collapse file

‎lib/internal/perf/nodetiming.js‎

Copy file name to clipboardExpand all lines: lib/internal/perf/nodetiming.js
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const {
2828
NODE_PERFORMANCE_MILESTONE_ENVIRONMENT,
2929
},
3030
loopIdleTime,
31+
uvMetricsInfo,
3132
} = internalBinding('performance');
3233

3334
class PerformanceNodeTiming {
@@ -122,6 +123,13 @@ class PerformanceNodeTiming {
122123
configurable: true,
123124
get: loopIdleTime,
124125
},
126+
127+
uvMetricsInfo: {
128+
__proto__: null,
129+
enumerable: true,
130+
configurable: true,
131+
get: uvMetricsInfo,
132+
},
125133
});
126134
}
127135

Collapse file

‎src/env_properties.h‎

Copy file name to clipboardExpand all lines: src/env_properties.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@
144144
V(env_var_settings_string, "envVarSettings") \
145145
V(errno_string, "errno") \
146146
V(error_string, "error") \
147+
V(events, "events") \
148+
V(events_waiting, "eventsWaiting") \
147149
V(exchange_string, "exchange") \
148150
V(expire_string, "expire") \
149151
V(exponent_string, "exponent") \
@@ -213,6 +215,7 @@
213215
V(kind_string, "kind") \
214216
V(length_string, "length") \
215217
V(library_string, "library") \
218+
V(loop_count, "loopCount") \
216219
V(mac_string, "mac") \
217220
V(max_buffer_string, "maxBuffer") \
218221
V(max_concurrent_streams_string, "maxConcurrentStreams") \
Collapse file

‎src/node_perf.cc‎

Copy file name to clipboardExpand all lines: src/node_perf.cc
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,30 @@ void LoopIdleTime(const FunctionCallbackInfo<Value>& args) {
261261
args.GetReturnValue().Set(1.0 * idle_time / NANOS_PER_MILLIS);
262262
}
263263

264+
void UvMetricsInfo(const FunctionCallbackInfo<Value>& args) {
265+
Environment* env = Environment::GetCurrent(args);
266+
uv_metrics_t metrics;
267+
268+
// uv_metrics_info always return 0
269+
CHECK_EQ(uv_metrics_info(env->event_loop(), &metrics), 0);
270+
271+
Local<Object> obj = Object::New(env->isolate());
272+
obj->Set(env->context(),
273+
env->loop_count(),
274+
Integer::NewFromUnsigned(env->isolate(), metrics.loop_count))
275+
.Check();
276+
obj->Set(env->context(),
277+
env->events(),
278+
Integer::NewFromUnsigned(env->isolate(), metrics.events))
279+
.Check();
280+
obj->Set(env->context(),
281+
env->events_waiting(),
282+
Integer::NewFromUnsigned(env->isolate(), metrics.events_waiting))
283+
.Check();
284+
285+
args.GetReturnValue().Set(obj);
286+
}
287+
264288
void CreateELDHistogram(const FunctionCallbackInfo<Value>& args) {
265289
Environment* env = Environment::GetCurrent(args);
266290
int64_t interval = args[0].As<Integer>()->Value();
@@ -324,6 +348,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
324348
SetMethod(isolate, target, "loopIdleTime", LoopIdleTime);
325349
SetMethod(isolate, target, "createELDHistogram", CreateELDHistogram);
326350
SetMethod(isolate, target, "markBootstrapComplete", MarkBootstrapComplete);
351+
SetMethod(isolate, target, "uvMetricsInfo", UvMetricsInfo);
327352
SetFastMethodNoSideEffect(
328353
isolate, target, "now", SlowPerformanceNow, &fast_performance_now);
329354
}
@@ -390,6 +415,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
390415
registry->Register(LoopIdleTime);
391416
registry->Register(CreateELDHistogram);
392417
registry->Register(MarkBootstrapComplete);
418+
registry->Register(UvMetricsInfo);
393419
registry->Register(SlowPerformanceNow);
394420
registry->Register(FastPerformanceNow);
395421
registry->Register(fast_performance_now.GetTypeInfo());
Collapse file
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Enforcing strict checks on the order or number of events across different
2+
// platforms can be tricky and unreliable due to various factors.
3+
// As a result, this test relies on the `uv_metrics_info` call instead.
4+
const { performance } = require('node:perf_hooks');
5+
const assert = require('node:assert');
6+
const fs = require('node:fs');
7+
const { nodeTiming } = performance;
8+
9+
function safeMetricsInfo(cb) {
10+
setImmediate(() => {
11+
const info = nodeTiming.uvMetricsInfo;
12+
cb(info);
13+
});
14+
}
15+
16+
{
17+
const info = nodeTiming.uvMetricsInfo;
18+
assert.strictEqual(info.loopCount, 0);
19+
assert.strictEqual(info.events, 0);
20+
// This is the only part of the test that we test events waiting
21+
// Adding checks for this property will make the test flaky
22+
// as it can be highly influenced by race conditions.
23+
assert.strictEqual(info.eventsWaiting, 0);
24+
}
25+
26+
{
27+
// The synchronous call should obviously not affect the uv metrics
28+
const fd = fs.openSync(__filename, 'r');
29+
fs.readFileSync(fd);
30+
const info = nodeTiming.uvMetricsInfo;
31+
assert.strictEqual(info.loopCount, 0);
32+
assert.strictEqual(info.events, 0);
33+
assert.strictEqual(info.eventsWaiting, 0);
34+
}
35+
36+
{
37+
function openFile(info) {
38+
assert.strictEqual(info.loopCount, 1);
39+
40+
fs.open(__filename, 'r', (err) => {
41+
assert.ifError(err);
42+
});
43+
}
44+
45+
safeMetricsInfo(openFile);
46+
}
Collapse file
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
common.skipIfWorker();
5+
6+
const { spawnSync } = require('node:child_process');
7+
const assert = require('node:assert');
8+
const fixtures = require('../common/fixtures');
9+
10+
const file = fixtures.path('test-nodetiming-uvmetricsinfo.js');
11+
12+
{
13+
const { status, stderr } = spawnSync(
14+
process.execPath,
15+
[
16+
file,
17+
],
18+
);
19+
assert.strictEqual(status, 0, stderr.toString());
20+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.