The code at the end of this post is cut down from a program that's supposed to use hickory_resolver to do a bunch of DNS lookups concurrently. It won't compile, with the error
error[E0597]: `resolver` does not live long enough
--> src/bin/async-resolve-multi.rs:17:24
|
10 | let resolver = Resolver::builder_with_config(
| -------- binding `resolver` declared here
...
17 | let task = resolver.lookup_ip(host);
| ^^^^^^^^ borrowed value does not live long enough
18 | futures.spawn(task);
| ------------------- argument requires that `resolver` is borrowed for `'static`
...
21 | });
| - `resolver` dropped here while still borrowed
The issue appears to be that the future returned by resolver.lookup_ip contains an internal reference to the Resolver object, which makes it not 'static (since the Resolver object obviously does not have static lifetime).
I am at a loss for how to fix this. Advice for related problems seems to be to convert the reference that isn't 'static to an Arc<Box<>> or something along those lines, but that's not an option here because I don't control the code that's producing the troublesome reference. Does anyone have a suggestion?
use hickory_resolver::Resolver;
use hickory_resolver::config::ResolverConfig;
use hickory_resolver::name_server::TokioConnectionProvider;
use tokio::runtime::Runtime;
use tokio::task::JoinSet;
fn main() {
let rt = Runtime::new().unwrap();
let results = rt.block_on(async {
let resolver = Resolver::builder_with_config(
ResolverConfig::default(),
TokioConnectionProvider::default()
).build();
let mut futures = JoinSet::new();
for host in ["www.example.com.", "www.google.com."] {
let task = resolver.lookup_ip(host);
futures.spawn(task);
}
futures.join_all().await
});
for res in results {
match res {
Ok(r) => {
println!("{}:", r.query().name.to_utf8());
for addr in r.iter() {
println!("\t{}", addr);
}
}
Err(e) => {
println!("error: {e}");
}
}
}
}
Note: This question is closely related to Newb: Tokio::JoinSet and Hickory-Resolver::Resolver Tokio runtimes interfering. However, since that question was posted, the AsyncResolver interface has been removed from hickory_resolver. Also, I'm trying to use one Resolver object to make many DNS queries, in order to get the benefit of Resolver's internal caching.