Skip to content

Commit f3ba1eb

Browse files
ShogunPandamarco-ippolito
authored andcommitted
net: add new net.server.listen tracing channel
PR-URL: #53136 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
1 parent 1e57c67 commit f3ba1eb

File tree

3 files changed

+119
-13
lines changed

3 files changed

+119
-13
lines changed

doc/api/diagnostics_channel.md

+21
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,26 @@ Emitted when a new TCP or pipe client socket is created.
11211121

11221122
Emitted when a new TCP or pipe connection is received.
11231123

1124+
`tracing:net.server.listen:asyncStart`
1125+
1126+
* `server` {net.Server}
1127+
* `options` {Object}
1128+
1129+
Emitted when [`net.Server.listen()`][] is invoked, before the port or pipe is actually setup.
1130+
1131+
`tracing:net.server.listen:asyncEnd`
1132+
1133+
* `server` {net.Server}
1134+
1135+
Emitted when [`net.Server.listen()`][] has completed and thus the server is ready to accept connection.
1136+
1137+
`tracing:net.server.listen:error`
1138+
1139+
* `server` {net.Server}
1140+
* `error` {Error}
1141+
1142+
Emitted when [`net.Server.listen()`][] is returning an error.
1143+
11241144
#### UDP
11251145

11261146
`udp.socket`
@@ -1169,5 +1189,6 @@ Emitted when a new thread is created.
11691189
[`diagnostics_channel.unsubscribe(name, onMessage)`]: #diagnostics_channelunsubscribename-onmessage
11701190
[`end` event]: #endevent
11711191
[`error` event]: #errorevent
1192+
[`net.Server.listen()`]: net.md#serverlisten
11721193
[`start` event]: #startevent
11731194
[context loss]: async_context.md#troubleshooting-context-loss

lib/net.js

+19
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ const kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext');
151151
const dc = require('diagnostics_channel');
152152
const netClientSocketChannel = dc.channel('net.client.socket');
153153
const netServerSocketChannel = dc.channel('net.server.socket');
154+
const netServerListen = dc.tracingChannel('net.server.listen');
154155

155156
const {
156157
hasObserver,
@@ -1879,6 +1880,11 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
18791880

18801881
if (typeof rval === 'number') {
18811882
const error = new UVExceptionWithHostPort(rval, 'listen', address, port);
1883+
1884+
if (netServerListen.hasSubscribers) {
1885+
netServerListen.error.publish({ server: this, error });
1886+
}
1887+
18821888
process.nextTick(emitErrorNT, this, error);
18831889
return;
18841890
}
@@ -1898,6 +1904,11 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
18981904
const ex = new UVExceptionWithHostPort(err, 'listen', address, port);
18991905
this._handle.close();
19001906
this._handle = null;
1907+
1908+
if (netServerListen.hasSubscribers) {
1909+
netServerListen.error.publish({ server: this, error: ex });
1910+
}
1911+
19011912
defaultTriggerAsyncIdScope(this[async_id_symbol],
19021913
process.nextTick,
19031914
emitErrorNT,
@@ -1906,6 +1917,10 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
19061917
return;
19071918
}
19081919

1920+
if (netServerListen.hasSubscribers) {
1921+
netServerListen.asyncEnd.publish({ server: this });
1922+
}
1923+
19091924
// Generate connection key, this should be unique to the connection
19101925
this._connectionKey = addressType + ':' + address + ':' + port;
19111926

@@ -1993,6 +2008,10 @@ Server.prototype.listen = function(...args) {
19932008
throw new ERR_SERVER_ALREADY_LISTEN();
19942009
}
19952010

2011+
if (netServerListen.hasSubscribers) {
2012+
netServerListen.asyncStart.publish({ server: this, options });
2013+
}
2014+
19962015
if (cb !== null) {
19972016
this.once('listening', cb);
19982017
}

test/parallel/test-diagnostics-channel-net.js

+79-13
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,87 @@ const net = require('net');
55
const dc = require('diagnostics_channel');
66

77
const isNetSocket = (socket) => socket instanceof net.Socket;
8+
const isNetServer = (server) => server instanceof net.Server;
89

9-
dc.subscribe('net.client.socket', common.mustCall(({ socket }) => {
10-
assert.strictEqual(isNetSocket(socket), true);
11-
}));
10+
function testDiagnosticChannel(subscribers, test, after) {
11+
dc.tracingChannel('net.server.listen').subscribe(subscribers);
1212

13-
dc.subscribe('net.server.socket', common.mustCall(({ socket }) => {
14-
assert.strictEqual(isNetSocket(socket), true);
15-
}));
13+
test(common.mustCall(() => {
14+
dc.tracingChannel('net.server.listen').unsubscribe(subscribers);
15+
after?.();
16+
}));
17+
}
1618

17-
const server = net.createServer(common.mustCall((socket) => {
18-
socket.destroy();
19-
server.close();
20-
}));
19+
const testSuccessfullListen = common.mustCall(() => {
20+
let cb;
21+
const server = net.createServer(common.mustCall((socket) => {
22+
socket.destroy();
23+
server.close();
24+
cb();
25+
}));
2126

22-
server.listen(() => {
23-
const { port } = server.address();
24-
net.connect(port);
27+
dc.subscribe('net.client.socket', common.mustCall(({ socket }) => {
28+
assert.strictEqual(isNetSocket(socket), true);
29+
}));
30+
31+
dc.subscribe('net.server.socket', common.mustCall(({ socket }) => {
32+
assert.strictEqual(isNetSocket(socket), true);
33+
}));
34+
35+
testDiagnosticChannel(
36+
{
37+
asyncStart: common.mustCall(({ server: currentServer, options }) => {
38+
assert.strictEqual(isNetServer(server), true);
39+
assert.strictEqual(currentServer, server);
40+
assert.strictEqual(options.customOption, true);
41+
}),
42+
asyncEnd: common.mustCall(({ server: currentServer }) => {
43+
assert.strictEqual(isNetServer(server), true);
44+
assert.strictEqual(currentServer, server);
45+
}),
46+
error: common.mustNotCall()
47+
},
48+
common.mustCall((callback) => {
49+
cb = callback;
50+
server.listen({ port: 0, customOption: true }, () => {
51+
const { port } = server.address();
52+
net.connect(port);
53+
});
54+
}),
55+
testFailingListen
56+
);
2557
});
58+
59+
const testFailingListen = common.mustCall(() => {
60+
const originalServer = net.createServer(common.mustNotCall());
61+
62+
originalServer.listen(() => {
63+
const server = net.createServer(common.mustNotCall());
64+
65+
testDiagnosticChannel(
66+
{
67+
asyncStart: common.mustCall(({ server: currentServer, options }) => {
68+
assert.strictEqual(isNetServer(server), true);
69+
assert.strictEqual(currentServer, server);
70+
assert.strictEqual(options.customOption, true);
71+
}),
72+
asyncEnd: common.mustNotCall(),
73+
error: common.mustCall(({ server: currentServer }) => {
74+
assert.strictEqual(isNetServer(server), true);
75+
assert.strictEqual(currentServer, server);
76+
}),
77+
},
78+
common.mustCall((callback) => {
79+
server.on('error', () => {});
80+
server.listen({ port: originalServer.address().port, customOption: true });
81+
callback();
82+
}),
83+
common.mustCall(() => {
84+
originalServer.close();
85+
server.close();
86+
})
87+
);
88+
});
89+
});
90+
91+
testSuccessfullListen();

0 commit comments

Comments
 (0)