2

I am running a basic node server which performs some https get requests to a GE Historian DB via REST API calls and receives JSON data in return. I have four different statistics for each of six machines which update themselves using recursive timeout calls on regular intervals every 5-60 seconds. After running for awhile, the REST API calls will stop getting data and instead produce an ENOBUFS error at which point the Windows 7 host PC must be rebooted before the server can be restarted.

I have seen a number of posts similar to:

https://github.com/nodejs/node-v0.x-archive/issues/3269

Very simple Node.js client throws error ENOBUFS after many http requests

Most of those threads suggest disabling the https agent entirely, but this doesn't resolve the issue. I currently am trying it by creating https.Agent objects for each of the four statistics which make http calls, specifying maxSockets = 1 for each agent. It seems to now be recycling ports correctly; but in case this falls on its face as the other attempted fixes have after about a day or so of running, I wanted to post and see if anyone had other ideas for what might fix this ENOBUFS error.

Thanks in advance for any assistance. For reference, here's the generic https request function I created to handle these queries and an example 'queryOptions' object:

Agent Declaration:

var agent1 = new https.Agent;
agent1.maxSockets = 1;

queryOptions Object example:

var queryOptions = {
        agent : agent1,
        hostname : "in02",
        port : 8443,
        path : '/historian-rest-api/v1/datapoints/currentvalue?tagNames=Compact_PME.INT_Accrued_Cycles_ThisRun[' + self.line.machineId + ']',
        headers : {
            "Accept" : "application/json",
            "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language" : "en-US,en;q=0.5",
            "Accept-Encoding" : "gzip, deflate, br",
            "Authorization" : "Bearer " + self.historianApi.token
        }
    };

getContent function:

const getContent = function(queryOptions, callback) {
    apiCallTimer = {
        start : moment(),
        end : null,
        elapsed : 0
    };

    https.get(queryOptions, function(res) {
        const statusCode = res.statusCode;
        const contentType = res.headers['content-type'];

        var error;
        if (statusCode !== 200) {
            error = new Error('Request Failed.\nStatus Code: ' + statusCode);
            //console.log(res);
        } else if (!/^application\/json/.test(contentType)) {
            error = new Error('Invalid content-type.\nExpected application/json but received ' + contentType);
        }
        if (error) {
            console.log(error.message);
            // consume response data to free up memory
            res.resume();
        }

        res.setEncoding('utf8');
        var rawData = '';
        res.on('data', function(chunk) {
            rawData += chunk;
        });
        res.on('end', function() {
            try {
                //console.log('API call complete!');

                var parsedData = JSON.parse(rawData);
                apiCallTimer.end = moment();
                apiCallTimer.elapsed = apiCallTimer.end - apiCallTimer.start;

                var queryResultObject = {
                    queryOptions : queryOptions,
                    json : parsedData,
                    apiCallTimer : apiCallTimer
                };
                callback(queryResultObject);
            } catch (e) {
                e.queryOptions = queryOptions;
                e.functionCalled = getContent;
                callback(e);
                //console.log(e.message);
            }
        });
    }).on('error', function(e) {
        callback(e);
    });
Community
  • 1
  • 1
Robert I
  • 21
  • 2

0 Answers0