Files
2026-10-12 07:22:52 -07:00

69 lines
2.2 KiB
Rust

//! This example shows how to create a resolver that uses the tokio multithreaded runtime. This is how
//! you might integrate the resolver into a more complex application.
fn main() {
tracing_subscriber::fmt::init();
run();
}
fn run() {
use tokio::runtime::Runtime;
// Set up the standard tokio runtime (multithreaded by default).
let runtime = Runtime::new().expect("Failed to create runtime");
let resolver = {
// To make this independent, if targeting macOS, BSD, Linux, or Windows, we can use the system's configuration:
#[cfg(any(unix, windows))]
{
use hickory_resolver::{TokioResolver, net::runtime::TokioRuntimeProvider};
// use the system resolver configuration
TokioResolver::builder(TokioRuntimeProvider::default())
.expect("failed to create resolver")
.build()
.unwrap()
}
// For other operating systems, we can use one of the preconfigured definitions
#[cfg(not(any(unix, windows)))]
{
// Directly reference the config types
use hickory_resolver::{
Resolver,
config::{GOOGLE, ResolverConfig, ResolverOpts},
};
// Get a new resolver with the google nameservers as the upstream recursive resolvers
Resolver::tokio(ResolverConfig::udp_and_tcp(), ResolverOpts::default())
}
};
// Create some futures representing name lookups.
let names = &["www.google.com", "www.reddit.com", "www.wikipedia.org"];
let mut futures = names
.iter()
.map(|name| (name, resolver.lookup_ip(*name)))
.collect::<Vec<_>>();
// Go through the list of resolution operations and wait for them to complete.
for (name, lookup) in futures.drain(..) {
let ips = runtime
.block_on(lookup)
.expect("Failed completing lookup future")
.iter()
.collect::<Vec<_>>();
println!("{name} resolved to {ips:?}");
}
// Drop the resolver, which means that the runtime will become idle.
drop(futures);
drop(resolver);
}
#[test]
fn test_multithreaded_runtime() {
test_support::subscribe();
run()
}