Implementation of a synchronous name resolver which relies on the system resolver, which is lib’c getaddrinfo function (abstracted in ruby via Addrinfo.getaddrinfo).
Its main advantage is relying on the reference implementation for name resolution across most/all OSs which deploy ruby (it’s what TCPSocket also uses), its main disadvantage is the inability to set timeouts / check socket for readiness events, hence why it relies on using the Timeout module, which poses a lot of problems for the selector loop, specially when network is unstable.
Methods
Public Class
Public Instance
Constants
DONE | = | 1 | ||
ERROR | = | 2 | ||
RESOLV_ERRORS | = | [Resolv::ResolvError, Resolv::DNS::Requester::RequestError, Resolv::DNS::EncodeError, Resolv::DNS::DecodeError].freeze |
Attributes
state | [R] |
Public Class methods
new(options)
[show source]
# File lib/httpx/resolver/system.rb 34 def initialize(options) 35 super(0, options) 36 @resolver_options = @options.resolver_options 37 resolv_options = @resolver_options.dup 38 timeouts = resolv_options.delete(:timeouts) || Resolver::RESOLVE_TIMEOUT 39 @_timeouts = Array(timeouts) 40 @timeouts = Hash.new { |tims, host| tims[host] = @_timeouts.dup } 41 resolv_options.delete(:cache) 42 @queries = [] 43 @ips = [] 44 @pipe_mutex = Thread::Mutex.new 45 @state = :idle 46 end
Public Instance methods
call()
[show source]
# File lib/httpx/resolver/system.rb 82 def call 83 case @state 84 when :open 85 consume 86 end 87 nil 88 end
close()
[show source]
# File lib/httpx/resolver/system.rb 62 def close 63 transition(:closed) 64 end
closed?()
[show source]
# File lib/httpx/resolver/system.rb 74 def closed? 75 @state == :closed 76 end
early_resolve(connection, **)
[show source]
# File lib/httpx/resolver/system.rb 119 def early_resolve(connection, **); end
empty?()
[show source]
# File lib/httpx/resolver/system.rb 58 def empty? 59 @connections.empty? 60 end
force_close(*)
[show source]
# File lib/httpx/resolver/system.rb 66 def force_close(*) 67 close 68 @queries.clear 69 @timeouts.clear 70 @ips.clear 71 super 72 end
handle_socket_timeout(interval)
[show source]
# File lib/httpx/resolver/system.rb 121 def handle_socket_timeout(interval) 122 error = HTTPX::ResolveTimeoutError.new(interval, "timed out while waiting on select") 123 error.set_backtrace(caller) 124 @queries.each do |_, connection| # rubocop:disable Style/HashEachMethods 125 emit_resolve_error(connection, connection.peer.host, error) if @connections.delete(connection) 126 end 127 128 while (connection = @connections.shift) 129 emit_resolve_error(connection, connection.peer.host, error) 130 end 131 132 close_or_resolve 133 end
interests()
[show source]
# File lib/httpx/resolver/system.rb 90 def interests 91 return if @queries.empty? 92 93 :r 94 end
lazy_resolve(connection)
[show source]
# File lib/httpx/resolver/system.rb 110 def lazy_resolve(connection) 111 @connections << connection 112 resolve 113 114 return if empty? 115 116 @current_session.select_resolver(self, @current_selector) 117 end
resolvers()
[show source]
# File lib/httpx/resolver/system.rb 48 def resolvers 49 return enum_for(__method__) unless block_given? 50 51 yield self 52 end
timeout()
[show source]
# File lib/httpx/resolver/system.rb 96 def timeout 97 _, connection = @queries.first 98 99 return unless connection 100 101 timeouts = @timeouts[connection.peer.host] 102 103 return if timeouts.empty? 104 105 log(level: 2) { "resolver #{FAMILY_TYPES[@record_type]}: next timeout #{timeouts.first} secs... (#{timeouts.size - 1} left)" } 106 107 timeouts.first 108 end