19
19
20
20
pub ( crate ) mod backoff;
21
21
22
+ mod dns;
23
+
22
24
#[ cfg( test) ]
23
25
pub ( crate ) mod mock_server;
24
26
@@ -110,6 +112,10 @@ pub enum ClientConfigKey {
110
112
ProxyCaCertificate ,
111
113
/// List of hosts that bypass proxy
112
114
ProxyExcludes ,
115
+ /// Randomize order addresses that the DNS resolution yields.
116
+ ///
117
+ /// This will spread the connections accross more servers.
118
+ RandomizeAddresses ,
113
119
/// Request timeout
114
120
///
115
121
/// The timeout is applied from when the request starts connecting until the
@@ -137,6 +143,7 @@ impl AsRef<str> for ClientConfigKey {
137
143
Self :: ProxyUrl => "proxy_url" ,
138
144
Self :: ProxyCaCertificate => "proxy_ca_certificate" ,
139
145
Self :: ProxyExcludes => "proxy_excludes" ,
146
+ Self :: RandomizeAddresses => "randomize_addresses" ,
140
147
Self :: Timeout => "timeout" ,
141
148
Self :: UserAgent => "user_agent" ,
142
149
}
@@ -163,6 +170,7 @@ impl FromStr for ClientConfigKey {
163
170
"proxy_url" => Ok ( Self :: ProxyUrl ) ,
164
171
"proxy_ca_certificate" => Ok ( Self :: ProxyCaCertificate ) ,
165
172
"proxy_excludes" => Ok ( Self :: ProxyExcludes ) ,
173
+ "randomize_addresses" => Ok ( Self :: RandomizeAddresses ) ,
166
174
"timeout" => Ok ( Self :: Timeout ) ,
167
175
"user_agent" => Ok ( Self :: UserAgent ) ,
168
176
_ => Err ( super :: Error :: UnknownConfigurationKey {
@@ -245,6 +253,7 @@ pub struct ClientOptions {
245
253
http2_max_frame_size : Option < ConfigValue < u32 > > ,
246
254
http1_only : ConfigValue < bool > ,
247
255
http2_only : ConfigValue < bool > ,
256
+ randomize_addresses : ConfigValue < bool > ,
248
257
}
249
258
250
259
impl Default for ClientOptions {
@@ -280,6 +289,7 @@ impl Default for ClientOptions {
280
289
// https://github.com/apache/arrow-rs/issues/5194
281
290
http1_only : true . into ( ) ,
282
291
http2_only : Default :: default ( ) ,
292
+ randomize_addresses : true . into ( ) ,
283
293
}
284
294
}
285
295
}
@@ -322,6 +332,9 @@ impl ClientOptions {
322
332
ClientConfigKey :: ProxyUrl => self . proxy_url = Some ( value. into ( ) ) ,
323
333
ClientConfigKey :: ProxyCaCertificate => self . proxy_ca_certificate = Some ( value. into ( ) ) ,
324
334
ClientConfigKey :: ProxyExcludes => self . proxy_excludes = Some ( value. into ( ) ) ,
335
+ ClientConfigKey :: RandomizeAddresses => {
336
+ self . randomize_addresses . parse ( value) ;
337
+ }
325
338
ClientConfigKey :: Timeout => self . timeout = Some ( ConfigValue :: Deferred ( value. into ( ) ) ) ,
326
339
ClientConfigKey :: UserAgent => {
327
340
self . user_agent = Some ( ConfigValue :: Deferred ( value. into ( ) ) )
@@ -358,6 +371,7 @@ impl ClientOptions {
358
371
ClientConfigKey :: ProxyUrl => self . proxy_url . clone ( ) ,
359
372
ClientConfigKey :: ProxyCaCertificate => self . proxy_ca_certificate . clone ( ) ,
360
373
ClientConfigKey :: ProxyExcludes => self . proxy_excludes . clone ( ) ,
374
+ ClientConfigKey :: RandomizeAddresses => Some ( self . randomize_addresses . to_string ( ) ) ,
361
375
ClientConfigKey :: Timeout => self . timeout . as_ref ( ) . map ( fmt_duration) ,
362
376
ClientConfigKey :: UserAgent => self
363
377
. user_agent
@@ -675,6 +689,10 @@ impl ClientOptions {
675
689
// transparently decompress the body via the non-default `gzip` feature.
676
690
builder = builder. no_gzip ( ) ;
677
691
692
+ if self . randomize_addresses . get ( ) ? {
693
+ builder = builder. dns_resolver ( Arc :: new ( dns:: ShuffleResolver ) ) ;
694
+ }
695
+
678
696
builder
679
697
. https_only ( !self . allow_http . get ( ) ?)
680
698
. build ( )
0 commit comments