net: add new net.server.listen tracing channel

PR-URL: https://github.com/nodejs/node/pull/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>
This commit is contained in:
Paolo Insogna authored and GitHub committed 2024-05-30 08:40:19 +00:00
1 parent d953861daf
commit a837886561
3 files changed
+119 -13

No files matched your search

+21
View File
@@ -1131,6 +1131,26 @@ Emitted when a new TCP or pipe client socket is created.
Emitted when a new TCP or pipe connection is received.
`tracing:net.server.listen:asyncStart`
* `server` {net.Server}
* `options` {Object}
Emitted when [`net.Server.listen()`][] is invoked, before the port or pipe is actually setup.
`tracing:net.server.listen:asyncEnd`
* `server` {net.Server}
Emitted when [`net.Server.listen()`][] has completed and thus the server is ready to accept connection.
`tracing:net.server.listen:error`
* `server` {net.Server}
* `error` {Error}
Emitted when [`net.Server.listen()`][] is returning an error.
#### UDP
`udp.socket`
@@ -1179,5 +1199,6 @@ Emitted when a new thread is created.
[`diagnostics_channel.unsubscribe(name, onMessage)`]: #diagnostics_channelunsubscribename-onmessage
[`end` event]: #endevent
[`error` event]: #errorevent
[`net.Server.listen()`]: net.md#serverlisten
[`start` event]: #startevent
[context loss]: async_context.md#troubleshooting-context-loss
+19
View File
@@ -151,6 +151,7 @@ const kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext');
const dc = require('diagnostics_channel');
const netClientSocketChannel = dc.channel('net.client.socket');
const netServerSocketChannel = dc.channel('net.server.socket');
const netServerListen = dc.tracingChannel('net.server.listen');
const {
hasObserver,
@@ -1879,6 +1880,11 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
if (typeof rval === 'number') {
const error = new UVExceptionWithHostPort(rval, 'listen', address, port);
if (netServerListen.hasSubscribers) {
netServerListen.error.publish({ server: this, error });
}
process.nextTick(emitErrorNT, this, error);
return;
}
@@ -1898,6 +1904,11 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
const ex = new UVExceptionWithHostPort(err, 'listen', address, port);
this._handle.close();
this._handle = null;
if (netServerListen.hasSubscribers) {
netServerListen.error.publish({ server: this, error: ex });
}
defaultTriggerAsyncIdScope(this[async_id_symbol],
process.nextTick,
emitErrorNT,
@@ -1906,6 +1917,10 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
return;
}
if (netServerListen.hasSubscribers) {
netServerListen.asyncEnd.publish({ server: this });
}
// Generate connection key, this should be unique to the connection
this._connectionKey = addressType + ':' + address + ':' + port;
@@ -1993,6 +2008,10 @@ Server.prototype.listen = function(...args) {
throw new ERR_SERVER_ALREADY_LISTEN();
}
if (netServerListen.hasSubscribers) {
netServerListen.asyncStart.publish({ server: this, options });
}
if (cb !== null) {
this.once('listening', cb);
}
+79 -13
View File
@@ -5,21 +5,87 @@ const net = require('net');
const dc = require('diagnostics_channel');
const isNetSocket = (socket) => socket instanceof net.Socket;
const isNetServer = (server) => server instanceof net.Server;
dc.subscribe('net.client.socket', common.mustCall(({ socket }) => {
assert.strictEqual(isNetSocket(socket), true);
}));
function testDiagnosticChannel(subscribers, test, after) {
dc.tracingChannel('net.server.listen').subscribe(subscribers);
dc.subscribe('net.server.socket', common.mustCall(({ socket }) => {
assert.strictEqual(isNetSocket(socket), true);
}));
test(common.mustCall(() => {
dc.tracingChannel('net.server.listen').unsubscribe(subscribers);
after?.();
}));
}
const server = net.createServer(common.mustCall((socket) => {
socket.destroy();
server.close();
}));
const testSuccessfullListen = common.mustCall(() => {
let cb;
const server = net.createServer(common.mustCall((socket) => {
socket.destroy();
server.close();
cb();
}));
server.listen(() => {
const { port } = server.address();
net.connect(port);
dc.subscribe('net.client.socket', common.mustCall(({ socket }) => {
assert.strictEqual(isNetSocket(socket), true);
}));
dc.subscribe('net.server.socket', common.mustCall(({ socket }) => {
assert.strictEqual(isNetSocket(socket), true);
}));
testDiagnosticChannel(
{
asyncStart: common.mustCall(({ server: currentServer, options }) => {
assert.strictEqual(isNetServer(server), true);
assert.strictEqual(currentServer, server);
assert.strictEqual(options.customOption, true);
}),
asyncEnd: common.mustCall(({ server: currentServer }) => {
assert.strictEqual(isNetServer(server), true);
assert.strictEqual(currentServer, server);
}),
error: common.mustNotCall()
},
common.mustCall((callback) => {
cb = callback;
server.listen({ port: 0, customOption: true }, () => {
const { port } = server.address();
net.connect(port);
});
}),
testFailingListen
);
});
const testFailingListen = common.mustCall(() => {
const originalServer = net.createServer(common.mustNotCall());
originalServer.listen(() => {
const server = net.createServer(common.mustNotCall());
testDiagnosticChannel(
{
asyncStart: common.mustCall(({ server: currentServer, options }) => {
assert.strictEqual(isNetServer(server), true);
assert.strictEqual(currentServer, server);
assert.strictEqual(options.customOption, true);
}),
asyncEnd: common.mustNotCall(),
error: common.mustCall(({ server: currentServer }) => {
assert.strictEqual(isNetServer(server), true);
assert.strictEqual(currentServer, server);
}),
},
common.mustCall((callback) => {
server.on('error', () => {});
server.listen({ port: originalServer.address().port, customOption: true });
callback();
}),
common.mustCall(() => {
originalServer.close();
server.close();
})
);
});
});
testSuccessfullListen();