4

I'm having some memory issues in a nodeJS application that is currently on production ( a proxy to S3 multipart upload server ) so I'm trying to search for a way to detect and prevent it.. I came across this tutorial but when I open the debug page the profile tab is not showing ( after I've followed the steps from the tutorial ). Am I doing something wrong? ( I'm following this tutorial https://github.com/felixge/node-memory-leak-tutorial )

If it helps, this is a part of my code that MIGHT be causing the leak:

IngestionClient.prototype.multipartUpload = function(params, req, res, aReqLength) {
var self = this;
var client = this.client[params.profile];
var dest = params.file;

logger.debug('PART ' + params.query.partNumber + '/' + params.query.totalSize +': BEGIN : '+req.headers['content-length']+' bytes : ['
        + params.file_id + ']');

var amazonRequest = client.request('PUT', '/' + dest
        + '?partNumber=' + params.query.partNumber + '&uploadId='
        + params.query.uploadId, {
    'Content-Length' : req.headers['content-length']
});

var partLength = 0;

req.on('data', function(data) {
    partLength += data.length;
    amazonRequest.write(data, 'binary');
});

req.on('end', function() {
    if(partLength == req.headers['content-length']) {
        logger.debug('PART ' + params.query.partNumber + '/' + params.query.totalSize +': CLIENT_RECEIVED_COMPLETE : ['
                + params.file_id + ']');
    }else {
        logger.error('PART ' + params.query.partNumber + '/' + params.query.totalSize +': CLIENT_RECEIVED_INCOMPLETE : Esperado '+req.headers['content-length']
        +' bytes / Recebido ' + partLength + ' : [' + params.file_id + ']');
        amazonRequest.abort();
        self.sendError(params, res);
    }

});

amazonRequest.on('response', function(amazonResponse) {
    var responseText;

        if (amazonResponse.statusCode == 200 && amazonResponse.headers.etag.length > 0) {
            self.queryDB(
                    'INSERT INTO SAMBAFILES_UPLOAD_CONTROL_PARTS SET FILE_ID="'
                            + params.file_id + '", ETAG=' + amazonResponse.headers.etag
                            + ', PART_NUMBER="' + params.query.partNumber + '"',
                    function(err, results) {
                        logger.debug('PART ' + params.query.partNumber + '/' + params.query.totalSize +': S3_PUT_COMPLETE : ['
                                + params.file_id + ']');            
                        responseText = '{"success": true}';
                        res.end(responseText);
                        self.checkComplete(params, dest);
                    });
        } else {
            var responseBody = "";
            amazonResponse.on('data', function(dataRes) {
                responseBody += dataRes;
            });

            amazonResponse.on("end", function(){
                if(responseBody.indexOf("<Code>RequestTimeout</Code>") > 0) {
                    //Erro de lentidao do envio ( + de 20 segundos ). Browser fará um retry
                    logger.error('PART ' + params.query.partNumber + '/' + params.query.totalSize +': S3_PUT_ERROR_TIMEOUT : Response Code ' 
                            + amazonResponse.statusCode + ' : [' + params.file_id + ']');
                }else {
                    logger.error('PART ' + params.query.partNumber + '/' + params.query.totalSize +': S3_PUT_ERROR : Response Code ' 
                            + amazonResponse.statusCode + ': ' + responseBody + ' : [' + params.file_id + ']');
                }
                amazonRequest.abort();
                self.sendError(params, res);

            });

        }

        console.log(util.inspect(process.memoryUsage()));

}).end();

};

Basically in each part that I receive from the browser I make a request to Amazon using the params and request received. Node version is 0.6.7

Thanks!

4
  • I advice you to also try with the latest greatest 0.8.x nodejs. Commented Jul 5, 2012 at 20:50
  • I'll do that after I figure whats happening. Just updating my node would add another variable to the problem so I was hoping to detect it first. Commented Jul 6, 2012 at 12:47
  • The problem could be a memory leak in node.js itself. That's why I ask you to update node.js. Commented Jul 7, 2012 at 4:37
  • A fix landed for the HTTP client in 0.6.17 for a memory leak. You may also want to add close handlers for your request and response object. Also, I've had a lot of luck using node-webkit-agent. Commented Jul 10, 2012 at 15:44

3 Answers 3

2

Mozilla team released node-memwatch, a nodejs module for tracking memory leak.

Official mozilla post : https://hacks.mozilla.org/2012/11/tracking-down-memory-leaks-in-node-js-a-node-js-holiday-season/

Github of the project : https://github.com/lloyd/node-memwatch

It looks very interesting and very promising.

Sign up to request clarification or add additional context in comments.

Comments

1

I suggest the tool http://search.npmjs.org/#/nodeheap. You can take a snapshot at anytime and compare what is still on the heap and use the tool to trace who the owners are.

Comments

0

The following plugin has been updated to work with new version of v8. It's the only one besides nodetime.com that is still working. It uses the actual webkit debugger:

https://github.com/c4milo/node-webkit-agent

It has very clear instructions as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.