mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-07 00:05:02 -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)
|
||||
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|
|
||||
num = Integer(num)
|
||||
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..." }
|
||||
request.transition(:idle)
|
||||
connection = find_connection(request, connections, options)
|
||||
connection.send(request)
|
||||
set_request_timeout(connection, request, options)
|
||||
__retry_request(connection, request, options)
|
||||
return
|
||||
end
|
||||
response
|
||||
@ -77,6 +87,23 @@ module HTTPX
|
||||
def __retryable_error?(ex)
|
||||
RETRYABLE_ERRORS.any? { |klass| ex.is_a?(klass) }
|
||||
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
|
||||
|
||||
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)"
|
||||
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 InstanceMethods
|
||||
attr_reader :calls
|
||||
|
Loading…
x
Reference in New Issue
Block a user