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 7d37dcd

Browse filesBrowse files
Stephen BelangerRafaelGSS
authored andcommitted
lib: add tracing channel to diagnostics_channel
PR-URL: #44943 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Bryan English <bryan@bryanenglish.com>
1 parent cbb3627 commit 7d37dcd
Copy full SHA for 7d37dcd
Expand file treeCollapse file tree

13 files changed

+1309
-35
lines changed
Open diff view settings
Collapse file

‎doc/api/diagnostics_channel.md‎

Copy file name to clipboardExpand all lines: doc/api/diagnostics_channel.md
+647Lines changed: 647 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Large diffs are not rendered by default.
Collapse file

‎lib/diagnostics_channel.js‎

Copy file name to clipboardExpand all lines: lib/diagnostics_channel.js
+282-25Lines changed: 282 additions & 25 deletions
Large diffs are not rendered by default.
Collapse file

‎src/node_util.cc‎

Copy file name to clipboardExpand all lines: src/node_util.cc
+4-9Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,18 +262,13 @@ void WeakReference::Get(const FunctionCallbackInfo<Value>& args) {
262262
args.GetReturnValue().Set(weak_ref->target_.Get(isolate));
263263
}
264264

265-
void WeakReference::GetRef(const FunctionCallbackInfo<Value>& args) {
266-
WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
267-
Isolate* isolate = args.GetIsolate();
268-
args.GetReturnValue().Set(
269-
v8::Number::New(isolate, weak_ref->reference_count_));
270-
}
271-
272265
void WeakReference::IncRef(const FunctionCallbackInfo<Value>& args) {
273266
WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
274267
weak_ref->reference_count_++;
275268
if (weak_ref->target_.IsEmpty()) return;
276269
if (weak_ref->reference_count_ == 1) weak_ref->target_.ClearWeak();
270+
args.GetReturnValue().Set(
271+
v8::Number::New(args.GetIsolate(), weak_ref->reference_count_));
277272
}
278273

