Skip to content
This repository

Maximum call stack size exceeded #143

Closed
MSNexploder opened this Issue September 26, 2011 · 6 comments

3 participants

Stefan Huber Eric Zhang Steve Wang
Stefan Huber

The following code dies using node v0.4.12.
I was able to track down the problem within the nowUtil.extend function, which gets recursively for deeply nested objects until stack size exceeds. More precisely it looks like it couldn't handle circular references properly.

But I couldn't come up with a not too hacky solution for this.

var io = require('socket.io');
var now = require('now');
var express = require('express');

var server = express.createServer();
var store = new io.RedisStore();

var everyone = now.initialize(server, {socketio: {store: store}});
// => RangeError: Maximum call stack size exceeded
Eric Zhang

Indeed the extend function doesn't currently handle circular references correctly causing the error. Not sure if we're going to fix this atm

Steve Wang

Eric -- as a quick fix (and the least hacky method -- decycle / retrocycle is not really a good option), would you consider changing it such that nowjs.initialize modifies the input object, as opposed to the default settings object (how I believe things are currently done)?

I haven't looked at the code in some time, but this might be as simple as reversing the order of the arguments to nowUtil.extend.

edit: it's slightly more complicated. I think the fix would be to change nowUtil.extend(this.options, options); to this.options = nowUtil.extend(options, this.options);.

Eric Zhang

Yeahhh you want the defaults to be overwritten so it has to extend into this.options or extra memory will be used

Steve Wang

Erm, all right, it's not as simple as this, but the main idea is there. You'd actually want to use a slight variant of extend that only adds fields if they didn't already exist in the target.

I think it might be something like the following:

function recurse(source, dest) {
  for (var i in source) {
    if (source[i] && typeof source[i] === 'object') {
      if (!dest[i] || typeof dest[i] !== 'object') {
        dest[i] = Array.isArray(source[i]) ? [] : {};
      }
      recurse(source[i], dest[i]);
    }
    else if (dest[i] === undefined) {
      dest[i] = source[i];
    }
  }
}

Also, sorry, I don't follow -- does it really use more memory if you extend into the other object, then overwrite this.options?

Eric Zhang
Eric Zhang ericz referenced this issue from a commit October 04, 2011
Eric Zhang #143 extend optimization a043fb1
Eric Zhang

Fixed

Eric Zhang ericz closed this October 04, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.