Skip to content

Commit df5083e

Browse files
H4adtargos
authored andcommitted
src,lib: expose getCategoryEnabledBuffer to use on node.http
Instead call the C++ code every time we need to check for a trace category, now we get the C++ pointer to the flag that holds the info if the trace is enabled and return this pointer inside a buffer that we can use to call/check if the value is enabled. With this change, no C++ call is made and the access to the info happens in JS side, which has no perf penalty. PR-URL: #53602 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 3c40868 commit df5083e

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

lib/internal/http.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66
} = primordials;
77

88
const { setUnrefTimeout } = require('internal/timers');
9-
const { trace, isTraceCategoryEnabled } = internalBinding('trace_events');
9+
const { getCategoryEnabledBuffer, trace } = internalBinding('trace_events');
1010
const {
1111
CHAR_LOWERCASE_B,
1212
CHAR_LOWERCASE_E,
@@ -35,8 +35,10 @@ function getNextTraceEventId() {
3535
return ++traceEventId;
3636
}
3737

38+
const httpEnabled = getCategoryEnabledBuffer('node.http');
39+
3840
function isTraceHTTPEnabled() {
39-
return isTraceCategoryEnabled('node.http');
41+
return httpEnabled[0] > 0;
4042
}
4143

4244
const traceEventCategory = 'node,node.http';

src/node_trace_events.cc

+27
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace node {
1616
class ExternalReferenceRegistry;
1717

1818
using v8::Array;
19+
using v8::ArrayBuffer;
20+
using v8::BackingStore;
1921
using v8::Context;
2022
using v8::Function;
2123
using v8::FunctionCallbackInfo;
@@ -25,6 +27,7 @@ using v8::Local;
2527
using v8::NewStringType;
2628
using v8::Object;
2729
using v8::String;
30+
using v8::Uint8Array;
2831
using v8::Value;
2932

3033
class NodeCategorySet : public BaseObject {
@@ -120,6 +123,27 @@ static void SetTraceCategoryStateUpdateHandler(
120123
env->set_trace_category_state_function(args[0].As<Function>());
121124
}
122125

126+
static void GetCategoryEnabledBuffer(const FunctionCallbackInfo<Value>& args) {
127+
CHECK(args[0]->IsString());
128+
129+
Isolate* isolate = args.GetIsolate();
130+
node::Utf8Value category_name(isolate, args[0]);
131+
132+
const uint8_t* enabled_pointer =
133+
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_name.out());
134+
uint8_t* enabled_pointer_cast = const_cast<uint8_t*>(enabled_pointer);
135+
136+
std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore(
137+
enabled_pointer_cast,
138+
sizeof(*enabled_pointer_cast),
139+
[](void*, size_t, void*) {},
140+
nullptr);
141+
auto ab = ArrayBuffer::New(isolate, std::move(bs));
142+
v8::Local<Uint8Array> u8 = v8::Uint8Array::New(ab, 0, 1);
143+
144+
args.GetReturnValue().Set(u8);
145+
}
146+
123147
void NodeCategorySet::Initialize(Local<Object> target,
124148
Local<Value> unused,
125149
Local<Context> context,
@@ -132,6 +156,8 @@ void NodeCategorySet::Initialize(Local<Object> target,
132156
target,
133157
"setTraceCategoryStateUpdateHandler",
134158
SetTraceCategoryStateUpdateHandler);
159+
SetMethod(
160+
context, target, "getCategoryEnabledBuffer", GetCategoryEnabledBuffer);
135161

136162
Local<FunctionTemplate> category_set =
137163
NewFunctionTemplate(isolate, NodeCategorySet::New);
@@ -160,6 +186,7 @@ void NodeCategorySet::RegisterExternalReferences(
160186
ExternalReferenceRegistry* registry) {
161187
registry->Register(GetEnabledCategories);
162188
registry->Register(SetTraceCategoryStateUpdateHandler);
189+
registry->Register(GetCategoryEnabledBuffer);
163190
registry->Register(NodeCategorySet::New);
164191
registry->Register(NodeCategorySet::Enable);
165192
registry->Register(NodeCategorySet::Disable);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
// Flags: --expose-internals
3+
4+
const common = require('../common');
5+
const { it } = require('node:test');
6+
7+
try {
8+
require('trace_events');
9+
} catch {
10+
common.skip('missing trace events');
11+
}
12+
13+
const { createTracing, getEnabledCategories } = require('trace_events');
14+
const assert = require('assert');
15+
16+
const binding = require('internal/test/binding');
17+
const getCategoryEnabledBuffer = binding.internalBinding('trace_events').getCategoryEnabledBuffer;
18+
19+
it('should track enabled/disabled categories', () => {
20+
const random = Math.random().toString().slice(2);
21+
const category = `node.${random}`;
22+
23+
const buffer = getCategoryEnabledBuffer(category);
24+
25+
const tracing = createTracing({
26+
categories: [category],
27+
});
28+
29+
assert.ok(buffer[0] === 0, `the buffer[0] should start with value 0, got: ${buffer[0]}`);
30+
31+
tracing.enable();
32+
33+
let currentCategories = getEnabledCategories();
34+
35+
assert.ok(currentCategories.includes(category), `the getEnabledCategories should include ${category}, got: ${currentCategories}`);
36+
assert.ok(buffer[0] > 0, `the buffer[0] should be greater than 0, got: ${buffer[0]}`);
37+
38+
tracing.disable();
39+
40+
currentCategories = getEnabledCategories();
41+
assert.ok(currentCategories === undefined, `the getEnabledCategories should return undefined, got: ${currentCategories}`);
42+
assert.ok(buffer[0] === 0, `the buffer[0] should be 0, got: ${buffer[0]}`);
43+
});

0 commit comments

Comments
 (0)