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
Classes and Modules
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 37 def initialize(options) 38 super(0, options) 39 @resolver_options = @options.resolver_options 40 resolv_options = @resolver_options.dup 41 timeouts = resolv_options.delete(:timeouts) || Resolver::RESOLVE_TIMEOUT 42 @_timeouts = Array(timeouts) 43 @timeouts = Hash.new { |tims, host| tims[host] = @_timeouts.dup } 44 resolv_options.delete(:cache) 45 @queries = [] 46 @ips = [] 47 @pipe_mutex = Thread::Mutex.new 48 @state = :idle 49 end
Public Instance methods
call()
[show source]
# File lib/httpx/resolver/system.rb 85 def call 86 case @state 87 when :open 88 consume 89 end 90 nil 91 end
close()
[show source]
# File lib/httpx/resolver/system.rb 65 def close 66 transition(:closed) 67 end
closed?()
[show source]
# File lib/httpx/resolver/system.rb 77 def closed? 78 @state == :closed 79 end
early_resolve(_, **)
[show source]
# File lib/httpx/resolver/system.rb 122 def early_resolve(_, **) # rubocop:disable Naming/PredicateMethod 123 false 124 end
empty?()
[show source]
# File lib/httpx/resolver/system.rb 61 def empty? 62 @connections.empty? 63 end
force_close(*)
[show source]
# File lib/httpx/resolver/system.rb 69 def force_close(*) 70 close 71 @queries.clear 72 @timeouts.clear 73 @ips.clear 74 super 75 end
handle_socket_timeout(interval)
[show source]
# File lib/httpx/resolver/system.rb 126 def handle_socket_timeout(interval) 127 error = HTTPX::ResolveTimeoutError.new(interval, "timed out while waiting on select") 128 error.set_backtrace(caller) 129 @queries.each do |_, connection| # rubocop:disable Style/HashEachMethods 130 emit_resolve_error(connection, connection.peer.host, error) if @connections.delete(connection) 131 end 132 133 while (connection = @connections.shift) 134 emit_resolve_error(connection, connection.peer.host, error) 135 end 136 137 close_or_resolve 138 end
interests()
[show source]
# File lib/httpx/resolver/system.rb 93 def interests 94 return if @queries.empty? 95 96 :r 97 end
lazy_resolve(connection)
[show source]
# File lib/httpx/resolver/system.rb 113 def lazy_resolve(connection) 114 @connections << connection 115 resolve 116 117 return if empty? 118 119 @current_session.select_resolver(self, @current_selector) 120 end
resolvers()
[show source]
# File lib/httpx/resolver/system.rb 51 def resolvers 52 return enum_for(__method__) unless block_given? 53 54 yield self 55 end
timeout()
[show source]
# File lib/httpx/resolver/system.rb 99 def timeout 100 _, connection = @queries.first 101 102 return unless connection 103 104 timeouts = @timeouts[connection.peer.host] 105 106 return if timeouts.empty? 107 108 log(level: 2) { "resolver #{FAMILY_TYPES[@record_type]}: next timeout #{timeouts.first} secs... (#{timeouts.size - 1} left)" } 109 110 timeouts.first 111 end