Module: Kernel
- Defined in:
- lib/retries.rb
Instance Method Summary collapse
-
#with_retries(options = {}) {|attempt_number| ... } ⇒ Object
Runs the supplied code block an retries with an exponential backoff.
Instance Method Details
#with_retries(options = {}) {|attempt_number| ... } ⇒ Object
Runs the supplied code block an retries with an exponential backoff.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/retries.rb', line 27 def with_retries( = {}, &block) # Check the options and set defaults = "Error with options to with_retries:" max_tries = [:max_tries] || 3 raise "#{} :max_tries must be greater than 0." unless max_tries > 0 base_sleep_seconds = [:base_sleep_seconds] || 0.5 max_sleep_seconds = [:max_sleep_seconds] || 1.0 if base_sleep_seconds > max_sleep_seconds raise "#{} :base_sleep_seconds cannot be greater than :max_sleep_seconds." end handler = [:handler] exception_types_to_rescue = Array([:rescue] || StandardError) raise "#{} with_retries must be passed a block" unless block_given? # Let's do this thing attempts = 0 start_time = Time.now begin attempts += 1 return block.call(attempts) rescue *exception_types_to_rescue => exception raise exception if attempts >= max_tries handler.call(exception, attempts, Time.now - start_time) if handler # Don't sleep at all if sleeping is disabled (used in testing). if Retries.sleep_enabled # The sleep time is an exponentially-increasing function of base_sleep_seconds. But, it never exceeds # max_sleep_seconds. sleep_seconds = [base_sleep_seconds * (2 ** (attempts - 1)), max_sleep_seconds].min # Randomize to a random value in the range sleep_seconds/2 .. sleep_seconds sleep_seconds = sleep_seconds * (0.5 * (1 + rand())) # But never sleep less than base_sleep_seconds sleep_seconds = [base_sleep_seconds, sleep_seconds].max sleep sleep_seconds end retry end end |