module RetryUnsafeMethod::RetryUnsafeMethod::ClassMethods
Public Instance Methods
retry_unsafe_method(method_name, retry_count, *exceptions, &block)
click to toggle source
# File lib/retry_unsafe_method/retry_unsafe_method.rb, line 10 def retry_unsafe_method(method_name, retry_count, *exceptions, &block) options = exceptions.last.is_a?(Hash) ? exceptions.pop : {} wait = options.delete(:wait) wait = nil if wait && (!wait.is_a?(Numeric) || wait <= 0) unless method_defined?(method_name) || private_method_defined?(method_name) raise StandardError.new("method #{method_name} is not defined") end if block_given? raise StandardError.new('you must not pass exceptions and block simultaneously') if exceptions.size > 0 check_proc = block else raise StandardError.new('you must pass exceptions or block') if exceptions.size == 0 check_proc = Proc.new { |e| exceptions.map(&:to_s).include?(e.class.to_s) } end safe_method_name = :"#{method_name}_safe_with_retry" unsafe_method_name = :"#{method_name}_unsafe_without_retry" define_method(safe_method_name) do |*args, &block| begin __send__(unsafe_method_name, *args, &block) rescue StandardError => e ivar = :"@current_retry_#{method_name}" if check_proc.call(e) instance_variable_set(ivar, 0) unless instance_variable_defined?(ivar) if instance_variable_get(ivar) < retry_count instance_variable_set(ivar, instance_variable_get(ivar) + 1) sleep(wait) if wait retry else remove_instance_variable(ivar) raise e end else remove_instance_variable(ivar) if instance_variable_defined?(ivar) raise e end end end # define_method if private_method_defined?(method_name) private safe_method_name elsif protected_method_defined?(method_name) protected safe_method_name else public safe_method_name end alias_method unsafe_method_name, method_name alias_method method_name, safe_method_name end