Sha256: 3832f1b978b513b39f7319dc3e4b8d69978772e918d9255daeab409ebb0c5e39

Contents?: true

Size: 1.09 KB

Versions: 1

Compression:

Stored size: 1.09 KB

Contents

require "delegate"
class Backoff < Delegator
  def self.wrap(object, exception_classes, logger, options)
    return object if object.is_a?(self.class)
    new(object, exception_classes, logger, options)
  end

  def initialize(object, exception_classes, logger, options = {})
    @exception_classes = exception_classes
    @delegate_sd_obj = object
    @logger = logger
    @sleeper = options[:sleeper] || Kernel.method(:sleep)
    @initial_backoff = options[:initial_backoff] || 1
    @multiplier = options[:multiplier] || 2
    @random = options[:random] || Random.new
    @jitter = options[:jitter] || lambda {|delay| @random.rand(0..delay.to_f) }
  end

  def __getobj__
    @delegate_sd_obj
  end

  def method_missing(sym, *args, &block)
    _with_backoff { super }
  end

  def _with_backoff(backoff = @initial_backoff)
    yield
  rescue *@exception_classes => e
    jittered_backoff = @jitter.call(backoff)
    @logger.error "Got #{e.class}, sleeping #{jittered_backoff}"
    @sleeper.call(backoff)
    @logger.info "Woke up after #{e.class} retrying again"
    backoff *= @multiplier
    retry
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
backoff-0.2.0 lib/backoff.rb