mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-09 00:02:50 -04:00
added retry_after option to the retries plugin
This commit is contained in:
parent
46e8f57868
commit
98cce7df65
@ -25,6 +25,17 @@ module HTTPX
|
|||||||
|
|
||||||
def self.extra_options(options)
|
def self.extra_options(options)
|
||||||
Class.new(options.class) do
|
Class.new(options.class) do
|
||||||
|
# number of seconds after which one can retry the request
|
||||||
|
def_option(:retry_after) do |num|
|
||||||
|
# return early if callable
|
||||||
|
return num if num.respond_to?(:call)
|
||||||
|
|
||||||
|
num = Integer(num)
|
||||||
|
raise Error, ":retry_after must be positive" unless num.positive?
|
||||||
|
|
||||||
|
num
|
||||||
|
end
|
||||||
|
|
||||||
def_option(:max_retries) do |num|
|
def_option(:max_retries) do |num|
|
||||||
num = Integer(num)
|
num = Integer(num)
|
||||||
raise Error, ":max_retries must be positive" unless num.positive?
|
raise Error, ":max_retries must be positive" unless num.positive?
|
||||||
@ -63,8 +74,7 @@ module HTTPX
|
|||||||
log { "failed to get response, #{request.retries} tries to go..." }
|
log { "failed to get response, #{request.retries} tries to go..." }
|
||||||
request.transition(:idle)
|
request.transition(:idle)
|
||||||
connection = find_connection(request, connections, options)
|
connection = find_connection(request, connections, options)
|
||||||
connection.send(request)
|
__retry_request(connection, request, options)
|
||||||
set_request_timeout(connection, request, options)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
response
|
response
|
||||||
@ -77,6 +87,23 @@ module HTTPX
|
|||||||
def __retryable_error?(ex)
|
def __retryable_error?(ex)
|
||||||
RETRYABLE_ERRORS.any? { |klass| ex.is_a?(klass) }
|
RETRYABLE_ERRORS.any? { |klass| ex.is_a?(klass) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def __retry_request(connection, request, options)
|
||||||
|
retry_after = options.retry_after
|
||||||
|
unless retry_after
|
||||||
|
connection.send(request)
|
||||||
|
set_request_timeout(connection, request, options)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
retry_after = retry_after.call(request) if retry_after.respond_to?(:call)
|
||||||
|
log { "retrying after #{retry_after} secs..." }
|
||||||
|
pool.after(retry_after) do
|
||||||
|
log { "retrying!!" }
|
||||||
|
connection.send(request)
|
||||||
|
set_request_timeout(connection, request, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module RequestMethods
|
module RequestMethods
|
||||||
|
@ -46,6 +46,38 @@ module Requests
|
|||||||
assert retries_session.calls.zero?, "expect request not to be retried (it was, #{retries_session.calls} times)"
|
assert retries_session.calls.zero?, "expect request not to be retried (it was, #{retries_session.calls} times)"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_plugin_retries_retry_after
|
||||||
|
before_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
|
||||||
|
retries_session = HTTPX
|
||||||
|
.plugin(RequestInspector)
|
||||||
|
.plugin(:retries, retry_after: 2)
|
||||||
|
.timeout(total_timeout: 3)
|
||||||
|
.max_retries(1)
|
||||||
|
retries_response = retries_session.get(build_uri("/delay/10"))
|
||||||
|
after_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
|
||||||
|
total_time = after_time - before_time
|
||||||
|
|
||||||
|
assert retries_response.is_a?(HTTPX::ErrorResponse)
|
||||||
|
assert_in_delta 3 + 2 + 3, total_time, 1, "request didn't take as expected to retry (#{total_time} secs)"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_plugin_retries_retry_after_callable
|
||||||
|
retries = 0
|
||||||
|
exponential = ->(_) { (retries += 1) * 2 }
|
||||||
|
before_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
|
||||||
|
retries_session = HTTPX
|
||||||
|
.plugin(RequestInspector)
|
||||||
|
.plugin(:retries, retry_after: exponential)
|
||||||
|
.timeout(total_timeout: 3)
|
||||||
|
.max_retries(2)
|
||||||
|
retries_response = retries_session.get(build_uri("/delay/10"))
|
||||||
|
after_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
|
||||||
|
total_time = after_time - before_time
|
||||||
|
|
||||||
|
assert retries_response.is_a?(HTTPX::ErrorResponse)
|
||||||
|
assert_in_delta 3 + 2 + 3 + 4 + 3, total_time, 1, "request didn't take as expected to retry (#{total_time} secs)"
|
||||||
|
end
|
||||||
|
|
||||||
module RequestInspector
|
module RequestInspector
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
attr_reader :calls
|
attr_reader :calls
|
||||||
|
Loading…
x
Reference in New Issue
Block a user