Skip to content

Commit 8362df0

Browse files
committed
ref: autoload tracing channels
1 parent 5ff5559 commit 8362df0

11 files changed

Lines changed: 148 additions & 375 deletions

File tree

integrationTests/diagnostics/test.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,7 @@ import assert from 'node:assert/strict';
66
import { AsyncLocalStorage } from 'node:async_hooks';
77
import dc from 'node:diagnostics_channel';
88

9-
import {
10-
buildSchema,
11-
enableDiagnosticsChannel,
12-
execute,
13-
parse,
14-
subscribe,
15-
validate,
16-
} from 'graphql';
17-
18-
enableDiagnosticsChannel(dc);
9+
import { buildSchema, execute, parse, subscribe, validate } from 'graphql';
1910

2011
function runParseCases() {
2112
// graphql:parse - synchronous.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* eslint-disable n/no-unsupported-features/node-builtins, import/no-nodejs-modules */
2+
import dc from 'node:diagnostics_channel';
3+
4+
import type { MinimalTracingChannel } from '../diagnostics.js';
5+
6+
export interface CollectedEvent {
7+
kind: 'start' | 'end' | 'asyncStart' | 'asyncEnd' | 'error';
8+
ctx: { [key: string]: unknown };
9+
}
10+
11+
/**
12+
* Subscribe to every lifecycle sub-channel on a TracingChannel and collect
13+
* events in order. Returns the event buffer plus an unsubscribe hook.
14+
*/
15+
export function collectEvents(channel: MinimalTracingChannel): {
16+
events: Array<CollectedEvent>;
17+
unsubscribe: () => void;
18+
} {
19+
const events: Array<CollectedEvent> = [];
20+
const handler = {
21+
start: (ctx: unknown) =>
22+
events.push({ kind: 'start', ctx: ctx as { [key: string]: unknown } }),
23+
end: (ctx: unknown) =>
24+
events.push({ kind: 'end', ctx: ctx as { [key: string]: unknown } }),
25+
asyncStart: (ctx: unknown) =>
26+
events.push({
27+
kind: 'asyncStart',
28+
ctx: ctx as { [key: string]: unknown },
29+
}),
30+
asyncEnd: (ctx: unknown) =>
31+
events.push({
32+
kind: 'asyncEnd',
33+
ctx: ctx as { [key: string]: unknown },
34+
}),
35+
error: (ctx: unknown) =>
36+
events.push({ kind: 'error', ctx: ctx as { [key: string]: unknown } }),
37+
};
38+
(channel as unknown as dc.TracingChannel).subscribe(handler);
39+
return {
40+
events,
41+
unsubscribe() {
42+
(channel as unknown as dc.TracingChannel).unsubscribe(handler);
43+
},
44+
};
45+
}
46+
47+
/**
48+
* Resolve a graphql tracing channel by name on the real
49+
* `node:diagnostics_channel`. graphql-js publishes on the same channels at
50+
* module load.
51+
*/
52+
export function getTracingChannel(name: string): MinimalTracingChannel {
53+
return dc.tracingChannel(name) as unknown as MinimalTracingChannel;
54+
}

src/__testUtils__/fakeDiagnosticsChannel.ts

Lines changed: 0 additions & 172 deletions
This file was deleted.

src/__tests__/diagnostics-test.ts

Lines changed: 19 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,31 @@
1+
/* eslint-disable import/no-nodejs-modules */
2+
import dc from 'node:diagnostics_channel';
3+
14
import { expect } from 'chai';
25
import { describe, it } from 'mocha';
36

4-
import { sharedFakeDc } from '../__testUtils__/fakeDiagnosticsChannel.js';
5-
67
import { invariant } from '../jsutils/invariant.js';
78

8-
import { enableDiagnosticsChannel, getChannels } from '../diagnostics.js';
9+
import { getChannels } from '../diagnostics.js';
910

1011
describe('diagnostics', () => {
11-
it('exposes the five graphql tracing channels after registration', () => {
12-
enableDiagnosticsChannel(sharedFakeDc);
13-
12+
it('auto-registers the five graphql tracing channels', () => {
1413
const channels = getChannels();
1514
invariant(channels !== undefined);
16-
expect(channels.execute).to.equal(
17-
sharedFakeDc.tracingChannel('graphql:execute'),
18-
);
19-
expect(channels.parse).to.equal(
20-
sharedFakeDc.tracingChannel('graphql:parse'),
21-
);
22-
expect(channels.validate).to.equal(
23-
sharedFakeDc.tracingChannel('graphql:validate'),
24-
);
25-
expect(channels.resolve).to.equal(
26-
sharedFakeDc.tracingChannel('graphql:resolve'),
27-
);
28-
expect(channels.subscribe).to.equal(
29-
sharedFakeDc.tracingChannel('graphql:subscribe'),
30-
);
31-
});
32-
33-
it('re-registration with the same module is a no-op', () => {
34-
enableDiagnosticsChannel(sharedFakeDc);
35-
const first = getChannels();
36-
invariant(first !== undefined);
37-
38-
enableDiagnosticsChannel(sharedFakeDc);
39-
const second = getChannels();
40-
41-
expect(second).to.equal(first);
42-
});
43-
44-
it('re-registration with a different module throws', () => {
45-
enableDiagnosticsChannel(sharedFakeDc);
46-
47-
expect(() =>
48-
enableDiagnosticsChannel({
49-
tracingChannel: () => {
50-
throw new Error('should not be called');
51-
},
52-
}),
53-
).to.throw(/different `diagnostics_channel` module/);
54-
});
55-
56-
it('re-registration accepts a wrapper sharing the same tracingChannel fn', () => {
57-
enableDiagnosticsChannel(sharedFakeDc);
58-
const first = getChannels();
59-
invariant(first !== undefined);
60-
61-
// Models an ESM Module Namespace object: distinct outer reference, but
62-
// the `tracingChannel` property is strictly the same function as the
63-
// default export's, so it routes to the same underlying channel cache.
64-
const namespaceLike = { tracingChannel: sharedFakeDc.tracingChannel };
65-
expect(namespaceLike).to.not.equal(sharedFakeDc);
66-
expect(namespaceLike.tracingChannel).to.equal(sharedFakeDc.tracingChannel);
6715

68-
expect(() => enableDiagnosticsChannel(namespaceLike)).to.not.throw();
69-
expect(getChannels()).to.equal(first);
16+
// Node's `tracingChannel(name)` returns a fresh wrapper per call but
17+
// the underlying sub-channels are cached by name, so compare those.
18+
const byName = {
19+
execute: 'graphql:execute',
20+
parse: 'graphql:parse',
21+
validate: 'graphql:validate',
22+
resolve: 'graphql:resolve',
23+
subscribe: 'graphql:subscribe',
24+
} as const;
25+
for (const [key, name] of Object.entries(byName)) {
26+
expect(channels[key as keyof typeof byName].start).to.equal(
27+
dc.channel(`tracing:${name}:start`),
28+
);
29+
}
7030
});
7131
});

0 commit comments

Comments
 (0)