| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a50bbca commit 3aaae68
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -880,6 +880,40 @@ added: v8.5.0 | |||
| 880 | 880 | The high resolution millisecond timestamp at which the Node.js process was | |
| 881 | 881 | initialized. | |
| 882 | 882 | ||
| 883 | + ### `performanceNodeTiming.uvMetricsInfo` | ||
| 884 | + | ||
| 885 | + <!-- YAML | ||
| 886 | + added: REPLACEME | ||
| 887 | + --> | ||
| 888 | + | ||
| 889 | + * Returns: {Object} | ||
| 890 | + * `loopCount` {number} Number of event loop iterations. | ||
| 891 | + * `events` {number} Number of events that have been processed by the event handler. | ||
| 892 | + * `eventsWaiting` {number} Number of events that were waiting to be processed when the event provider was called. | ||
| 893 | + | ||
| 894 | + This is a wrapper to the `uv_metrics_info` function. | ||
| 895 | + It returns the current set of event loop metrics. | ||
| 896 | + | ||
| 897 | + It is recommended to use this property inside a function whose execution was | ||
| 898 | + scheduled using `setImmediate` to avoid collecting metrics before finishing all | ||
| 899 | + operations scheduled during the current loop iteration. | ||
| 900 | + | ||
| 901 | + ```cjs | ||
| 902 | + const { performance } = require('node:perf_hooks'); | ||
| 903 | + | ||
| 904 | + setImmediate(() => { | ||
| 905 | + console.log(performance.nodeTiming.uvMetricsInfo); | ||
| 906 | + }); | ||
| 907 | + ``` | ||
| 908 | + | ||
| 909 | + ```mjs | ||
| 910 | + import { performance } from 'node:perf_hooks'; | ||
| 911 | + | ||
| 912 | + setImmediate(() => { | ||
| 913 | + console.log(performance.nodeTiming.uvMetricsInfo); | ||
| 914 | + }); | ||
| 915 | + ``` | ||
| 916 | + | ||
| 883 | 917 | ### `performanceNodeTiming.v8Start` | |
| 884 | 918 | ||
| 885 | 919 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ const { | |||
| 28 | 28 | NODE_PERFORMANCE_MILESTONE_ENVIRONMENT, | |
| 29 | 29 | }, | |
| 30 | 30 | loopIdleTime, | |
| 31 | + uvMetricsInfo, | ||
| 31 | 32 | } = internalBinding('performance'); | |
| 32 | 33 | ||
| 33 | 34 | class PerformanceNodeTiming { | |
@@ -122,6 +123,13 @@ class PerformanceNodeTiming { | |||
| 122 | 123 | configurable: true, | |
| 123 | 124 | get: loopIdleTime, | |
| 124 | 125 | }, | |
| 126 | + | ||
| 127 | + uvMetricsInfo: { | ||
| 128 | + __proto__: null, | ||
| 129 | + enumerable: true, | ||
| 130 | + configurable: true, | ||
| 131 | + get: uvMetricsInfo, | ||
| 132 | + }, | ||
| 125 | 133 | }); | |
| 126 | 134 | } | |
| 127 | 135 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -134,6 +134,8 @@ | |||
| 134 | 134 | V(env_var_settings_string, "envVarSettings") \ | |
| 135 | 135 | V(errno_string, "errno") \ | |
| 136 | 136 | V(error_string, "error") \ | |
| 137 | + V(events, "events") \ | ||
| 138 | + V(events_waiting, "eventsWaiting") \ | ||
| 137 | 139 | V(exchange_string, "exchange") \ | |
| 138 | 140 | V(expire_string, "expire") \ | |
| 139 | 141 | V(exponent_string, "exponent") \ | |
@@ -203,6 +205,7 @@ | |||
| 203 | 205 | V(kind_string, "kind") \ | |
| 204 | 206 | V(length_string, "length") \ | |
| 205 | 207 | V(library_string, "library") \ | |
| 208 | + V(loop_count, "loopCount") \ | ||
| 206 | 209 | V(mac_string, "mac") \ | |
| 207 | 210 | V(max_buffer_string, "maxBuffer") \ | |
| 208 | 211 | V(max_concurrent_streams_string, "maxConcurrentStreams") \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -261,6 +261,30 @@ void LoopIdleTime(const FunctionCallbackInfo<Value>& args) { | |||
| 261 | 261 | args.GetReturnValue().Set(1.0 * idle_time / NANOS_PER_MILLIS); | |
| 262 | 262 | } | |
| 263 | 263 | ||
| 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 | + | ||
| 264 | 288 | void CreateELDHistogram(const FunctionCallbackInfo<Value>& args) { | |
| 265 | 289 | Environment* env = Environment::GetCurrent(args); | |
| 266 | 290 | int64_t interval = args[0].As<Integer>()->Value(); | |
@@ -324,6 +348,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, | |||
| 324 | 348 | SetMethod(isolate, target, "loopIdleTime", LoopIdleTime); | |
| 325 | 349 | SetMethod(isolate, target, "createELDHistogram", CreateELDHistogram); | |
| 326 | 350 | SetMethod(isolate, target, "markBootstrapComplete", MarkBootstrapComplete); | |
| 351 | + SetMethod(isolate, target, "uvMetricsInfo", UvMetricsInfo); | ||
| 327 | 352 | SetFastMethodNoSideEffect( | |
| 328 | 353 | isolate, target, "now", SlowPerformanceNow, &fast_performance_now); | |
| 329 | 354 | } | |
@@ -390,6 +415,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |||
| 390 | 415 | registry->Register(LoopIdleTime); | |
| 391 | 416 | registry->Register(CreateELDHistogram); | |
| 392 | 417 | registry->Register(MarkBootstrapComplete); | |
| 418 | + registry->Register(UvMetricsInfo); | ||
| 393 | 419 | registry->Register(SlowPerformanceNow); | |
| 394 | 420 | registry->Register(FastPerformanceNow); | |
| 395 | 421 | registry->Register(fast_performance_now.GetTypeInfo()); | |
| Original file line number | Diff line number | Diff 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 | + } | ||
| Original file line number | Diff line number | Diff 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 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments