tlopo-ruby/tlopo-retry

View on GitHub
lib/tlopo/retry.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

require 'tlopo/retry/version'
require 'logger'
require 'timeout'

# Simple module so we have a namespace
module Tlopo
  LOGGER ||= Logger.new $stderr

  module Setters
    def make_setter(*names)
      names.each do |name|
        define_method(name) do |val|
          instance_variable_set("@#{name}", val)
          self
        end
      end
    end
  end

  class Retry
    extend Setters
    make_setter :tries, :interval, :exponential_backoff, :error_types
    def initialize(**args)
      @tries = args[:tries] || 3
      @interval = args[:interval] || 1
      @exponential_backoff = args[:exponential_backoff] || false
      @error_types = args[:error_types] || [StandardError]
    end

    def run(&block)
      count = 1
      while count <= @tries
        next unless block_given?

        begin
          return instance_eval(&block)
        rescue *@error_types => e
          time = @exponential_backoff ? @interval**count : @interval
          sleep time
          count += 1
          e
        end
      end
      LOGGER.error e
      raise "Retries exhausted, error: #{e.message}"
    end
  end
end