class FFWD::Retrier

Try to execute a block on an exponential timer until it no longer throws an exception.

Constants

MAX_FACTOR

Public Class Methods

new(timeout, &block) click to toggle source
# File lib/ffwd/retrier.rb, line 27
def initialize timeout, &block
  @block = block
  @timer = nil
  @timeout = timeout
  @max_timeout = timeout * 2**MAX_FACTOR
  @current_timeout = @timeout
  @attempt = 0
  @error_callbacks = []

  starting do
    try_block
  end

  stopping do
    if @timer
      @timer.cancel
      @timer = nil
    end
  end
end

Public Instance Methods

error(&block) click to toggle source
# File lib/ffwd/retrier.rb, line 48
def error &block
  @error_callbacks << block
end
try_block() click to toggle source
# File lib/ffwd/retrier.rb, line 52
def try_block
  @attempt += 1
  @block.call @attempt
  @current_timeout = @timeout
rescue => e
  @error_callbacks.each do |block|
    block.call @attempt, @current_timeout, e
  end

  @timer = EM::Timer.new(@current_timeout) do
    @current_timeout *= 2 unless @current_timeout >= @max_timeout
    @timer = nil
    try_block
  end
end