1919
2020pub ( crate ) mod backoff;
2121
22+ mod dns;
23+
2224#[ cfg( test) ]
2325pub ( crate ) mod mock_server;
2426
@@ -110,6 +112,10 @@ pub enum ClientConfigKey {
110112 ProxyCaCertificate ,
111113 /// List of hosts that bypass proxy
112114 ProxyExcludes ,
115+ /// Randomize order addresses that the DNS resolution yields.
116+ ///
117+ /// This will spread the connections accross more servers.
118+ RandomizeAddresses ,
113119 /// Request timeout
114120 ///
115121 /// The timeout is applied from when the request starts connecting until the
@@ -137,6 +143,7 @@ impl AsRef<str> for ClientConfigKey {
137143 Self :: ProxyUrl => "proxy_url" ,
138144 Self :: ProxyCaCertificate => "proxy_ca_certificate" ,
139145 Self :: ProxyExcludes => "proxy_excludes" ,
146+ Self :: RandomizeAddresses => "randomize_addresses" ,
140147 Self :: Timeout => "timeout" ,
141148 Self :: UserAgent => "user_agent" ,
142149 }
@@ -163,6 +170,7 @@ impl FromStr for ClientConfigKey {
163170 "proxy_url" => Ok ( Self :: ProxyUrl ) ,
164171 "proxy_ca_certificate" => Ok ( Self :: ProxyCaCertificate ) ,
165172 "proxy_excludes" => Ok ( Self :: ProxyExcludes ) ,
173+ "randomize_addresses" => Ok ( Self :: RandomizeAddresses ) ,
166174 "timeout" => Ok ( Self :: Timeout ) ,
167175 "user_agent" => Ok ( Self :: UserAgent ) ,
168176 _ => Err ( super :: Error :: UnknownConfigurationKey {
@@ -245,6 +253,7 @@ pub struct ClientOptions {
245253 http2_max_frame_size : Option < ConfigValue < u32 > > ,
246254 http1_only : ConfigValue < bool > ,
247255 http2_only : ConfigValue < bool > ,
256+ randomize_addresses : ConfigValue < bool > ,
248257}
249258
250259impl Default for ClientOptions {
@@ -280,6 +289,7 @@ impl Default for ClientOptions {
280289 // https://github.com/apache/arrow-rs/issues/5194
281290 http1_only : true . into ( ) ,
282291 http2_only : Default :: default ( ) ,
292+ randomize_addresses : true . into ( ) ,
283293 }
284294 }
285295}
@@ -322,6 +332,9 @@ impl ClientOptions {
322332 ClientConfigKey :: ProxyUrl => self . proxy_url = Some ( value. into ( ) ) ,
323333 ClientConfigKey :: ProxyCaCertificate => self . proxy_ca_certificate = Some ( value. into ( ) ) ,
324334 ClientConfigKey :: ProxyExcludes => self . proxy_excludes = Some ( value. into ( ) ) ,
335+ ClientConfigKey :: RandomizeAddresses => {
336+ self . randomize_addresses . parse ( value) ;
337+ }
325338 ClientConfigKey :: Timeout => self . timeout = Some ( ConfigValue :: Deferred ( value. into ( ) ) ) ,
326339 ClientConfigKey :: UserAgent => {
327340 self . user_agent = Some ( ConfigValue :: Deferred ( value. into ( ) ) )
@@ -358,6 +371,7 @@ impl ClientOptions {
358371 ClientConfigKey :: ProxyUrl => self . proxy_url . clone ( ) ,
359372 ClientConfigKey :: ProxyCaCertificate => self . proxy_ca_certificate . clone ( ) ,
360373 ClientConfigKey :: ProxyExcludes => self . proxy_excludes . clone ( ) ,
374+ ClientConfigKey :: RandomizeAddresses => Some ( self . randomize_addresses . to_string ( ) ) ,
361375 ClientConfigKey :: Timeout => self . timeout . as_ref ( ) . map ( fmt_duration) ,
362376 ClientConfigKey :: UserAgent => self
363377 . user_agent
@@ -675,6 +689,10 @@ impl ClientOptions {
675689 // transparently decompress the body via the non-default `gzip` feature.
676690 builder = builder. no_gzip ( ) ;
677691
692+ if self . randomize_addresses . get ( ) ? {
693+ builder = builder. dns_resolver ( Arc :: new ( dns:: ShuffleResolver ) ) ;
694+ }
695+
678696 builder
679697 . https_only ( !self . allow_http . get ( ) ?)
680698 . build ( )
0 commit comments