Class: FFWD::Retrier

Inherits:
Object
  • Object
show all
Includes:
Lifecycle
Defined in:
lib/ffwd/retrier.rb

Overview

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

Constant Summary collapse

MAX_FACTOR =
7

Instance Method Summary collapse

Methods included from Lifecycle

#depend_on, #start, #started?, #starting, #starting_hooks, #stop, #stopped?, #stopping, #stopping_hooks

Constructor Details

#initialize(timeout, &block) ⇒ Retrier

Returns a new instance of Retrier.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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

Instance Method Details

#error(&block) ⇒ Object



48
49
50
# File 'lib/ffwd/retrier.rb', line 48

def error &block
  @error_callbacks << block
end

#try_blockObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 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