0

I have a function that is recursive in framing tcp stream. But when I reach around 1000+ packets received per second I suddenly get Max call stack exceeded or something along those lines.

My code is:

  var expectedRemaining = (this.expectedSz - this.receivedSz);

  if (buff.length > expectedRemaining) {
    var tmp = buff.slice(0, expectedRemaining);
    buff = buff.slice(expectedRemaining);

    recurse = true;
    this.inPacket.push(tmp);
    this.receivedSz = this.expectedSz;
  } else {
    this.inPacket.push(buff);
    this.receivedSz += buff.length;
  }

  if (this.receivedSz === this.expectedSz) {
    this.emit('data', Buffer.concat( this.inPacket, this.expectedSz));
    this.reset();
  }

  if (recurse) this.handleData(buff);

Any suggestions?

majidarif
  • 18,694
  • 16
  • 88
  • 133
  • Instead of making this recursive, you could use a `setImmediate` call to allow the stack frame to pop and events to fire before coming back to your `handleData` function. – Austin Mullins Feb 13 '15 at 23:21
  • @AustinMullins how would that be? Can I just wrap the calling of `handleData` in a `setImmediate` callback? – majidarif Feb 13 '15 at 23:21

1 Answers1

1

Right now, your function looks something like this (psuedocode):

this.handleData = function handleData(buf) {
   if ( someCondition ) {
      // do stuff
      recurse = true;
   }
   else {
      // do other stuff
   }

   if (recurse) {
       this.handleData(buf);
   }
};

What I'm suggesting is that you implement the recursive behavior with a setImmediate call. This will allow the stack frame to be cleared and the data event to be emitted before entering your function again.

this.handleData = function handleData(buf) {
   if ( someCondition ) {
      // do stuff
      recurse = true;
   }
   else {
      // do other stuff
   }

   if (recurse) {
       setImmediate(function() {
           this.handleData(buf);
       });
   }
};

Just in case people don't read the comments, for the application described in the original question, nextTick ended up being a better fit. The main difference is that nextTick guarantees that the given function will execute before any queued events.

Austin Mullins
  • 7,307
  • 2
  • 33
  • 48