279274
void WeakReference::DecRef(const FunctionCallbackInfo<Value>& args) {
@@ -282,6 +277,8 @@ void WeakReference::DecRef(const FunctionCallbackInfo<Value>& args) {
282277
weak_ref->reference_count_--;
283278
if (weak_ref->target_.IsEmpty()) return;
284279
if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak();
280+
args.GetReturnValue().Set(
281+
v8::Number::New(args.GetIsolate(), weak_ref->reference_count_));
285282
}
286283

287284
static void GuessHandleType(const FunctionCallbackInfo<Value>& args) {
@@ -365,7 +362,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
365362
registry->Register(ArrayBufferViewHasBuffer);
366363
registry->Register(WeakReference::New);
367364
registry->Register(WeakReference::Get);
368-
registry->Register(WeakReference::GetRef);
369365
registry->Register(WeakReference::IncRef);
370366
registry->Register(WeakReference::DecRef);
371367
registry->Register(GuessHandleType);
@@ -457,7 +453,6 @@ void Initialize(Local<Object> target,
457453
WeakReference::kInternalFieldCount);
458454
weak_ref->Inherit(BaseObject::GetConstructorTemplate(env));
459455
SetProtoMethod(isolate, weak_ref, "get", WeakReference::Get);
460-
SetProtoMethod(isolate, weak_ref, "getRef", WeakReference::GetRef);
461456
SetProtoMethod(isolate, weak_ref, "incRef", WeakReference::IncRef);
462457
SetProtoMethod(isolate, weak_ref, "decRef", WeakReference::DecRef);
463458
SetConstructorFunction(context, target, "WeakReference", weak_ref);
Collapse file

‎src/node_util.h‎

Copy file name to clipboardExpand all lines: src/node_util.h
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class WeakReference : public SnapshotableObject {
2121
v8::Local<v8::Object> target);
2222
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
2323
static void Get(const v8::FunctionCallbackInfo<v8::Value>& args);
24-
static void GetRef(const v8::FunctionCallbackInfo<v8::Value>& args);
2524
static void IncRef(const v8::FunctionCallbackInfo<v8::Value>& args);
2625
static void DecRef(const v8::FunctionCallbackInfo<v8::Value>& args);
2726

Collapse file
+108Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const dc = require('diagnostics_channel');
6+
const { AsyncLocalStorage } = require('async_hooks');
7+
8+
let n = 0;
9+
const thisArg = new Date();
10+
const inputs = [
11+
{ foo: 'bar' },
12+
{ baz: 'buz' },
13+
];
14+
15+
const channel = dc.channel('test');
16+
17+
// Bind a storage directly to published data
18+
const store1 = new AsyncLocalStorage();
19+
channel.bindStore(store1);
20+
let store1bound = true;
21+
22+
// Bind a store with transformation of published data
23+
const store2 = new AsyncLocalStorage();
24+
channel.bindStore(store2, common.mustCall((data) => {
25+
assert.strictEqual(data, inputs[n]);
26+
return { data };
27+
}, 4));
28+
29+
// Regular subscribers should see publishes from runStores calls
30+
channel.subscribe(common.mustCall((data) => {
31+
if (store1bound) {
32+
assert.deepStrictEqual(data, store1.getStore());
33+
}
34+
assert.deepStrictEqual({ data }, store2.getStore());
35+
assert.strictEqual(data, inputs[n]);
36+
}, 4));
37+
38+
// Verify stores are empty before run
39+
assert.strictEqual(store1.getStore(), undefined);
40+
assert.strictEqual(store2.getStore(), undefined);
41+
42+
channel.runStores(inputs[n], common.mustCall(function(a, b) {
43+
// Verify this and argument forwarding
44+
assert.strictEqual(this, thisArg);
45+
assert.strictEqual(a, 1);
46+
assert.strictEqual(b, 2);
47+
48+
// Verify store 1 state matches input
49+
assert.strictEqual(store1.getStore(), inputs[n]);
50+
51+
// Verify store 2 state has expected transformation
52+
assert.deepStrictEqual(store2.getStore(), { data: inputs[n] });
53+
54+
// Should support nested contexts
55+
n++;
56+
channel.runStores(inputs[n], common.mustCall(function() {
57+
// Verify this and argument forwarding
58+
assert.strictEqual(this, undefined);
59+
60+
// Verify store 1 state matches input
61+
assert.strictEqual(store1.getStore(), inputs[n]);
62+
63+
// Verify store 2 state has expected transformation
64+
assert.deepStrictEqual(store2.getStore(), { data: inputs[n] });
65+
}));
66+
n--;
67+
68+
// Verify store 1 state matches input
69+
assert.strictEqual(store1.getStore(), inputs[n]);
70+
71+
// Verify store 2 state has expected transformation
72+
assert.deepStrictEqual(store2.getStore(), { data: inputs[n] });
73+
}), thisArg, 1, 2);
74+
75+
// Verify stores are empty after run
76+
assert.strictEqual(store1.getStore(), undefined);
77+
assert.strictEqual(store2.getStore(), undefined);
78+
79+
// Verify unbinding works
80+
assert.ok(channel.unbindStore(store1));
81+
store1bound = false;
82+
83+
// Verify unbinding a store that is not bound returns false
84+
assert.ok(!channel.unbindStore(store1));
85+
86+
n++;
87+
channel.runStores(inputs[n], common.mustCall(() => {
88+
// Verify after unbinding store 1 will remain undefined
89+
assert.strictEqual(store1.getStore(), undefined);
90+
91+
// Verify still bound store 2 receives expected data
92+
assert.deepStrictEqual(store2.getStore(), { data: inputs[n] });
93+
}));
94+
95+
// Contain transformer errors and emit on next tick
96+
const fail = new Error('fail');
97+
channel.bindStore(store1, () => {
98+
throw fail;
99+
});
100+
101+
let calledRunStores = false;
102+
process.once('uncaughtException', common.mustCall((err) => {
103+
assert.strictEqual(calledRunStores, true);
104+
assert.strictEqual(err, fail);
105+
}));
106+
107+
channel.runStores(inputs[n], common.mustCall());
108+
calledRunStores = true;
Collapse file
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const dc = require('diagnostics_channel');
5+
const assert = require('assert');
6+
7+
const channel = dc.tracingChannel('test');
8+
9+
const expectedError = new Error('test');
10+
const input = { foo: 'bar' };
11+
const thisArg = { baz: 'buz' };
12+
13+
function check(found) {
14+
assert.deepStrictEqual(found, input);
15+
}
16+
17+
const handlers = {
18+
start: common.mustCall(check, 2),
19+
end: common.mustCall(check, 2),
20+
asyncStart: common.mustCall(check, 2),
21+
asyncEnd: common.mustCall(check, 2),
22+
error: common.mustCall((found) => {
23+
check(found);
24+
assert.deepStrictEqual(found.error, expectedError);
25+
}, 2)
26+
};
27+
28+
channel.subscribe(handlers);
29+
30+
channel.traceCallback(function(cb, err) {
31+
assert.deepStrictEqual(this, thisArg);
32+
setImmediate(cb, err);
33+
}, 0, input, thisArg, common.mustCall((err, res) => {
34+
assert.strictEqual(err, expectedError);
35+
assert.strictEqual(res, undefined);
36+
}), expectedError);
37+
38+
channel.tracePromise(function(value) {
39+
assert.deepStrictEqual(this, thisArg);
40+
return Promise.reject(value);
41+
}, input, thisArg, expectedError).then(
42+
common.mustNotCall(),
43+
common.mustCall((value) => {
44+
assert.deepStrictEqual(value, expectedError);
45+
})
46+
);
Collapse file
+60Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const dc = require('diagnostics_channel');
5+
const assert = require('assert');
6+
7+
const channel = dc.tracingChannel('test');
8+
9+
const expectedResult = { foo: 'bar' };
10+
const input = { foo: 'bar' };
11+
const thisArg = { baz: 'buz' };
12+
13+
function check(found) {
14+
assert.deepStrictEqual(found, input);
15+
}
16+
17+
const handlers = {
18+
start: common.mustCall(check, 2),
19+
end: common.mustCall(check, 2),
20+
asyncStart: common.mustCall((found) => {
21+
check(found);
22+
assert.strictEqual(found.error, undefined);
23+
assert.deepStrictEqual(found.result, expectedResult);
24+
}, 2),
25+
asyncEnd: common.mustCall((found) => {
26+
check(found);
27+
assert.strictEqual(found.error, undefined);
28+
assert.deepStrictEqual(found.result, expectedResult);
29+
}, 2),
30+
error: common.mustNotCall()
31+
};
32+
33+
channel.subscribe(handlers);
34+
35+
channel.traceCallback(function(cb, err, res) {
36+
assert.deepStrictEqual(this, thisArg);
37+
setImmediate(cb, err, res);
38+
}, 0, input, thisArg, common.mustCall((err, res) => {
39+
assert.strictEqual(err, null);
40+
assert.deepStrictEqual(res, expectedResult);
41+
}), null, expectedResult);
42+
43+
channel.tracePromise(function(value) {
44+
assert.deepStrictEqual(this, thisArg);
45+
return Promise.resolve(value);
46+
}, input, thisArg, expectedResult).then(
47+
common.mustCall((value) => {
48+
assert.deepStrictEqual(value, expectedResult);
49+
}),
50+
common.mustNotCall()
51+
);
52+
53+
let failed = false;
54+
try {
55+
channel.traceCallback(common.mustNotCall(), 0, input, thisArg, 1, 2, 3);
56+
} catch (err) {
57+
assert.ok(/"callback" argument must be of type function/.test(err.message));
58+
failed = true;
59+
}
60+
assert.strictEqual(failed, true);
Collapse file
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const { AsyncLocalStorage } = require('async_hooks');
5+
const dc = require('diagnostics_channel');
6+
const assert = require('assert');
7+
8+
const channel = dc.tracingChannel('test');
9+
const store = new AsyncLocalStorage();
10+
11+
const firstContext = { foo: 'bar' };
12+
const secondContext = { baz: 'buz' };
13+
14+
channel.start.bindStore(store, common.mustCall(() => {
15+
return firstContext;
16+
}));
17+
18+
channel.asyncStart.bindStore(store, common.mustCall(() => {
19+
return secondContext;
20+
}));
21+
22+
assert.strictEqual(store.getStore(), undefined);
23+
channel.traceCallback(common.mustCall((cb) => {
24+
assert.deepStrictEqual(store.getStore(), firstContext);
25+
setImmediate(cb);
26+
}), 0, {}, null, common.mustCall(() => {
27+
assert.deepStrictEqual(store.getStore(), secondContext);
28+
}));
29+
assert.strictEqual(store.getStore(), undefined);
Collapse file
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const { setTimeout } = require('node:timers/promises');
5+
const { AsyncLocalStorage } = require('async_hooks');
6+
const dc = require('diagnostics_channel');
7+
const assert = require('assert');
8+
9+
const channel = dc.tracingChannel('test');
10+
const store = new AsyncLocalStorage();
11+
12+
const context = { foo: 'bar' };
13+
14+
channel.start.bindStore(store, common.mustCall(() => {
15+
return context;
16+
}));
17+
18+
assert.strictEqual(store.getStore(), undefined);
19+
channel.tracePromise(common.mustCall(async () => {
20+
assert.deepStrictEqual(store.getStore(), context);
21+
await setTimeout(1);
22+
assert.deepStrictEqual(store.getStore(), context);
23+
}));
24+
assert.strictEqual(store.getStore(), undefined);
Collapse file
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const { AsyncLocalStorage } = require('async_hooks');
5+
const dc = require('diagnostics_channel');
6+
const assert = require('assert');
7+
8+
const channel = dc.tracingChannel('test');
9+
const store = new AsyncLocalStorage();
10+
11+
const context = { foo: 'bar' };
12+
13+
channel.start.bindStore(store, common.mustCall(() => {
14+
return context;
15+
}));
16+
17+
assert.strictEqual(store.getStore(), undefined);
18+
channel.traceSync(common.mustCall(() => {
19+
assert.deepStrictEqual(store.getStore(), context);
20+
}));
21+
assert.strictEqual(store.getStore(), undefined);

0 commit comments

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