var CircuitBreaker = function(opts) {
  var opts = opts || {};
  this.threshold = opts.threshold || 15;
  this.minErrors = opts.minErrors || 3;
  this.duration = opts.duration || 10000;
  this.numOfBuckets = opts.numOfBuckets || 10;
  this._buckets = [{ failures: 0, successes: 0 }];

  var self = this;

  this.success = function() {
    var bucket = self._buckets[self._buckets.length - 1];
    bucket.successes++;
  };

  this.failed = function() {
    var bucket = self._buckets[self._buckets.length - 1];
    bucket.failures++;
  };

  this._ticker = window.setInterval(function() {
    var bucket = { failures: 0, successes: 0 };

    if (self._buckets.length > self.numOfBuckets) {
      self._buckets.shift();
    }

    self._buckets.push(bucket);
  }, this.duration / this.numOfBuckets);
};

CircuitBreaker.prototype.run = function(command) {
  if (this.isBroken()) return;

  command(this.success, this.failed);
};

CircuitBreaker.prototype.isBroken = function() {
  var failures = 0, successes = 0;

  for (var i = 0, l = this._buckets.length; i < l; i++) {
    var bucket = this._buckets[i];

    failures += bucket.failures;
    successes += bucket.successes;
  }

  var total = failures + successes;
  if (total == 0) total = 1;

  var failedPercent = (failures / total) * 100;

  return (failedPercent > this.threshold && failures > this.minErrors) && Math.random() > 0.1;
};

@@ -226,16 +226,58 @@
  %7C%7C 10;%0A
+  this.retryRate = opts.retryRate %7C%7C 0.1;%0A
   this._
@@ -1403,16 +1403,21 @@
 ors) && 
+%0A    
 Math.ran
@@ -1424,16 +1424,27 @@
 dom() %3E 
-0.1
+this.retryRate
 ;%0A%7D;%0A

use configurable retry rate