module Ncio::Support::RetryAction
Provide a method to retry arbitrary code blocks with the ability to rescue certain exceptions and retry rather than failing hard on the exception.
Copied from: github.com/puppetlabs/puppetlabs-cloud_provisioner/blob/f6cbac3/lib/puppet/cloudpack/utils.rb
Public Class Methods
retry_action(params = { retry_exceptions: nil, timeout: nil, log: nil }) { || ... }
click to toggle source
Retry an action, catching exceptions and retrying if the exception has been specified.
rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
# File lib/ncio/support/retry_action.rb, line 28 def self.retry_action(params = { retry_exceptions: nil, timeout: nil, log: nil }) # Retry actions for a specified amount of time. This method will allow # the final retry to complete even if that extends beyond the timeout # period. raise RetryException::NoBlockGiven unless block_given? raise RetryException::NoTimeoutGiven if params[:timeout].nil? params[:retry_exceptions] ||= [] # Assumes reset_logging! has been called. This happens in the Ncio::App # initialization. log = params[:log] || Ncio::Support.log start = Time.now failures = 0 # rubocop:disable Lint/RescueException begin yield rescue Exception => e # If we were giving exceptions to catch, # catch the exceptions we care about and retry. # All others fail hard raise RetryException::Timeout if timedout?(start, params[:timeout]) retry_exceptions = params[:retry_exceptions] unless retry_exceptions.empty? if retry_exceptions.include?(e.class) log.warn("Retrying: #{e.class}: #{e}") else # If the exceptions is not in the list of retry_exceptions # re-raise. raise e end end # rubocop:enable Lint/RescueException failures += 1 # Increase the amount of time that we sleep after every # failed retry attempt. sleep(((2**failures) - 1) * 0.1) retry end # rubocop:enable Metrics/PerceivedComplexity, Metrics/MethodLength end
timedout?(start, timeout)
click to toggle source
# File lib/ncio/support/retry_action.rb, line 17 def self.timedout?(start, timeout) return true if timeout.nil? (Time.now - start) >= timeout end