Class: TryUntil::Repeatedly

Inherits:
Object
  • Object
show all
Defined in:
lib/try_until/repeatedly.rb

Overview

External interface Example: include TryUntil result = Repeatedly.new(Probe.new(Object.new, :to_s))

.attempts(5)
.interval(10)
.delay(10)
.rescues([ ArgumentError, IOError ])
.stop_when(lambda { |response| JSON.parse(response.body)['id'] == 'some_id' })
.log_to($stdout)
.execute

Not all of the above settings are required. These are the default values: attempts = 3 interval = 0 delay = 0 rescues = [] stop_when = lambda { |response| false } log_to = TryUntil::NullPrinter.new

Instance Method Summary collapse

Constructor Details

#initialize(probe) ⇒ Repeatedly

Returns a new instance of Repeatedly.



24
25
26
27
# File 'lib/try_until/repeatedly.rb', line 24

def initialize(probe)
  @probe = probe
  defaults
end

Instance Method Details

#attempts(int_num) ⇒ Object



29
30
31
32
# File 'lib/try_until/repeatedly.rb', line 29

def attempts(int_num)
  @attempts = int_num
  self
end

#configurationObject



89
90
91
92
# File 'lib/try_until/repeatedly.rb', line 89

def configuration
  { :probe => @probe.to_s, :attempts => @attempts, :interval => @interval,
    :delay => @delay, :rescues => @rescues, :log_to => @log_to }
end

#delay(seconds) ⇒ Object



39
40
41
42
# File 'lib/try_until/repeatedly.rb', line 39

def delay(seconds)
  @delay = seconds
  self
end

#executeObject

The heart of this gem: This method will repeatedly call ‘#sample’ on the subject and evaluate if the expectated result is returned. In case of errors it will rescue those and continue, provided the type of error is among the ones defined in @rescues.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/try_until/repeatedly.rb', line 63

def execute
  Kernel.sleep(@delay) if @delay > 0
  count = 1
  condition_met = false
  while count <= @attempts
    begin
      result = @probe.sample
      if @stop_when.call(result)
        condition_met = true
        log_outcome(count, 'CONDITION_MET')
        return result
      end
      log_outcome(count, 'CONDITION_NOT_MET')
    rescue *@rescues => exception
      log_outcome(count, exception.class)
      raise exception, "During final attempt (#{@attempts} configured) target returned #{exception}" if count == @attempts
    ensure
      unless condition_met
        Kernel.sleep @interval if count < @attempts && @interval > 0
        count += 1
      end
    end
  end
  raise "After #{@attempts} attempts, the expected result was not returned!"
end

#interval(seconds) ⇒ Object



34
35
36
37
# File 'lib/try_until/repeatedly.rb', line 34

def interval(seconds)
  @interval = seconds
  self
end

#log_to(io) ⇒ Object



54
55
56
57
# File 'lib/try_until/repeatedly.rb', line 54

def log_to(io)
  @log_to = io
  self
end

#rescues(errors) ⇒ Object



44
45
46
47
# File 'lib/try_until/repeatedly.rb', line 44

def rescues(errors)
  @rescues = errors
  self
end

#stop_when(callable) ⇒ Object



49
50
51
52
# File 'lib/try_until/repeatedly.rb', line 49

def stop_when(callable)
  @stop_when = callable
  self
end