Michael
Michael

Reputation: 433

NodeJs: How to handle a very high amount of timers?

I am using socket.io to send packets via websockets. They seem to disappear from time to time. So I have to implement some sort of acknowledge-system. My Idea was to immediatelly respond to a packet with an ACK-packet. If the server does not receive this ACK-packet within a given time, he will resend it (up to 3 times, then disconnect the socket).

My first thought was to start a timer (setTimeout) after sending a packet. if the timeout-event occurs, the packet has to be sent again. If the ACK will arrive, the timeout will get deleted. Quite easy and short.

var io = require('socket.io').listen(80);

// ... connection handling ...

function sendData(someData, socket) {
  // TODO: Some kind of counter to stop after 3 tries.
  socket.emit("someEvent", someData);
  var timeout = setTimeout(function(){ sendData(someData, socket); }, 2000);
  socket.on("ack", function(){
    // Everything went ok.
    clearTimeout(timeout);
  });
}

But I will have 1k-3k clients connected with much traffic. I can't imagine, that 10k timers running at the same time are handlable by NodeJS. Even worse: I read that NodeJS will not fire the event if there is no time for it.

How to implement a good working and efficient packet acknowledge system?

Upvotes: 2

Views: 3025

Answers (2)

Andrzej Szombierski
Andrzej Szombierski

Reputation: 349

I read that NodeJS will not fire the event if there is no time for it.

This is a bit of an exaggeration, node.js timers are reliable. A timer set by setTimeout will fire at some point. It may be delayed if the process is busy at the exact scheduled time, but the callback will be called eventually.

Quoted from Node.js docs for setTimeout:

The callback will likely not be invoked in precisely delay milliseconds. Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. The callback will be called as close as possible to the time specified.

Upvotes: 1

arghbleargh
arghbleargh

Reputation: 3160

If socket.io is not reliable enough for you, you might want to consider implementing your own websocket interface instead of adding a layer on top of socket.io. But to answer your question, I don't think running 10k timers is going to be a big deal. For example, the following code ran in under 3 seconds for me and printed out the expected result of 100000:

var x = 0;
for (var i = 0; i < 100000; i++) {
    setTimeout(function() { x++; }, 1000);
}

setTimeout(function() { console.log(x); }, 2000);

There isn't actually that much overhead for a timeout; it essentially just gets put in a queue until it's time to execute it.

Upvotes: 3

Related Questions