You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							101 lines
						
					
					
						
							2.3 KiB
						
					
					
				
			
		
		
	
	
							101 lines
						
					
					
						
							2.3 KiB
						
					
					
				var RetryOperation = require('./retry_operation');
 | 
						|
 | 
						|
exports.operation = function(options) {
 | 
						|
  var timeouts = exports.timeouts(options);
 | 
						|
  return new RetryOperation(timeouts, {
 | 
						|
      forever: options && (options.forever || options.retries === Infinity),
 | 
						|
      unref: options && options.unref,
 | 
						|
      maxRetryTime: options && options.maxRetryTime
 | 
						|
  });
 | 
						|
};
 | 
						|
 | 
						|
exports.timeouts = function(options) {
 | 
						|
  if (options instanceof Array) {
 | 
						|
    return [].concat(options);
 | 
						|
  }
 | 
						|
 | 
						|
  var opts = {
 | 
						|
    retries: 10,
 | 
						|
    factor: 2,
 | 
						|
    minTimeout: 1 * 1000,
 | 
						|
    maxTimeout: Infinity,
 | 
						|
    randomize: false
 | 
						|
  };
 | 
						|
  for (var key in options) {
 | 
						|
    opts[key] = options[key];
 | 
						|
  }
 | 
						|
 | 
						|
  if (opts.minTimeout > opts.maxTimeout) {
 | 
						|
    throw new Error('minTimeout is greater than maxTimeout');
 | 
						|
  }
 | 
						|
 | 
						|
  var timeouts = [];
 | 
						|
  for (var i = 0; i < opts.retries; i++) {
 | 
						|
    timeouts.push(this.createTimeout(i, opts));
 | 
						|
  }
 | 
						|
 | 
						|
  if (options && options.forever && !timeouts.length) {
 | 
						|
    timeouts.push(this.createTimeout(i, opts));
 | 
						|
  }
 | 
						|
 | 
						|
  // sort the array numerically ascending
 | 
						|
  timeouts.sort(function(a,b) {
 | 
						|
    return a - b;
 | 
						|
  });
 | 
						|
 | 
						|
  return timeouts;
 | 
						|
};
 | 
						|
 | 
						|
exports.createTimeout = function(attempt, opts) {
 | 
						|
  var random = (opts.randomize)
 | 
						|
    ? (Math.random() + 1)
 | 
						|
    : 1;
 | 
						|
 | 
						|
  var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
 | 
						|
  timeout = Math.min(timeout, opts.maxTimeout);
 | 
						|
 | 
						|
  return timeout;
 | 
						|
};
 | 
						|
 | 
						|
exports.wrap = function(obj, options, methods) {
 | 
						|
  if (options instanceof Array) {
 | 
						|
    methods = options;
 | 
						|
    options = null;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!methods) {
 | 
						|
    methods = [];
 | 
						|
    for (var key in obj) {
 | 
						|
      if (typeof obj[key] === 'function') {
 | 
						|
        methods.push(key);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (var i = 0; i < methods.length; i++) {
 | 
						|
    var method   = methods[i];
 | 
						|
    var original = obj[method];
 | 
						|
 | 
						|
    obj[method] = function retryWrapper(original) {
 | 
						|
      var op       = exports.operation(options);
 | 
						|
      var args     = Array.prototype.slice.call(arguments, 1);
 | 
						|
      var callback = args.pop();
 | 
						|
 | 
						|
      args.push(function(err) {
 | 
						|
        if (op.retry(err)) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        if (err) {
 | 
						|
          arguments[0] = op.mainError();
 | 
						|
        }
 | 
						|
        callback.apply(this, arguments);
 | 
						|
      });
 | 
						|
 | 
						|
      op.attempt(function() {
 | 
						|
        original.apply(obj, args);
 | 
						|
      });
 | 
						|
    }.bind(obj, original);
 | 
						|
    obj[method].options = options;
 | 
						|
  }
 | 
						|
};
 |