Rob Wilkerson
Rob Wilkerson

Reputation: 41256

Node JS Memory Leak?

I have a Node app (v0.8.26) running on Express (v3.4.8). In that app I have a route that sends an array of objects in the response body. What I'm finding is that doing so immediately begins spinning up the Node memory usage and before long everything shuts down. I'm getting a little desperate so I'm hoping someone can help (quickly).

Here's my route:

get_products: function(req, res) {
  var san = req.params.san;

  // Authenticate and then retrieve
  client.login(datasources.api.auth.sourceId, datasources.api.auth.password, function(err, authToken) {
    if (err) {
      return res.send(401, err);
    }

    client.getProducts(token, san, function(err, products) {
      if (err) {
        var httpStatus = err.httpStatus || 500;

        if (httpStatus === 500) {
          console.trace(err);
        }

        return res.send(httpStatus, err.message);
      }

      if (products) {
        return products.length > 0
          ? res.send(200, products)  // <--- ERROR OCCURS HERE
          : res.send(200, []);
      }
      else {
        return res.send(403, 'Purchase is not allowed at this time.');
      }
    });
  });
},

And the array being returned looks like this:

[ { PRODUCTID: '7',
    PRODUCTNAME: 'Token 1',
    QTY: '500',
    PRICE: '5',
    AVAILABLE: '1',
    PRODUCTTYPE: '1',
    BILLINGDEALNAME: 'Token 1' },
  { PRODUCTID: '8',
    PRODUCTNAME: 'Token 2',
    QTY: '1000',
    PRICE: '9',
    AVAILABLE: '1',
    PRODUCTTYPE: '1',
    BILLINGDEALNAME: 'Token 2' },
  { PRODUCTID: '9',
    PRODUCTNAME: 'Token 3',
    QTY: '2000',
    PRICE: '16',
    AVAILABLE: '1',
    PRODUCTTYPE: '1',
    BILLINGDEALNAME: 'Token 3' },
  { PRODUCTID: '5',
    PRODUCTNAME: 'Token - Free',
    QTY: '500',
    PRICE: '0',
    AVAILABLE: '0',
    PRODUCTTYPE: '0',
    BILLINGDEALNAME: 'Token - Free Token Use' },
  { PRODUCTID: '6',
    PRODUCTNAME: 'Token - Prepaid',
    QTY: '500',
    PRICE: '0',
    AVAILABLE: '0',
    PRODUCTTYPE: '0',
    BILLINGDEALNAME: 'Token - Prepaid Token Use' } ]

I know it's not a ton of information, but it's all I have. If I force the route to return an empty array in the response, there's no problem. I don't know where else to look.

Help?!

UPDATE

I've tweaked the code slightly for debugging. The ternary operator has been ditched:

if (products.length > 0) {
  //return res.send(200, []);
  console.error('RETURNING PRODUCTS');
  console.error(products);
  // return res.send(200, []);

  return res.send(200, products);
}
else {
  return res.send(200, []);
}

Upvotes: 0

Views: 375

Answers (3)

vodolaz095
vodolaz095

Reputation: 6986

probably you can use streaming in response

if (products.length > 0) {
  res.statusCode = 200;
  products.map(res.write);
  res.end();
}
else {
  return res.send(200, []);
}

Upvotes: 0

Rob Wilkerson
Rob Wilkerson

Reputation: 41256

The key to this, for my specific problem, at least, was to downgrade Express.js from 3.4.x to 3.3.x. Because this is a production system, I wasn't able to play with it in order to gain a more sophisticated understanding of what was happening and I've never been able to reproduce this in my downstream environments.

Just wanted to close this out for anyone who may be searching later.

Upvotes: 1

vodolaz095
vodolaz095

Reputation: 6986

try recent version of nodejs - 0.10.26 - i have similiar issues in nodejs of 0.8.x versions

Upvotes: 0

Related Questions