Class: Wait
- Inherits:
-
Object
- Object
- Wait
- Defined in:
- lib/wait.rb,
lib/version.rb,
lib/loggers/base.rb,
lib/raisers/base.rb,
lib/testers/base.rb,
lib/counters/base.rb,
lib/delayers/base.rb,
lib/loggers/debug.rb,
lib/rescuers/base.rb,
lib/raisers/signal.rb,
lib/testers/truthy.rb,
lib/raisers/passive.rb,
lib/testers/passive.rb,
lib/delayers/regular.rb,
lib/delayers/exponential.rb
Defined Under Namespace
Classes: BaseCounter, BaseDelayer, BaseLogger, BaseRaiser, BaseRescuer, BaseTester, DebugLogger, ExponentialDelayer, PassiveRaiser, PassiveTester, RegularDelayer, ResultInvalid, SignalRaiser, TimeoutError, TruthyTester
Constant Summary collapse
- DEFAULT =
{ :attempts => 5, :timeout => 15, :delay => 1, :counter => BaseCounter, :delayer => RegularDelayer, :rescuer => BaseRescuer, :tester => TruthyTester, :raiser => SignalRaiser, :logger => BaseLogger }
- VERSION =
'0.5.3'
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ Wait
constructor
Creates a new Wait instance.
-
#until(&block) ⇒ Object
Description.
Constructor Details
#initialize(options = {}) ⇒ Wait
Creates a new Wait instance.
Basic Options
- :attempts
-
Number of times to attempt the block. Default is
5
. - :timeout
-
Seconds until the block times out. Default is
15
. - :delay
-
Seconds to delay in between attempts. Default is
1
. - :rescue
-
One or an array of exceptions to rescue. Default is
nil
. - :debug
-
If
true
, debug logging is enabled. Default isfalse
.
Advanced Options
- :logger
-
Ruby logger used. Default is Wait::BaseLogger.
- :counter
-
Strategy used to count attempts. Default is Wait::BaseCounter.
- :delayer
-
Strategy used to delay in between attempts. Default is Wait::RegularDelayer.
- :rescuer
-
Strategy used to rescue exceptions. Default is Wait::BaseRescuer.
- :tester
-
Strategy used to test the result. Default is Wait::TruthyTester.
- :raiser
-
Strategy used to raise specific exceptions. Default is Wait::SignalRaiser.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/wait.rb', line 48 def initialize( = {}) # Assign defaults. debug = [:debug] || false @logger = [:logger] || (debug ? DebugLogger : DEFAULT[:logger]).new attempts = [:attempts] || DEFAULT[:attempts] @counter = [:counter] || DEFAULT[:counter].new(attempts) @timeout = [:timeout] || DEFAULT[:timeout] delay = [:delay] || DEFAULT[:delay] @delayer = [:delayer] || DEFAULT[:delayer].new(delay) exceptions = [:rescue] @rescuer = [:rescuer] || DEFAULT[:rescuer].new(exceptions) @tester = [:tester] || DEFAULT[:tester].new @raiser = [:raiser] || DEFAULT[:raiser].new # Assign the logger to each of the strategies. [@counter, @delayer, @rescuer, @tester, @raiser].each do |strategy| strategy.logger = @logger if strategy.respond_to?(:logger=) end end |
Instance Method Details
#until(&block) ⇒ Object
Description
Wait#until executes a block until there’s a valid (by default, truthy) result. Useful for blocking script execution until:
-
an HTTP request was successful
-
a port has opened
-
a process has started
-
etc.
Examples
wait = Wait.new
# => #<Wait>
wait.until { Time.now.sec.even? }
# [Counter] attempt 1/5
# [Tester] result: false
# [Rescuer] rescued: Wait::ResultInvalid
# [Raiser] not raising: Wait::ResultInvalid
# [Delayer] delaying for 1s
# [Counter] attempt 2/5
# [Tester] result: true
# => true
If you wish to handle an exception by attempting the block again, pass one or an array of exceptions with the :rescue
option.
wait = Wait.new(:rescue => RuntimeError)
# => #<Wait>
wait.until do |attempt|
case attempt
when 1 then nil
when 2 then raise RuntimeError
when 3 then "foo"
end
end
# [Counter] attempt 1/5
# [Tester] result: nil
# [Rescuer] rescued: Wait::ResultInvalid
# [Raiser] not raising: Wait::ResultInvalid
# [Delayer] delaying for 1s
# [Counter] attempt 2/5
# [Rescuer] rescued: RuntimeError
# [Raiser] not raising: RuntimeError
# [Delayer] delaying for 1s
# [Counter] attempt 3/5
# [Tester] result: "foo"
# => "foo"
Returns
The result of the block if valid (by default, truthy).
Raises
If no results are valid, the exception from the last attempt made.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/wait.rb', line 124 def until(&block) # Reset the attempt counter. @counter.reset begin # Increment the attempt counter. @counter.increment # Wrap the given block in a timeout. result = Timeout.timeout(@timeout, TimeoutError) do # Execute the block and pass the attempt count (an +Integer+) to it. yield(@counter.attempt) end # Raise an exception unless the result is valid. @tester.valid?(result) ? result : raise(ResultInvalid) rescue TimeoutError, ResultInvalid, *@rescuer.exceptions => exception # Log the exception. @rescuer.log(exception) # Raise the exception if it ought to be. raise(exception) if @raiser.raise?(exception) # Raise the exception if this was the last attempt. raise(exception) if @counter.last_attempt? # Sleep before the next attempt. @delayer.sleep # Try the block again. retry end end |