lib/httpx/plugins/retries.rb in httpx-0.3.1 vs lib/httpx/plugins/retries.rb in httpx-0.4.0

- old
+ new

@@ -1,50 +1,78 @@ # frozen_string_literal: true module HTTPX module Plugins + # + # This plugin adds support for retrying requests when certain errors happen. + # module Retries MAX_RETRIES = 3 + # TODO: pass max_retries in a configure/load block + IDEMPOTENT_METHODS = %i[get options head put delete].freeze + RETRYABLE_ERRORS = [IOError, + EOFError, + Errno::ECONNRESET, + Errno::ECONNABORTED, + Errno::EPIPE, + (OpenSSL::SSL::SSLError if defined?(OpenSSL)), + TimeoutError, + Parser::Error, + Errno::EINVAL, + Errno::ETIMEDOUT].freeze + def self.extra_options(options) + Class.new(options.class) do + def_option(:max_retries) do |num| + num = Integer(num) + raise Error, ":max_retries must be positive" unless num.positive? + + num + end + + def_option(:retry_change_requests) + end.new(options) + end + module InstanceMethods def max_retries(n) branch(default_options.with_max_retries(n.to_i)) end private - def fetch_response(request) + def fetch_response(request, connections, options) response = super if response.is_a?(ErrorResponse) && request.retries.positive? && - IDEMPOTENT_METHODS.include?(request.verb) + __repeatable_request?(request, options) && + __retryable_error?(response.error) request.retries -= 1 - channel = find_channel(request) - channel.send(request) + log { "failed to get response, #{request.retries} tries to go..." } + request.transition(:idle) + connection = find_connection(request, connections, options) + connection.send(request) return end response end + + def __repeatable_request?(request, options) + IDEMPOTENT_METHODS.include?(request.verb) || options.retry_change_requests + end + + def __retryable_error?(ex) + RETRYABLE_ERRORS.any? { |klass| ex.is_a?(klass) } + end end module RequestMethods attr_accessor :retries def initialize(*args) super @retries = @options.max_retries || MAX_RETRIES - end - end - - module OptionsMethods - def self.included(klass) - super - klass.def_option(:max_retries) do |num| - num = Integer(num) - raise Error, ":max_retries must be positive" unless num.positive? - num - end end end end register_plugin :retries, Retries end