<commit_before>'use strict'

var events = require('events')
var merge = require('merge')
var Q = require('q')
var util = require('util')
var winston = require('winston')
var winstonWrapper = require('winston-meta-wrapper')

function Retry (opts) {
  this._opts = merge(Object.create(Retry.DEFAULTS), opts)
  // logging
  this._log = winstonWrapper(winston)
  this._log.addMeta({
    module: '1tp:signaling:retry'
  })
  // event emitter
  events.EventEmitter.call(this)
  // done
  this._log.debug('created repeater with opts ' + JSON.stringify(this._opts))
}

// Inherit EventEmitter
util.inherits(Retry, events.EventEmitter)

Retry.DEFAULTS = {
  maxRetries: 5,
  timeoutDelay: 500
}

Retry.prototype.executeP = function (operation, confirmEventName, delay, retries) {
  this._log.debug('scheduling promise execution until receiving event ' + confirmEventName)
  // set delay if undefined
  if (delay === undefined) {
    delay = this._opts.timeoutDelay
  }
  // set retries if undefined
  if (retries === undefined) {
    retries = this._opts.maxRetries
  }
  var self = this
  var promise = Q.fcall(operation)
  // execute promise
  return promise.then(function () {
    var deferred = Q.defer()
    // if timeout before confirmEvent
    var timeout = setTimeout(
      function () {
        // remove confirm event listener
        self.removeAllListeners([confirmEventName])
        // resolve
        deferred.resolve(false)
      },
      delay
    )
    // if confirm event is fired
    self.once(confirmEventName, function () {
      // then clear timeout
      clearTimeout(timeout)
      // and resolve
      deferred.resolve(true)
    })
    return deferred.promise
  }).then(function (confirmed) {
    if (!confirmed) {
      if (retries === 0) {
        var message = 'giving up, no more retries left'
        self._log.debug(message)
        throw new Error(message)
      } else {
        self._log.debug("let's give it another try")
        return self.executeP(operation, confirmEventName, delay, retries - 1)
      }
    } else {
      self._log.debug('confirmation arrived -- done')
    }
  })
}

Retry.prototype.confirm = function (confirmEventName) {
  this._log.debug('confirming ' + confirmEventName)
  this.emit(confirmEventName)
}

module.exports = Retry<commit_msg>added exponential backoff support<commit_after>'use strict'

var events = require('events')
var merge = require('merge')
var Q = require('q')
var util = require('util')
var winston = require('winston')
var winstonWrapper = require('winston-meta-wrapper')

function Retry (opts) {
  this._opts = merge(Object.create(Retry.DEFAULTS), opts)
  // logging
  this._log = winstonWrapper(winston)
  this._log.addMeta({
    module: '1tp:signaling:retry'
  })
  // event emitter
  events.EventEmitter.call(this)
  // done
  this._log.debug('created repeater with opts ' + JSON.stringify(this._opts))
}

// Inherit EventEmitter
util.inherits(Retry, events.EventEmitter)

Retry.DEFAULTS = {
  maxRetries: 5,
  timeoutDelay: 500,
  maxDelay: 5000,
  exponentialBackoff: false
}

Retry.prototype.executeP = function (operation, confirmEventName, delay, retries) {
  this._log.debug('scheduling promise execution until receiving event ' + confirmEventName + ', delay = ' + delay + ', retries = ' + retries)
  // set delay if undefined
  if (delay === undefined) {
    delay = this._opts.timeoutDelay
  }
  // set retries if undefined
  if (retries === undefined) {
    retries = this._opts.maxRetries
  }
  var self = this
  var promise = Q.fcall(operation)
  // execute promise
  return promise.then(function () {
    var deferred = Q.defer()
    // if timeout before confirmEvent
    var timeout = setTimeout(
      function () {
        // remove confirm event listener
        self.removeAllListeners([confirmEventName])
        // resolve
        deferred.resolve(false)
      },
      delay
    )
    // if confirm event is fired
    self.once(confirmEventName, function () {
      // then clear timeout
      clearTimeout(timeout)
      // and resolve
      deferred.resolve(true)
    })
    return deferred.promise
  }).then(function (confirmed) {
    if (!confirmed) {
      if (retries === 0) {
        var message = 'giving up, no more retries left'
        self._log.debug(message)
        throw new Error(message)
      } else {
        self._log.debug("let's give it another try")
        var newDelay = (self._opts.exponentialBackoff) ? Math.min(self._opts.maxDelay, delay * 2) : delay
        return self.executeP(operation, confirmEventName, newDelay, retries - 1)
      }
    } else {
      self._log.debug('confirmation arrived -- done')
    }
  })
}

Retry.prototype.confirm = function (confirmEventName) {
  this._log.debug('confirming ' + confirmEventName)
  this.emit(confirmEventName)
}

module.exports = Retry
{'fraction_non_alphanumeric': 0.12053200332502079, 'fraction_numerical': 0.003948462177888612, 'mean_word_length': 3.0309882747068677, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '1440024', 'n_tokens_mistral': 1468, 'n_tokens_neox': 1453, 'n_words': 355}