def with_retries(*rescued, &block)
      options      = rescued.last.is_a?(Hash) ? rescued.pop : {}
      exception    = nil
      retries      = 0

      rescued = Defaults::RETRIED_EXCEPTIONS if rescued.empty?

      max_attempts = options[:attempts] || Defaults::RETRY_ATTEMPTS
      backoff_base = options[:base]     || Defaults::RETRY_BASE
      backoff_max  = options[:max_wait] || Defaults::RETRY_MAX_WAIT

      begin
        return yield retries, exception
      rescue *rescued => e
        exception = e

        retries += 1
        raise if retries > max_attempts

        # Calculate the exponential backoff combined with an element of
        # randomness.
        backoff = [backoff_base * (2 ** (retries - 1)), backoff_max].min
        backoff = backoff * (0.5 * (1 + Kernel.rand))

        # Ensure we are sleeping at least the minimum interval.
        backoff = [backoff_base, backoff].max

        # Exponential backoff.
        Kernel.sleep(backoff)

        # Now retry
        retry
      end
    end
def with_retries(*rescued, &block)
      options      = rescued.last.is_a?(Hash) ? rescued.pop : {}
      exception    = nil
      retries      = 0

      rescued = Defaults::RETRIED_EXCEPTIONS if rescued.empty?

      max_attempts = options[:attempts] || Defaults::RETRY_ATTEMPTS
      backoff_base = options[:base]     || Defaults::RETRY_BASE
      backoff_max  = options[:max_wait] || Defaults::RETRY_MAX_WAIT

      begin
        return yield retries, exception
      rescue *rescued => e
        exception = e

        retries += 1
        raise if retries > max_attempts

        # Calculate the exponential backoff combined with an element of
        # randomness.
        backoff = [backoff_base * (2 ** (retries - 1)), backoff_max].min
        backoff = backoff * (0.5 * (1 + Kernel.rand))

        # Ensure we are sleeping at least the minimum interval.
        backoff = [backoff_base, backoff].max

        # Exponential backoff.
        Kernel.sleep(backoff)

        # Now retry
        retry
      end
    end
Execute the given block with retries and exponential backoff.

 @param [Array<Exception>] rescued
   the list of exceptions to rescue