I am observing a significant data-lost on a UDP connection with node.js 0.6.18> and 0.8.0 . It appears at high packet rates about 1200 packet per second with frames about 1500 byte limit. Each data packages has a incrementing number so it easy to track the number of lost packages.
var server = dgram.createSocket("udp4");
server.on("message", function (message, rinfo) {
//~processData(message);
//~ writeData(message, null, 5000);
}).bind(10001);
On the receiving callback I tested two cases I first saved 5000 packages in a file. The result ware no dropped packages. After I have included a data processing routine and got about 50% drop rate. What I expected was that the process data routine should be completely asynchronous and should not introduce dead time to the system, since it is a simple parser to process binary data in the package and to emits events to a further processing routine.
It seems that the parsing routine introduce dead time in which the event handler is unable to handle each packets.
At the low package rates (< 1200 packages/sec) there are no data lost observed! Is this a bug or I am doing something wrong?
Node.js runs as a single threaded system. While you are doing your processing you process is unable to receive data and network data will queue up until OS buffers are full and then packets will get dropped. There are many ways to handle this, but typically you will have one set of processes that receives (and queues) data, while another set of processes will do your processing WITHOUT delaying the receiving processes. There are probably lots of modules to help you architect this, but I'll leave that to the experts... ;-)
I've bumped into a similar issue with statsd which also uses node.js udp. If you're running on linux, changing the receive buffers seems to improve things considerably to avoid drops.
Specifically, you can run something like
sudo sysctl -w net.core.rmem_default=20971520
see this statsd github issue for more info.