Projekt

Obecné

Profil

Stáhnout (2.24 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
var RetryOperation = require('./retry_operation');
2
3
exports.operation = function(options) {
4
  var timeouts = exports.timeouts(options);
5
  return new RetryOperation(timeouts, {
6
      forever: options && options.forever,
7
      unref: options && options.unref,
8
      maxRetryTime: options && options.maxRetryTime
9
  });
10
};
11
12
exports.timeouts = function(options) {
13
  if (options instanceof Array) {
14
    return [].concat(options);
15
  }
16
17
  var opts = {
18
    retries: 10,
19
    factor: 2,
20
    minTimeout: 1 * 1000,
21
    maxTimeout: Infinity,
22
    randomize: false
23
  };
24
  for (var key in options) {
25
    opts[key] = options[key];
26
  }
27
28
  if (opts.minTimeout > opts.maxTimeout) {
29
    throw new Error('minTimeout is greater than maxTimeout');
30
  }
31
32
  var timeouts = [];
33
  for (var i = 0; i < opts.retries; i++) {
34
    timeouts.push(this.createTimeout(i, opts));
35
  }
36
37
  if (options && options.forever && !timeouts.length) {
38
    timeouts.push(this.createTimeout(i, opts));
39
  }
40
41
  // sort the array numerically ascending
42
  timeouts.sort(function(a,b) {
43
    return a - b;
44
  });
45
46
  return timeouts;
47
};
48
49
exports.createTimeout = function(attempt, opts) {
50
  var random = (opts.randomize)
51
    ? (Math.random() + 1)
52
    : 1;
53
54
  var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
55
  timeout = Math.min(timeout, opts.maxTimeout);
56
57
  return timeout;
58
};
59
60
exports.wrap = function(obj, options, methods) {
61
  if (options instanceof Array) {
62
    methods = options;
63
    options = null;
64
  }
65
66
  if (!methods) {
67
    methods = [];
68
    for (var key in obj) {
69
      if (typeof obj[key] === 'function') {
70
        methods.push(key);
71
      }
72
    }
73
  }
74
75
  for (var i = 0; i < methods.length; i++) {
76
    var method   = methods[i];
77
    var original = obj[method];
78
79
    obj[method] = function retryWrapper(original) {
80
      var op       = exports.operation(options);
81
      var args     = Array.prototype.slice.call(arguments, 1);
82
      var callback = args.pop();
83
84
      args.push(function(err) {
85
        if (op.retry(err)) {
86
          return;
87
        }
88
        if (err) {
89
          arguments[0] = op.mainError();
90
        }
91
        callback.apply(this, arguments);
92
      });
93
94
      op.attempt(function() {
95
        original.apply(obj, args);
96
      });
97
    }.bind(obj, original);
98
    obj[method].options = options;
99
  }
100
};