<commit_before>var _ = require('underscore');
var os = require('os');
var request = require('request');
var util = require('util');

// Enable cookies
request = request.defaults({jar: true});

var options = {};
var server = 'https://api.gatech.edu';

var BuzzAPI = function(config) {
    options.api_app_id = config.apiUser;
    options.api_app_password = new Buffer(config.apiPassword).toString('base64');
    options.api_request_mode = config.sync ? 'sync' : 'async';
    server = config.server || server;
};

BuzzAPI.prototype.post = function(resource, operation, data, callback) {
    if (_.isFunction(data)) {
        callback = data;
        data = {};
    }
    var myOpts = {};
    myOpts.url = util.format('%s/apiv3/%s/%s', server, resource, operation);
    data.handle = data.handle || util.format('from-%d@%s-rand%d', process.pid, os.hostname(), Math.floor(Math.random() * 32768));
    myOpts.body = _.extend(data, options);
    myOpts.json = true;
    request.post(myOpts, function(err, res, body) {
        if (err || body.api_error_info) {
            return callback(err, body.api_error_info, body);
        } else if (options.api_request_mode === 'sync') {
            return callback(null, body.api_result_data, body);
        } else {
            getResult(body.api_result_data, body.api_app_ticket, callback);
        }
    });
};

var getResult = function(messageId, ticket, callback) {
    request({
        'url': util.format('%s/apiv3/api.my_messages', server),
        'qs': {
            'api_app_ticket': ticket,
            'api_pull_response_to': messageId
        },
        'json': true
    }, function(err, res, body) {
        if (err || body.api_error_info) {
            return callback(err, body.api_error_info, body);
        } else if (_.isEmpty(body.api_result_data)) {
            // Empty result_data here means our data isn't ready, try again
            return getResult(messageId, body.api_app_ticket, callback);
        } else if (!body.api_result_data.api_result_data) {
            return callback(new Error('BuzzAPI returned an empty result, this usually means it timed out requesting a resource'), {}, body);
        } else {
            return callback(null, body.api_result_data.api_result_data, body);
        }
    });   
};

module.exports = BuzzAPI;
<commit_msg>add timeout for long running recursive retries<commit_after>var _ = require('underscore');
var os = require('os');
var request = require('request');
var util = require('util');

// Enable cookies
request = request.defaults({jar: true});

var options = {};
var server = 'https://api.gatech.edu';

var BuzzAPI = function(config) {
    options.api_app_id = config.apiUser;
    options.api_app_password = new Buffer(config.apiPassword).toString('base64');
    options.api_request_mode = config.sync ? 'sync' : 'async';
    server = config.server || server;
};

BuzzAPI.prototype.post = function(resource, operation, data, callback) {
    if (_.isFunction(data)) {
        callback = data;
        data = {};
    }
    var myOpts = {};
    myOpts.url = util.format('%s/apiv3/%s/%s', server, resource, operation);
    data.handle = data.handle || util.format('from-%d@%s-rand%d', process.pid, os.hostname(), Math.floor(Math.random() * 32768));
    myOpts.body = _.extend(data, options);
    myOpts.json = true;
    request.post(myOpts, function(err, res, body) {
        if (err || body.api_error_info) {
            return callback(err, body.api_error_info, body);
        } else if (options.api_request_mode === 'sync') {
            return callback(null, body.api_result_data, body);
        } else {
            getResult(body.api_result_data, body.api_app_ticket, callback);
        }
    });
};

var getResult = function(messageId, ticket, initTime, callback) {
    if (_.isFunction(initTime)) {
        callback = initTime;
        initTime = new Date();
    } else if (new Date() - initTime > 900){
       return callback(new Error('Request was open for 15 minutes'));
    }
    request({
        'url': util.format('%s/apiv3/api.my_messages', server),
        'qs': {
            'api_app_ticket': ticket,
            'api_pull_response_to': messageId
        },
        'json': true
    }, function(err, res, body) {
        if (err || body.api_error_info) {
            return callback(err, body.api_error_info, body);
        } else if (_.isEmpty(body.api_result_data)) {
            // Empty result_data here means our data isn't ready, try again
            return getResult(messageId, body.api_app_ticket, initTime, callback);
        } else if (!body.api_result_data.api_result_data) {
            return callback(new Error('BuzzAPI returned an empty result, this usually means it timed out requesting a resource'), {}, body);
        } else {
            return callback(null, body.api_result_data.api_result_data, body);
        }
    });
};

module.exports = BuzzAPI;

{'fraction_non_alphanumeric': 0.14212783336736778, 'fraction_numerical': 0.004696753114151521, 'mean_word_length': 2.8842188739095955, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1473337', 'n_tokens_mistral': 1521, 'n_tokens_neox': 1496, 'n_words': 345}