|
| 1 | +use itertools::Itertools; |
1 | 2 | use tokio::net::lookup_host; |
2 | 3 | use tracing::warn; |
3 | 4 | use uuid::Uuid; |
@@ -270,27 +271,23 @@ pub(crate) struct ResolvedContactPoint { |
270 | 271 | // The resolution may return multiple IPs and the function returns one of them. |
271 | 272 | // It prefers to return IPv4s first, and only if there are none, IPv6s. |
272 | 273 | pub(crate) async fn resolve_hostname(hostname: &str) -> Result<SocketAddr, io::Error> { |
273 | | - let mut ret = None; |
274 | | - let addrs: Vec<SocketAddr> = match lookup_host(hostname).await { |
275 | | - Ok(addrs) => addrs.collect(), |
| 274 | + let addrs = match lookup_host(hostname).await { |
| 275 | + Ok(addrs) => itertools::Either::Left(addrs), |
276 | 276 | // Use a default port in case of error, but propagate the original error on failure |
277 | | - Err(e) => lookup_host((hostname, 9042)).await.or(Err(e))?.collect(), |
278 | | - }; |
279 | | - for a in addrs { |
280 | | - match a { |
281 | | - SocketAddr::V4(_) => return Ok(a), |
282 | | - _ => { |
283 | | - ret = Some(a); |
284 | | - } |
| 277 | + Err(e) => { |
| 278 | + let addrs = lookup_host((hostname, 9042)).await.or(Err(e))?; |
| 279 | + itertools::Either::Right(addrs) |
285 | 280 | } |
286 | | - } |
| 281 | + }; |
287 | 282 |
|
288 | | - ret.ok_or_else(|| { |
289 | | - io::Error::new( |
290 | | - io::ErrorKind::Other, |
291 | | - format!("Empty address list returned by DNS for {}", hostname), |
292 | | - ) |
293 | | - }) |
| 283 | + addrs |
| 284 | + .find_or_last(|addr| matches!(addr, SocketAddr::V4(_))) |
| 285 | + .ok_or_else(|| { |
| 286 | + io::Error::new( |
| 287 | + io::ErrorKind::Other, |
| 288 | + format!("Empty address list returned by DNS for {}", hostname), |
| 289 | + ) |
| 290 | + }) |
294 | 291 | } |
295 | 292 |
|
296 | 293 | /// Transforms the given [`InternalKnownNode`]s into [`ContactPoint`]s. |
@@ -323,18 +320,20 @@ pub(crate) async fn resolve_contact_points( |
323 | 320 | }) => to_resolve.push((hostname, Some(datacenter.clone()))), |
324 | 321 | }; |
325 | 322 | } |
326 | | - let resolve_futures = to_resolve.iter().map(|(hostname, datacenter)| async move { |
327 | | - match resolve_hostname(hostname).await { |
328 | | - Ok(address) => Some(ResolvedContactPoint { |
329 | | - address, |
330 | | - datacenter: datacenter.clone(), |
331 | | - }), |
332 | | - Err(e) => { |
333 | | - warn!("Hostname resolution failed for {}: {}", hostname, &e); |
334 | | - None |
| 323 | + let resolve_futures = to_resolve |
| 324 | + .into_iter() |
| 325 | + .map(|(hostname, datacenter)| async move { |
| 326 | + match resolve_hostname(hostname).await { |
| 327 | + Ok(address) => Some(ResolvedContactPoint { |
| 328 | + address, |
| 329 | + datacenter, |
| 330 | + }), |
| 331 | + Err(e) => { |
| 332 | + warn!("Hostname resolution failed for {}: {}", hostname, &e); |
| 333 | + None |
| 334 | + } |
335 | 335 | } |
336 | | - } |
337 | | - }); |
| 336 | + }); |
338 | 337 | let resolved: Vec<_> = futures::future::join_all(resolve_futures).await; |
339 | 338 | initial_peers.extend(resolved.into_iter().flatten()); |
340 | 339 |
|
|
0 commit comments