<commit_before>/**
 * Copyright 2016-2017 F5 Networks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

var fs = require('fs');
var q = require('q');
var Logger = require('./logger');
var ipc = require('./ipc');
var signals = require('./signals');

var logger = Logger.getLogger({logLevel: 'none', module: module});

const EOL = require('os').EOL;
const REBOOT_SCRIPTS_DIR = '/tmp/rebootScripts/';

/**
 * @module
 */
module.exports = {

    DEFAULT_RETRY: {
        maxRetries: 90,
        retryIntervalMs: 10000
    },

    SHORT_RETRY: {
        maxRetries: 3,
        retryIntervalMs: 300
    },

    NO_RETRY: {
        maxRetries: 0,
        retryIntervalMs: 0
    },

    setLoggerOptions: function(loggerOptions) {
        loggerOptions.module = module;
        logger = Logger.getLogger(loggerOptions);
    },

    /**
     * Tries a method until it succeeds or reaches a maximum number of retries.
     *
     * @param {Object}   thisArg                      - The 'this' argument to pass to the called function
     * @param {Object}   retryOptions                 - Options for retrying the request.
     * @param {Integer}  retryOptions.maxRetries      - Number of times to retry if first try fails. 0 to not retry. Default 60.
     * @param {Integer}  retryOptions.retryIntervalMs - Milliseconds between retries. Default 10000.
     * @param {Function} funcToTry                    - Function to try. Function should return a
     *                                                  Promise which is later resolved or rejected.
     * @param {Object[]} args                         - Array of arguments to pass to funcToTry
     *
     * @returns {Promise} A promise which is resolved with the return from funcToTry
     *                    if funcToTry is resolved within maxRetries.
     */
    tryUntil: function(thisArg, retryOptions, funcToTry, args) {
        var _tryUntil = function(maxRetries, interval, funcToTry, deferred) {

            var promise;

            if (!deferred) {
                deferred = q.defer();
            }

            promise = funcToTry.apply(thisArg, args);

            // Allow this to work with native promises which do not have a done
            if (!promise.done) {
                promise.done = function() {};
            }

            promise
                .then(function(response) {
                    deferred.resolve(response);
                }.bind(this))
                .catch(function(err) {
                    logger.verbose('tryUntil error:', err ? err.message : '', 'tries left:', maxRetries);
                    if (err) {
                        logger.debug(err);
                    }

                    if (maxRetries > 0) {
                        --maxRetries;
                        setTimeout(_tryUntil, interval, maxRetries, interval, funcToTry, deferred);
                    }
                    else {
                        logger.verbose('Max tries reached.');
                        deferred.reject(err);
                    }
                }.bind(this))
                .done();

            return deferred.promise;
        }.bind(this);

        return _tryUntil(retryOptions.maxRetries, retryOptions.retryIntervalMs, funcToTry);
    },

    /**
     * Calls an array of promises in serial.
     *
     * @param {Object}   thisArg  - The 'this' argument to pass to the called function
     * @param {Object[]} promises - An array of promise definitions. Each<commit_msg>Allow tryUntil to work with native promises (take 2)<commit_after>/**
 * Copyright 2016-2017 F5 Networks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

var fs = require('fs');
var q = require('q');
var Logger = require('./logger');
var ipc = require('./ipc');
var signals = require('./signals');

var logger = Logger.getLogger({logLevel: 'none', module: module});

const EOL = require('os').EOL;
const REBOOT_SCRIPTS_DIR = '/tmp/rebootScripts/';

/**
 * @module
 */
module.exports = {

    DEFAULT_RETRY: {
        maxRetries: 90,
        retryIntervalMs: 10000
    },

    SHORT_RETRY: {
        maxRetries: 3,
        retryIntervalMs: 300
    },

    NO_RETRY: {
        maxRetries: 0,
        retryIntervalMs: 0
    },

    setLoggerOptions: function(loggerOptions) {
        loggerOptions.module = module;
        logger = Logger.getLogger(loggerOptions);
    },

    /**
     * Tries a method until it succeeds or reaches a maximum number of retries.
     *
     * @param {Object}   thisArg                      - The 'this' argument to pass to the called function
     * @param {Object}   retryOptions                 - Options for retrying the request.
     * @param {Integer}  retryOptions.maxRetries      - Number of times to retry if first try fails. 0 to not retry. Default 60.
     * @param {Integer}  retryOptions.retryIntervalMs - Milliseconds between retries. Default 10000.
     * @param {Function} funcToTry                    - Function to try. Function should return a
     *                                                  Promise which is later resolved or rejected.
     * @param {Object[]} args                         - Array of arguments to pass to funcToTry
     *
     * @returns {Promise} A promise which is resolved with the return from funcToTry
     *                    if funcToTry is resolved within maxRetries.
     */
    tryUntil: function(thisArg, retryOptions, funcToTry, args) {
        var _tryUntil = function(maxRetries, interval, funcToTry, deferred) {

            var promise;

            if (!deferred) {
                deferred = q.defer();
            }

            promise = funcToTry.apply(thisArg, args)
                .then(function(response) {
                    deferred.resolve(response);
                }.bind(this))
                .catch(function(err) {
                    logger.verbose('tryUntil error:', err ? err.message : '', 'tries left:', maxRetries);
                    if (err) {
                        logger.debug(err);
                    }

                    if (maxRetries > 0) {
                        --maxRetries;
                        setTimeout(_tryUntil, interval, maxRetries, interval, funcToTry, deferred);
                    }
                    else {
                        logger.verbose('Max tries reached.');
                        deferred.reject(err);
                    }
                }.bind(this));

                // Allow this to work with native promises which do not have a done
                if (promise.done) {
                    promise.done();
                }

            return deferred.promise;
        }.bind(this);

        return _tryUntil(retryOptions.maxRetries, retryOptions.retryIntervalMs, funcToTry);
    },

    /**
     * Calls an array of promises in serial.
     *
     * @param {Object}   thisArg  - The 'this' argument to pass to the called function
     * @param {Object[]} promises - An array of promise definitions. Each
{'fraction_non_alphanumeric': 0.09505988023952096, 'fraction_numerical': 0.008857285429141716, 'mean_word_length': 1.8051084674597622, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1241750', 'n_tokens_mistral': 2151, 'n_tokens_neox': 2022, 'n_words': 692}