Class: ExponentialBackoff

Inherits:
Object
  • Object
show all
Defined in:
lib/exponential_backoff.rb,
lib/exponential_backoff/version.rb

Constant Summary collapse

VERSION =
"0.0.2"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(interval, maximum_elapsed_time = nil) ⇒ ExponentialBackoff

Returns a new instance of ExponentialBackoff.

Raises:

  • (ArgumentError)


7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/exponential_backoff.rb', line 7

def initialize(interval, maximum_elapsed_time = nil)
  if interval.respond_to?(:first)
    @minimal_interval, @maximum_elapsed_time = interval.first, interval.last
  else
    @minimal_interval, @maximum_elapsed_time = interval, maximum_elapsed_time
  end
  raise ArgumentError, "Invalid range specified" if [@minimal_interval, @maximum_elapsed_time].any? { |i| !i.is_a?(Numeric) }

  @randomize_factor = 0
  @multiplier = 2.0
  clear
end

Instance Attribute Details

#current_intervalObject (readonly)

Returns the value of attribute current_interval.



5
6
7
# File 'lib/exponential_backoff.rb', line 5

def current_interval
  @current_interval
end

#multiplierObject

Returns the value of attribute multiplier.



4
5
6
# File 'lib/exponential_backoff.rb', line 4

def multiplier
  @multiplier
end

#randomize_factorObject

Returns the value of attribute randomize_factor.



4
5
6
# File 'lib/exponential_backoff.rb', line 4

def randomize_factor
  @randomize_factor
end

Instance Method Details

#clearObject



20
21
22
# File 'lib/exponential_backoff.rb', line 20

def clear
  @enumerator = intervals
end

#interval_at(iteration) ⇒ Object



42
43
44
# File 'lib/exponential_backoff.rb', line 42

def interval_at(iteration)
  randomized_interval(capped_interval(regular_interval(@minimal_interval, @multiplier, iteration)))
end

#intervalsObject



46
47
48
49
50
51
52
53
54
# File 'lib/exponential_backoff.rb', line 46

def intervals
  Enumerator.new do |yielder|
    iteration = 0
    loop do
      yielder.yield interval_at(iteration)
      iteration += 1
    end
  end
end

#intervals_for(range) ⇒ Object



38
39
40
# File 'lib/exponential_backoff.rb', line 38

def intervals_for(range)
  range.to_a.map { |iteration| interval_at(iteration) }
end

#iteration_active?(iteration) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
31
32
33
34
35
36
# File 'lib/exponential_backoff.rb', line 28

def iteration_active?(iteration)
  index = 0
  current_interval = interval_at(index)
  while current_interval < iteration && current_interval < @maximum_elapsed_time
    index += 1
    current_interval = interval_at(index)
  end
  current_interval == iteration || iteration % @maximum_elapsed_time == 0
end

#next_intervalObject



24
25
26
# File 'lib/exponential_backoff.rb', line 24

def next_interval
  @current_interval = @enumerator.next
end

#until_success(&block) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/exponential_backoff.rb', line 56

def until_success(&block)
  intervals.each_with_index do |interval, iteration|
    retval = block.call(interval, iteration)
    return if retval || retval.nil?
    sleep(interval)
  end
end