use std::net::ToSocketAddrs;
use rand::prelude::SliceRandom;
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
use tokio::task::JoinSet;
type DynErr = Box<dyn std::error::Error + Send + Sync>;
#[derive(Debug)]
pub(crate) struct ShuffleResolver;
impl Resolve for ShuffleResolver {
fn resolve(&self, name: Name) -> Resolving {
Box::pin(async move {
let mut tasks = JoinSet::new();
tasks.spawn_blocking(move || {
let it = (name.as_str(), 0).to_socket_addrs()?;
let mut addrs = it.collect::<Vec<_>>();
addrs.shuffle(&mut rand::rng());
Ok(Box::new(addrs.into_iter()) as Addrs)
});
tasks
.join_next()
.await
.expect("spawned on task")
.map_err(|err| Box::new(err) as DynErr)?
})
}
}