[GH-ISSUE #454] Often receive error: No connections available #492

Closed
opened 2026-03-15 22:46:20 +03:00 by kerem · 1 comment
Owner

Originally created by @sintanial on GitHub (May 11, 2018).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/454

I use trust_dns_resolver to resolve domains, and often i receive error "No connections available"
I receiving it on many hosts, for example: www.gstatic.com, fonts.googleapis.com
Sometimes it's working perfect, sometimes failed :(

In my case, i spawn dns resolver in separate thread, because trust_dns_resolver use old tokio api, but my code use new tokio version, so for solve this collision i use channels and separate thread

pub fn run_trust_dns_resolver(close_rx: oneshot::Receiver<()>) -> mpsc::UnboundedSender<(String, oneshot::Sender<io::Result<LookupIp>>)> {
    let (resolve_task_tx, resolve_task_rx) = mpsc::unbounded();

    info!("[trust-dns] run resolver;");
    thread::spawn(move || {
        let mut event_loop = Core::new().unwrap();
        let resolver = ResolverFuture::new(ResolverConfig::default(), ResolverOpts::default(), &event_loop.handle());

        let handle = event_loop.handle().clone();

        let resolve_process = resolve_task_rx
            .map_err(|()| io::ErrorKind::UnexpectedEof.into())
            .for_each(|(host, responser): (String, oneshot::Sender<io::Result<LookupIp>>)| {
                debug!("[trust-dns] try resolve host: {:?}", host);
                let resolve_process = resolver
                    .lookup_ip(host.as_ref())
                    .then(move |res| {
                        match res {
                            Ok(lookup) => responser.send(Ok(lookup)),
                            Err(err) => responser.send(Err(io::Error::new(io::ErrorKind::Other, format!("failed to resolve dns; host={:?}, err={}", host, err)))),
                        };
                        Ok(())
                    });

                handle.spawn(resolve_process);

                Ok(())
            });

        let close_process = close_rx.then(|res| {
            debug!("[trust-dns] receive close signal");
            res
        }).map_err(|err| io::Error::new(io::ErrorKind::Other, err));

        let process = resolve_process.select(close_process).map(|ok| ok.0).map_err(|er| er.0);

        event_loop.run(process).unwrap();
        info!("[trust-dns] complete resolver");
    });

    resolve_task_tx
}

let (close_dns_tx, close_dns_rx) = oneshot::channel();
let dns_task_sender = run_trust_dns_resolver(close_dns_rx);

// when i need to resolve dns, i use dns_task_sender like this
let (dns_result_tx, dns_result_rx) = oneshot::channel();
dns_task_sender.unbounded_send((host, dns_result_tx));

tokio::spawn(dns_result_rx.and_then(|res: io::Result<LookupIp>| {
// res has resolved addresses
}));
Originally created by @sintanial on GitHub (May 11, 2018). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/454 I use trust_dns_resolver to resolve domains, and often i receive error "No connections available" I receiving it on many hosts, for example: www.gstatic.com, fonts.googleapis.com Sometimes it's working perfect, sometimes failed :( In my case, i spawn dns resolver in separate thread, because trust_dns_resolver use old tokio api, but my code use new tokio version, so for solve this collision i use channels and separate thread ```rust pub fn run_trust_dns_resolver(close_rx: oneshot::Receiver<()>) -> mpsc::UnboundedSender<(String, oneshot::Sender<io::Result<LookupIp>>)> { let (resolve_task_tx, resolve_task_rx) = mpsc::unbounded(); info!("[trust-dns] run resolver;"); thread::spawn(move || { let mut event_loop = Core::new().unwrap(); let resolver = ResolverFuture::new(ResolverConfig::default(), ResolverOpts::default(), &event_loop.handle()); let handle = event_loop.handle().clone(); let resolve_process = resolve_task_rx .map_err(|()| io::ErrorKind::UnexpectedEof.into()) .for_each(|(host, responser): (String, oneshot::Sender<io::Result<LookupIp>>)| { debug!("[trust-dns] try resolve host: {:?}", host); let resolve_process = resolver .lookup_ip(host.as_ref()) .then(move |res| { match res { Ok(lookup) => responser.send(Ok(lookup)), Err(err) => responser.send(Err(io::Error::new(io::ErrorKind::Other, format!("failed to resolve dns; host={:?}, err={}", host, err)))), }; Ok(()) }); handle.spawn(resolve_process); Ok(()) }); let close_process = close_rx.then(|res| { debug!("[trust-dns] receive close signal"); res }).map_err(|err| io::Error::new(io::ErrorKind::Other, err)); let process = resolve_process.select(close_process).map(|ok| ok.0).map_err(|er| er.0); event_loop.run(process).unwrap(); info!("[trust-dns] complete resolver"); }); resolve_task_tx } let (close_dns_tx, close_dns_rx) = oneshot::channel(); let dns_task_sender = run_trust_dns_resolver(close_dns_rx); // when i need to resolve dns, i use dns_task_sender like this let (dns_result_tx, dns_result_rx) = oneshot::channel(); dns_task_sender.unbounded_send((host, dns_result_tx)); tokio::spawn(dns_result_rx.and_then(|res: io::Result<LookupIp>| { // res has resolved addresses })); ```
kerem 2026-03-15 22:46:20 +03:00
Author
Owner

@bluejekyll commented on GitHub (May 11, 2018):

Thank you for the example. I’ll take a look a little later. Is it possible your dealing with any faulty connections?

A couple of things to try in the mean time: 1) increase the timeouts in the ResolverOpts, 2) if you can, try master, this has a new tokio library underneath that would be good to rule out as an issue.

<!-- gh-comment-id:388376403 --> @bluejekyll commented on GitHub (May 11, 2018): Thank you for the example. I’ll take a look a little later. Is it possible your dealing with any faulty connections? A couple of things to try in the mean time: 1) increase the timeouts in the ResolverOpts, 2) if you can, try master, this has a new tokio library underneath that would be good to rule out as an issue.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#492
No description provided.