Merge branch 'issue-257' into 'master'

DNS retries to native resolver

Closes #257

See merge request os85/httpx!293
This commit is contained in:
HoneyryderChuck 2023-11-06 12:03:52 +00:00
commit f6bee9e6e4
4 changed files with 18 additions and 22 deletions

View File

@ -5,7 +5,7 @@ require "ipaddr"
module HTTPX
module Resolver
RESOLVE_TIMEOUT = 5
RESOLVE_TIMEOUT = [2, 3].freeze
require "httpx/resolver/resolver"
require "httpx/resolver/system"

View File

@ -164,7 +164,8 @@ module HTTPX
def async_resolve(connection, hostname, scheme)
families = connection.options.ip_families
log { "resolver: query for #{hostname}" }
resolve_timeout = @timeouts[connection.origin.host].first
timeouts = @timeouts[connection.origin.host]
resolve_timeout = timeouts.first
Thread.start do
Thread.current.report_on_exception = false
@ -191,6 +192,8 @@ module HTTPX
end
rescue StandardError => e
if e.is_a?(Timeout::Error)
timeouts.shift
retry unless timeouts.empty?
e = ResolveTimeoutError.new(resolve_timeout, e.message)
e.set_backtrace(e.backtrace)
end

View File

@ -2,7 +2,7 @@ module HTTPX
type ipaddr = IPAddr | String
module Resolver
RESOLVE_TIMEOUT: Integer
RESOLVE_TIMEOUT: Array[Integer]
@lookup_mutex: Thread::Mutex

View File

@ -123,29 +123,22 @@ module Requests
end
end
# this test mocks an unresponsive DNS server which doesn't return a DNS asnwer back.
define_method :"test_resolver_#{resolver_type}_timeout" do
session = HTTPX.plugin(SessionWithPool)
uri = URI(build_uri("/get"))
# absolute URL, just to shorten the impact of resolv.conf search.
uri.host = "#{uri.host}."
start_test_servlet(SlowDNSServer, 12) do |slow_dns_server|
resolver_opts = options.merge(nameserver: [slow_dns_server.nameserver], timeouts: [1, 2])
resolver_class = Class.new(HTTPX::Resolver::Native) do
def interests
super
:w
HTTPX.plugin(SessionWithPool).wrap do |session|
uri = build_uri("/get")
before_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
response = session.get(uri, resolver_class: resolver_type, resolver_options: resolver_opts)
after_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
total_time = after_time - before_time
verify_error_response(response, HTTPX::ResolveTimeoutError)
assert_in_delta 2 + 1, total_time, 12, "request didn't take as expected to retry dns queries (#{total_time} secs)"
end
def dwrite; end
end
before_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
response = session.head(uri, resolver_class: resolver_class, resolver_options: options.merge(timeouts: [1, 2]))
after_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
total_time = after_time - before_time
verify_error_response(response, HTTPX::ResolveTimeoutError)
assert_in_delta 2 + 1, total_time, 6, "request didn't take as expected to retry dns queries (#{total_time} secs)"
end
# this test mocks the case where there's no nameserver set to send the DNS queries to.