From d0b510bcddd5846b31581633df40a81901a80b4e Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Wed, 18 Dec 2024 11:14:49 +0000 Subject: [PATCH] resolver cache per ractor --- lib/httpx/resolver.rb | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/httpx/resolver.rb b/lib/httpx/resolver.rb index 6094ace2..1b8417c2 100644 --- a/lib/httpx/resolver.rb +++ b/lib/httpx/resolver.rb @@ -48,7 +48,12 @@ module HTTPX # matches +hostname+ to entries in the hosts file, returns nil if none is # found, or there is no hosts file. def hosts_resolve(hostname) - ips = @hosts_resolver.getaddresses(hostname) + ips = if in_ractor? + Ractor.store_if_absent(:httpx_hosts_resolver) { Resolv::Hosts.new } + else + @hosts_resolver + end.getaddresses(hostname) + return if ips.empty? ips.map { |ip| Entry.new(ip) } @@ -115,7 +120,12 @@ module HTTPX end def generate_id - id_synchronize { @identifier = (@identifier + 1) & 0xFFFF } + if in_ractor? + identifier = Ractor.store_if_absent(:httpx_resolver_identifier) { -1 } + (Ractor.current[:httpx_resolver_identifier] = (identifier + 1) & 0xFFFF) + else + id_synchronize { @identifier = (@identifier + 1) & 0xFFFF } + end end def encode_dns_query(hostname, type: Resolv::DNS::Resource::IN::A, message_id: generate_id) @@ -164,11 +174,28 @@ module HTTPX end def lookup_synchronize + if in_ractor? + lookups = Ractor.store_if_absent(:httpx_resolver_lookups) { Hash.new { |h, k| h[k] = [] } } + return yield(lookups) + end + @lookup_mutex.synchronize { yield(@lookups) } end def id_synchronize(&block) @identifier_mutex.synchronize(&block) end + + if defined?(Ractor) && + # no ractor support for 3.0 + RUBY_VERSION >= "3.1.0" + def in_ractor? + Ractor.main != Ractor.current + end + else + def in_ractor? + false + end + end end end