Description
Version
v16.16.0 (standalone), v16.14.2 (running within Electron 19.0.0)
Platform
Windows 11 (Microsoft Windows NT 10.0.22000.0 x64)
Subsystem
dgram
What steps will reproduce the bug?
const dgram = require('dgram');
let loopIterations = 0;
let callback;
callback = () => {
loopIterations += 1;
//nested setImmediate calls fire once per event loop
setImmediate(callback);
};
let udp = dgram.createSocket({ type: 'udp4' });
udp.on('message', (data, rinfo) => {
console.log(loopIterations);
});
const PORT = 17654;
udp.bind(PORT, () => {
udp.connect(PORT, () => {
udp.setSendBufferSize(1024 * 1024);
udp.setRecvBufferSize(1024 * 1024);
setImmediate(callback);
//once per second, send a large number of UDP packets to our socket
setInterval(() => {
for (let i=0; i<16 * 1024; i++) {
udp.send(" ");
}
}, 1000);
});
});
How often does it reproduce? Is there a required condition?
This bug reproduces unconditionally on Windows, but does not seem to reproduce on Linux.
What is the expected behavior?
When multiple UDP datagrams are available, several of them should be presented to the 'message'
callback within each event loop iteration. (This is the behaviour on Linux.) The test program should print the same integer multiple times in a row.
What do you see instead?
The same integer is never printed twice. Consecutive integers are printed (308, 309, 310...). This indicates that only one UDP datagram is delivered per event loop iteration, even when more datagrams are present in the socket's receive buffer.
Additional information
This bug seems inconsequential on a standalone Node installation. On my machine, the Node event loop has a throughput approaching 1,000,000 iterations per second. Assuming 1024 bytes per datagram, the event loop can deliver 8 Gbps of data.
However, in Electron, the Node event loop is much slower (presumably due to coordination with Chromium's event loop). On my machine, a typical throughput would be 20,000 to 40,000 iterations per second, intermittently dipping below 10,000 iterations per second.
This introduces a significant network bottleneck: the highest safe data rate, even through a local socket, is about 0.08 Gbps. At lower data rates, the bug still introduces up to 100ms of transfer latency per megabyte of data.