Skip to content

Commit 064e449

Browse files
committed
add support for TracingChannel#hasSubscribers
1 parent cbf4222 commit 064e449

File tree

6 files changed

+121
-3
lines changed

6 files changed

+121
-3
lines changed

.github/workflows/pull-request.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ jobs:
7979
- 20.0.0 # first 20
8080
- 20.5.1 # sync unsubscribe bug
8181
- 20.6.0 # sync unsubscribe bug fixed
82-
- 20.x # nothing special, full support dc, latest 20
83-
- 21.0.0 # nothing special, full support dc, first 21
84-
- 21.x # nothing special, full support dc, latest 21
82+
- 20.x # nothing special, latest 20
83+
- 20.12.x # last version without TC early exit and TC#hasSubscribers()
84+
- 20.13.0 # introduces TC early exit and TC#hasSubscribers()
85+
- 21.0.0 # nothing special, first 21
86+
- 21.x # nothing special, latest 21
87+
- 22.0.0 # introduces TC early exit and TC#hasSubscribers()
88+
- 22.x # nothing special, full support DC
8589
steps:
8690
- uses: actions/checkout@v2
8791
- uses: actions/setup-node@v1

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Since this package recreates a Node.js API, read the [Node.js `diagnostics_chann
1313
| Oldest Supported Node.js Version | 12.17.0 |
1414
| Target Node.js DC API Version | 20.6.0 |
1515

16+
> Note that `dc-polyfill` currently has the `TracingChannel#hasSubscribers` getter backported from Node.js v22 however it doesn't yet support the tracing channel early exit feature. Once that's been added we'll delete this clause and update the above table.
17+
1618
Whenever the currently running version of Node.js ships with `diagnostics_channel` (i.e. v16+, v15.14+, v14.17+), **dc-polyfill** will make sure to use the global registry of channels provided by the core module. For older versions of Node.js **dc-polyfill** instead uses its own global collection of channels. This global collection remains in the same location and is shared across all instances of **dc-polyfill**. This avoids the issue wherein multiple versions of an npm library installed in a module dependency hierarchy would otherwise provide different singleton instances.
1719

1820
Ideally, this package will forever remain backwards compatible, there will never be a v2.x release, and there will never be an additional global channel collection.

checks.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,12 @@ function hasSyncUnsubscribeBug() {
5656
return MAJOR === 20 && MINOR <= 5;
5757
}
5858
module.exports.hasSyncUnsubscribeBug = hasSyncUnsubscribeBug;
59+
60+
// if there is a TracingChannel#hasSubscribers() method
61+
// @see https://github.com/nodejs/node/pull/51915
62+
// TODO: note that we still need to add the TC early exit from this same version
63+
function hasTracingChannelHasSubscribersMethod() {
64+
return MAJOR >= 22
65+
|| (MAJOR == 20 && MINOR >= 13);
66+
};
67+
module.exports.hasTracingChannelHasSubscribersMethod = hasTracingChannelHasSubscribersMethod;

dc-polyfill.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,9 @@ if (checks.hasSyncUnsubscribeBug()) {
3030
dc = require('./patch-sync-unsubscribe-bug.js')(dc);
3131
}
3232

33+
if (!checks.hasTracingChannelHasSubscribersMethod()) {
34+
dc = require('./patch-tracing-channel-has-subscribers.js')(dc);
35+
}
36+
3337
module.exports = dc;
3438

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const {
2+
ReflectApply,
3+
PromiseReject,
4+
PromiseResolve,
5+
PromisePrototypeThen,
6+
ArrayPrototypeSplice,
7+
ArrayPrototypeAt,
8+
} = require('./primordials.js');
9+
10+
const { ERR_INVALID_ARG_TYPE } = require('./errors.js');
11+
12+
const traceEvents = [
13+
'start',
14+
'end',
15+
'asyncStart',
16+
'asyncEnd',
17+
'error',
18+
];
19+
20+
module.exports = function (unpatched) {
21+
const { channel } = unpatched;
22+
23+
const dc = { ...unpatched };
24+
25+
const tracingChannel = dc.tracingChannel;
26+
27+
dc.tracingChannel = function() {
28+
const tc = tracingChannel(...arguments);
29+
30+
Object.defineProperty(tc, 'hasSubscribers', { // TODO: on prototype?
31+
get: function () {
32+
return this.start.hasSubscribers
33+
|| this.end.hasSubscribers
34+
|| this.asyncStart.hasSubscribers
35+
|| this.asyncEnd.hasSubscribers
36+
|| this.error.hasSubscribers;
37+
}
38+
});
39+
40+
return tc;
41+
};
42+
43+
return dc;
44+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
const test = require('tape');
4+
const common = require('./common.js');
5+
const dc = require('../dc-polyfill.js');
6+
7+
test('test-diagnostics-channel-tracing-has-subscribers', (t) => {
8+
t.plan(10);
9+
10+
const handler = common.mustNotCall();
11+
12+
{
13+
const handlers = {
14+
start: common.mustNotCall()
15+
};
16+
17+
const channel = dc.tracingChannel('test');
18+
19+
t.strictEqual(channel.hasSubscribers, false);
20+
21+
channel.subscribe(handlers);
22+
t.strictEqual(channel.hasSubscribers, true);
23+
24+
channel.unsubscribe(handlers);
25+
t.strictEqual(channel.hasSubscribers, false);
26+
27+
channel.start.subscribe(handler);
28+
t.strictEqual(channel.hasSubscribers, true);
29+
30+
channel.start.unsubscribe(handler);
31+
t.strictEqual(channel.hasSubscribers, false);
32+
}
33+
34+
{
35+
const handlers = {
36+
asyncEnd: common.mustNotCall()
37+
};
38+
39+
const channel = dc.tracingChannel('test');
40+
41+
t.strictEqual(channel.hasSubscribers, false);
42+
43+
channel.subscribe(handlers);
44+
t.strictEqual(channel.hasSubscribers, true);
45+
46+
channel.unsubscribe(handlers);
47+
t.strictEqual(channel.hasSubscribers, false);
48+
49+
channel.asyncEnd.subscribe(handler);
50+
t.strictEqual(channel.hasSubscribers, true);
51+
52+
channel.asyncEnd.unsubscribe(handler);
53+
t.strictEqual(channel.hasSubscribers, false);
54+
}
55+
});

0 commit comments

Comments
 (0)