httpx 0.18.7 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/doc/release_notes/0_19_0.md +39 -0
- data/lib/httpx/adapters/faraday.rb +7 -3
- data/lib/httpx/connection.rb +14 -10
- data/lib/httpx/extensions.rb +16 -0
- data/lib/httpx/headers.rb +0 -2
- data/lib/httpx/io/tcp.rb +24 -5
- data/lib/httpx/options.rb +44 -11
- data/lib/httpx/plugins/cookies.rb +5 -7
- data/lib/httpx/plugins/proxy.rb +2 -5
- data/lib/httpx/plugins/retries.rb +1 -1
- data/lib/httpx/pool.rb +40 -20
- data/lib/httpx/resolver/https.rb +32 -42
- data/lib/httpx/resolver/multi.rb +79 -0
- data/lib/httpx/resolver/native.rb +24 -39
- data/lib/httpx/resolver/resolver.rb +92 -0
- data/lib/httpx/resolver/system.rb +175 -19
- data/lib/httpx/resolver.rb +37 -11
- data/lib/httpx/response.rb +4 -2
- data/lib/httpx/session_extensions.rb +9 -2
- data/lib/httpx/timers.rb +1 -1
- data/lib/httpx/transcoder/chunker.rb +0 -1
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +2 -0
- data/sig/errors.rbs +8 -0
- data/sig/headers.rbs +0 -2
- data/sig/httpx.rbs +4 -0
- data/sig/options.rbs +10 -7
- data/sig/parser/http1.rbs +14 -5
- data/sig/pool.rbs +17 -9
- data/sig/registry.rbs +3 -0
- data/sig/request.rbs +11 -0
- data/sig/resolver/https.rbs +15 -27
- data/sig/resolver/multi.rbs +7 -0
- data/sig/resolver/native.rbs +3 -12
- data/sig/resolver/resolver.rbs +36 -0
- data/sig/resolver/system.rbs +3 -9
- data/sig/resolver.rbs +12 -10
- data/sig/response.rbs +15 -5
- data/sig/selector.rbs +3 -3
- data/sig/timers.rbs +5 -2
- data/sig/transcoder/chunker.rbs +16 -5
- data/sig/transcoder/json.rbs +5 -0
- data/sig/transcoder.rbs +3 -1
- metadata +9 -5
- data/lib/httpx/resolver/resolver_mixin.rb +0 -75
- data/sig/resolver/resolver_mixin.rbs +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d2af1a18388c76620d8a5b28e0f1d2dd90a4d2d0ee2c514be85ea7ba1b05c45
|
4
|
+
data.tar.gz: ca44331c601c46d51813cd5ccab8b258e94cf517913e26b78716885234e6cf86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eac8b6a85fdd44dda2bcaf000cc7dc5dfa19b075165b52fa709dd8b575e9b4a919293e724242d2449794b74e28cf34c00687c6f99e23baee563c45626429b3c7
|
7
|
+
data.tar.gz: 564f2e8f6d580070eaffa3cda012f0efb032948ce4851b96f947cd5a004d1e8fde9496f29031b341709ccc44040ea3473304697e5d5c7c659b7c2cd286702b78
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# 0.19.0
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
### Happy Eyeballs v2
|
6
|
+
|
7
|
+
When the system supports dual-stack networking, `httpx` implements the Happy Eyeballs v2 algorithm (RFC 8305) to resolve hostnames to both IPv6 and IPv4 addresses while privileging IPv6 connectivity. This is implemented by `httpx` both for the `:native` as well as the `:https` (DoH) resolver (which do not perform address sorting, thereby being "DNS-based load-balancing" friendly), and "outsourced" to `getaddrinfo` when using the `:system` resolver.
|
8
|
+
|
9
|
+
IPv6 connectivity will also be privileged for `/etc/hosts` local DNS (i.e. `localhost` connections will connec to `::1`).
|
10
|
+
|
11
|
+
A new option, `:ip_families`, will also be available (`[Socket::AF_INET6, Socket::AF_INET]` in dual-stack systems). If you'd like to i.e. force IPv4 connectivity, you can do use it (`client = HTTPX.with(ip_families: [Socket::AF_INET])`).
|
12
|
+
|
13
|
+
## Improvements
|
14
|
+
|
15
|
+
### DNS: :system resolver uses getaddrinfo (instead of the resolver lib)
|
16
|
+
|
17
|
+
The `:system` resolver switched to using the `getaddinfo` system function to perform DNS requests. Not only is this call **not** blocking the session event loop anymore (unlike pre-0.19.0 `:system` resolver), it adds a lot of functionality that the stdlib `resolv` library just doesn't support at the moment (such as SRV records).
|
18
|
+
|
19
|
+
### HTTP/2 proxy support
|
20
|
+
|
21
|
+
The `:proxy` plugin handles "prior-knowledge" HTTP/2 proxies.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
HTTPX.plugin(:proxy, fallback_protocol: "h2").with_proxy(uri: "http://http2-proxy:3128").get(...
|
25
|
+
```
|
26
|
+
|
27
|
+
Connection coalescing has also been enabled for proxied connections (also `CONNECT`-tunneled connections).
|
28
|
+
|
29
|
+
### curl-to-httpx
|
30
|
+
|
31
|
+
widget in [project website](https://honeyryderchuck.gitlab.io/httpx/) to turn curl commands into the equivalent `httpx` code.
|
32
|
+
|
33
|
+
## Bugfixes
|
34
|
+
|
35
|
+
* faraday adapter now supports passing session options.
|
36
|
+
* proxy: several fixes which enabled env-var (`HTTP(S)_PROXY`) defined proxy support.
|
37
|
+
* proxy: fixed graceful recovery from proxy tcp connect errors.
|
38
|
+
* several fixes around CNAMEs timeouts with the native resolver.
|
39
|
+
* https resolver is now closed when wrapping session closes (it was left open).
|
@@ -81,6 +81,9 @@ module Faraday
|
|
81
81
|
|
82
82
|
def response=(response)
|
83
83
|
super
|
84
|
+
|
85
|
+
return if response.is_a?(::HTTPX::ErrorResponse)
|
86
|
+
|
84
87
|
response.body.on_data = @response_on_data
|
85
88
|
end
|
86
89
|
end
|
@@ -136,7 +139,7 @@ module Faraday
|
|
136
139
|
|
137
140
|
def on_response(&blk)
|
138
141
|
if blk
|
139
|
-
@on_response =
|
142
|
+
@on_response = ->(response) do
|
140
143
|
blk.call(response)
|
141
144
|
end
|
142
145
|
self
|
@@ -200,9 +203,9 @@ module Faraday
|
|
200
203
|
end
|
201
204
|
end
|
202
205
|
|
203
|
-
def initialize(app)
|
206
|
+
def initialize(app, options = {})
|
204
207
|
super(app)
|
205
|
-
@session = Session.new
|
208
|
+
@session = Session.new(options)
|
206
209
|
end
|
207
210
|
|
208
211
|
def call(env)
|
@@ -210,6 +213,7 @@ module Faraday
|
|
210
213
|
if parallel?(env)
|
211
214
|
handler = env[:parallel_manager].enqueue(env)
|
212
215
|
handler.on_response do |response|
|
216
|
+
response.raise_for_status
|
213
217
|
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
|
214
218
|
response_headers.merge!(response.headers)
|
215
219
|
end
|
data/lib/httpx/connection.rb
CHANGED
@@ -44,7 +44,7 @@ module HTTPX
|
|
44
44
|
|
45
45
|
def_delegator :@write_buffer, :empty?
|
46
46
|
|
47
|
-
attr_reader :origin, :origins, :state, :pending, :options
|
47
|
+
attr_reader :io, :origin, :origins, :state, :pending, :options
|
48
48
|
|
49
49
|
attr_writer :timers
|
50
50
|
|
@@ -78,7 +78,11 @@ module HTTPX
|
|
78
78
|
# this is a semi-private method, to be used by the resolver
|
79
79
|
# to initiate the io object.
|
80
80
|
def addresses=(addrs)
|
81
|
-
@io
|
81
|
+
if @io
|
82
|
+
@io.add_addresses(addrs)
|
83
|
+
else
|
84
|
+
@io = IO.registry(@type).new(@origin, addrs, @options)
|
85
|
+
end
|
82
86
|
end
|
83
87
|
|
84
88
|
def addresses
|
@@ -490,14 +494,14 @@ module HTTPX
|
|
490
494
|
|
491
495
|
def transition(nextstate)
|
492
496
|
handle_transition(nextstate)
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
497
|
+
rescue Errno::ECONNREFUSED,
|
498
|
+
Errno::EADDRNOTAVAIL,
|
499
|
+
Errno::EHOSTUNREACH,
|
500
|
+
TLSError => e
|
501
|
+
# connect errors, exit gracefully
|
502
|
+
handle_error(e)
|
503
|
+
@state = :closed
|
504
|
+
emit(:close)
|
501
505
|
end
|
502
506
|
|
503
507
|
def handle_transition(nextstate)
|
data/lib/httpx/extensions.rb
CHANGED
@@ -54,6 +54,22 @@ module HTTPX
|
|
54
54
|
Numeric.__send__(:include, NegMethods)
|
55
55
|
end
|
56
56
|
|
57
|
+
module StringExtensions
|
58
|
+
refine String do
|
59
|
+
def delete_suffix!(suffix)
|
60
|
+
suffix = Backports.coerce_to_str(suffix)
|
61
|
+
chomp! if frozen?
|
62
|
+
len = suffix.length
|
63
|
+
if len > 0 && index(suffix, -len)
|
64
|
+
self[-len..-1] = ''
|
65
|
+
self
|
66
|
+
else
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end unless String.method_defined?(:delete_suffix!)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
57
73
|
module HashExtensions
|
58
74
|
refine Hash do
|
59
75
|
def compact
|
data/lib/httpx/headers.rb
CHANGED
data/lib/httpx/io/tcp.rb
CHANGED
@@ -15,6 +15,7 @@ module HTTPX
|
|
15
15
|
|
16
16
|
def initialize(origin, addresses, options)
|
17
17
|
@state = :idle
|
18
|
+
@addresses = []
|
18
19
|
@hostname = origin.host
|
19
20
|
@options = Options.new(options)
|
20
21
|
@fallback_protocol = @options.fallback_protocol
|
@@ -30,15 +31,29 @@ module HTTPX
|
|
30
31
|
raise Error, "Given IO objects do not match the request authority" unless @io
|
31
32
|
|
32
33
|
_, _, _, @ip = @io.addr
|
33
|
-
@addresses
|
34
|
-
@ip_index = @addresses.size - 1
|
34
|
+
@addresses << @ip
|
35
35
|
@keep_open = true
|
36
36
|
@state = :connected
|
37
37
|
else
|
38
|
-
|
38
|
+
add_addresses(addresses)
|
39
39
|
end
|
40
40
|
@ip_index = @addresses.size - 1
|
41
|
-
@io ||= build_socket
|
41
|
+
# @io ||= build_socket
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_addresses(addrs)
|
45
|
+
return if addrs.empty?
|
46
|
+
|
47
|
+
addrs = addrs.map { |addr| addr.is_a?(IPAddr) ? addr : IPAddr.new(addr) }
|
48
|
+
|
49
|
+
ip_index = @ip_index || (@addresses.size - 1)
|
50
|
+
if addrs.first.ipv6?
|
51
|
+
# should be the next in line
|
52
|
+
@addresses = [*@addresses[0, ip_index], *addrs, *@addresses[ip_index..-1]]
|
53
|
+
else
|
54
|
+
@addresses.unshift(*addrs)
|
55
|
+
@ip_index += addrs.size if @ip_index
|
56
|
+
end
|
42
57
|
end
|
43
58
|
|
44
59
|
def to_io
|
@@ -52,7 +67,7 @@ module HTTPX
|
|
52
67
|
def connect
|
53
68
|
return unless closed?
|
54
69
|
|
55
|
-
if @io.closed?
|
70
|
+
if !@io || @io.closed?
|
56
71
|
transition(:idle)
|
57
72
|
@io = build_socket
|
58
73
|
end
|
@@ -62,12 +77,16 @@ module HTTPX
|
|
62
77
|
Errno::EHOSTUNREACH => e
|
63
78
|
raise e if @ip_index <= 0
|
64
79
|
|
80
|
+
log { "failed connecting to #{@ip} (#{e.message}), trying next..." }
|
65
81
|
@ip_index -= 1
|
82
|
+
@io = build_socket
|
66
83
|
retry
|
67
84
|
rescue Errno::ETIMEDOUT => e
|
68
85
|
raise ConnectTimeoutError.new(@options.timeout[:connect_timeout], e.message) if @ip_index <= 0
|
69
86
|
|
87
|
+
log { "failed connecting to #{@ip} (#{e.message}), trying next..." }
|
70
88
|
@ip_index -= 1
|
89
|
+
@io = build_socket
|
71
90
|
retry
|
72
91
|
end
|
73
92
|
|
data/lib/httpx/options.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "socket"
|
4
|
+
|
3
5
|
module HTTPX
|
4
6
|
class Options
|
5
7
|
WINDOW_SIZE = 1 << 14 # 16K
|
@@ -9,6 +11,18 @@ module HTTPX
|
|
9
11
|
KEEP_ALIVE_TIMEOUT = 20
|
10
12
|
SETTINGS_TIMEOUT = 10
|
11
13
|
|
14
|
+
# https://github.com/ruby/resolv/blob/095f1c003f6073730500f02acbdbc55f83d70987/lib/resolv.rb#L408
|
15
|
+
ip_address_families = begin
|
16
|
+
list = Socket.ip_address_list
|
17
|
+
if list.any? { |a| a.ipv6? && !a.ipv6_loopback? && !a.ipv6_linklocal? }
|
18
|
+
[Socket::AF_INET6, Socket::AF_INET]
|
19
|
+
else
|
20
|
+
[Socket::AF_INET]
|
21
|
+
end
|
22
|
+
rescue NotImplementedError
|
23
|
+
[Socket::AF_INET]
|
24
|
+
end
|
25
|
+
|
12
26
|
DEFAULT_OPTIONS = {
|
13
27
|
:debug => ENV.key?("HTTPX_DEBUG") ? $stderr : nil,
|
14
28
|
:debug_level => (ENV["HTTPX_DEBUG"] || 1).to_i,
|
@@ -37,6 +51,7 @@ module HTTPX
|
|
37
51
|
:persistent => false,
|
38
52
|
:resolver_class => (ENV["HTTPX_RESOLVER"] || :native).to_sym,
|
39
53
|
:resolver_options => { cache: true },
|
54
|
+
:ip_families => ip_address_families,
|
40
55
|
}.freeze
|
41
56
|
|
42
57
|
begin
|
@@ -110,20 +125,18 @@ module HTTPX
|
|
110
125
|
end
|
111
126
|
|
112
127
|
def initialize(options = {})
|
113
|
-
|
114
|
-
defaults.each do |k, v|
|
115
|
-
next if v.nil?
|
116
|
-
|
117
|
-
begin
|
118
|
-
value = __send__(:"option_#{k}", v)
|
119
|
-
instance_variable_set(:"@#{k}", value)
|
120
|
-
rescue NoMethodError
|
121
|
-
raise Error, "unknown option: #{k}"
|
122
|
-
end
|
123
|
-
end
|
128
|
+
__initialize__(options)
|
124
129
|
freeze
|
125
130
|
end
|
126
131
|
|
132
|
+
def freeze
|
133
|
+
super
|
134
|
+
@origin.freeze
|
135
|
+
@timeout.freeze
|
136
|
+
@headers.freeze
|
137
|
+
@addresses.freeze
|
138
|
+
end
|
139
|
+
|
127
140
|
def option_origin(value)
|
128
141
|
URI(value)
|
129
142
|
end
|
@@ -174,6 +187,10 @@ module HTTPX
|
|
174
187
|
Array(value)
|
175
188
|
end
|
176
189
|
|
190
|
+
def option_ip_families(value)
|
191
|
+
Array(value)
|
192
|
+
end
|
193
|
+
|
177
194
|
%i[
|
178
195
|
params form json body ssl http2_settings
|
179
196
|
request_class response_class headers_class request_body_class
|
@@ -249,5 +266,21 @@ module HTTPX
|
|
249
266
|
end
|
250
267
|
end
|
251
268
|
end
|
269
|
+
|
270
|
+
private
|
271
|
+
|
272
|
+
def __initialize__(options = {})
|
273
|
+
defaults = DEFAULT_OPTIONS.merge(options)
|
274
|
+
defaults.each do |k, v|
|
275
|
+
next if v.nil?
|
276
|
+
|
277
|
+
begin
|
278
|
+
value = __send__(:"option_#{k}", v)
|
279
|
+
instance_variable_set(:"@#{k}", value)
|
280
|
+
rescue NoMethodError
|
281
|
+
raise Error, "unknown option: #{k}"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
252
285
|
end
|
253
286
|
end
|
@@ -18,12 +18,6 @@ module HTTPX
|
|
18
18
|
require "httpx/plugins/cookies/set_cookie_parser"
|
19
19
|
end
|
20
20
|
|
21
|
-
module OptionsMethods
|
22
|
-
def option_cookies(value)
|
23
|
-
value.is_a?(Jar) ? value : Jar.new(value)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
21
|
module InstanceMethods
|
28
22
|
extend Forwardable
|
29
23
|
|
@@ -77,7 +71,7 @@ module HTTPX
|
|
77
71
|
end
|
78
72
|
|
79
73
|
module OptionsMethods
|
80
|
-
def
|
74
|
+
def __initialize__(*)
|
81
75
|
super
|
82
76
|
|
83
77
|
return unless @headers.key?("cookie")
|
@@ -89,6 +83,10 @@ module HTTPX
|
|
89
83
|
end
|
90
84
|
end
|
91
85
|
end
|
86
|
+
|
87
|
+
def option_cookies(value)
|
88
|
+
value.is_a?(Jar) ? value : Jar.new(value)
|
89
|
+
end
|
92
90
|
end
|
93
91
|
end
|
94
92
|
register_plugin :cookies, Cookies
|
data/lib/httpx/plugins/proxy.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "resolv"
|
4
|
-
require "ipaddr"
|
5
|
-
require "forwardable"
|
6
|
-
|
7
3
|
module HTTPX
|
8
4
|
class HTTPProxyError < Error; end
|
9
5
|
|
@@ -117,6 +113,7 @@ module HTTPX
|
|
117
113
|
|
118
114
|
def fetch_response(request, connections, options)
|
119
115
|
response = super
|
116
|
+
|
120
117
|
if response.is_a?(ErrorResponse) &&
|
121
118
|
__proxy_error?(response) && !@_proxy_uris.empty?
|
122
119
|
@_proxy_uris.shift
|
@@ -251,7 +248,7 @@ module HTTPX
|
|
251
248
|
case nextstate
|
252
249
|
when :closing
|
253
250
|
# this is a hack so that we can use the super method
|
254
|
-
# and it'll
|
251
|
+
# and it'll think that the current state is open
|
255
252
|
@state = :open if @state == :connecting
|
256
253
|
end
|
257
254
|
super
|
@@ -96,8 +96,8 @@ module HTTPX
|
|
96
96
|
# rubocop:enable Style/MultilineTernaryOperator
|
97
97
|
)
|
98
98
|
response.close if response.respond_to?(:close)
|
99
|
-
request.retries -= 1
|
100
99
|
log { "failed to get response, #{request.retries} tries to go..." }
|
100
|
+
request.retries -= 1
|
101
101
|
request.transition(:idle)
|
102
102
|
|
103
103
|
retry_after = options.retry_after
|
data/lib/httpx/pool.rb
CHANGED
@@ -14,7 +14,6 @@ module HTTPX
|
|
14
14
|
|
15
15
|
def initialize
|
16
16
|
@resolvers = {}
|
17
|
-
@_resolver_ios = {}
|
18
17
|
@timers = Timers.new
|
19
18
|
@selector = Selector.new
|
20
19
|
@connections = []
|
@@ -56,9 +55,20 @@ module HTTPX
|
|
56
55
|
connections = connections.reject(&:inflight?)
|
57
56
|
connections.each(&:close)
|
58
57
|
next_tick until connections.none? { |c| c.state != :idle && @connections.include?(c) }
|
58
|
+
|
59
|
+
# close resolvers
|
60
|
+
outstanding_connections = @connections
|
61
|
+
resolver_connections = @resolvers.each_value.flat_map(&:connections).compact
|
62
|
+
outstanding_connections -= resolver_connections
|
63
|
+
|
64
|
+
return unless outstanding_connections.empty?
|
65
|
+
|
59
66
|
@resolvers.each_value do |resolver|
|
60
67
|
resolver.close unless resolver.closed?
|
61
|
-
end
|
68
|
+
end
|
69
|
+
# for https resolver
|
70
|
+
resolver_connections.each(&:close)
|
71
|
+
next_tick until resolver_connections.none? { |c| c.state != :idle && @connections.include?(c) }
|
62
72
|
end
|
63
73
|
|
64
74
|
def init_connection(connection, _options)
|
@@ -107,11 +117,12 @@ module HTTPX
|
|
107
117
|
return
|
108
118
|
end
|
109
119
|
|
110
|
-
|
111
|
-
|
112
|
-
|
120
|
+
find_resolver_for(connection) do |resolver|
|
121
|
+
resolver << connection
|
122
|
+
next if resolver.empty?
|
113
123
|
|
114
|
-
|
124
|
+
select_connection(resolver)
|
125
|
+
end
|
115
126
|
end
|
116
127
|
|
117
128
|
def on_resolver_connection(connection)
|
@@ -138,12 +149,11 @@ module HTTPX
|
|
138
149
|
|
139
150
|
def on_resolver_close(resolver)
|
140
151
|
resolver_type = resolver.class
|
141
|
-
return
|
152
|
+
return if resolver.closed?
|
142
153
|
|
143
154
|
@resolvers.delete(resolver_type)
|
144
155
|
|
145
156
|
deselect_connection(resolver)
|
146
|
-
@_resolver_ios.delete(resolver)
|
147
157
|
resolver.close unless resolver.closed?
|
148
158
|
end
|
149
159
|
|
@@ -174,12 +184,10 @@ module HTTPX
|
|
174
184
|
end
|
175
185
|
|
176
186
|
def coalesce_connections(conn1, conn2)
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
register_connection(conn2)
|
182
|
-
end
|
187
|
+
return register_connection(conn2) unless conn1.coalescable?(conn2)
|
188
|
+
|
189
|
+
conn1.merge(conn2)
|
190
|
+
@connections.delete(conn2)
|
183
191
|
end
|
184
192
|
|
185
193
|
def next_timeout
|
@@ -196,13 +204,25 @@ module HTTPX
|
|
196
204
|
resolver_type = Resolver.registry(resolver_type) if resolver_type.is_a?(Symbol)
|
197
205
|
|
198
206
|
@resolvers[resolver_type] ||= begin
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
207
|
+
resolver_manager = if resolver_type.multi?
|
208
|
+
Resolver::Multi.new(resolver_type, connection_options)
|
209
|
+
else
|
210
|
+
resolver_type.new(connection_options)
|
211
|
+
end
|
212
|
+
resolver_manager.on(:resolve, &method(:on_resolver_connection))
|
213
|
+
resolver_manager.on(:error, &method(:on_resolver_error))
|
214
|
+
resolver_manager.on(:close, &method(:on_resolver_close))
|
215
|
+
resolver_manager
|
216
|
+
end
|
217
|
+
|
218
|
+
manager = @resolvers[resolver_type]
|
219
|
+
|
220
|
+
(manager.is_a?(Resolver::Multi) && manager.early_resolve(connection)) || manager.resolvers.each do |resolver|
|
221
|
+
resolver.pool = self
|
222
|
+
yield resolver
|
205
223
|
end
|
224
|
+
|
225
|
+
manager
|
206
226
|
end
|
207
227
|
end
|
208
228
|
end
|