feat(dns): tokio_threadpool::blocking resolver
Unlike the default resolver, this avoids spawning extra dedicated threads but only works on the multi-threaded Tokio runtime. Closes #1676
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							6fe532da4c
						
					
				
				
					commit
					1e8d6439cf
				
			| @@ -35,6 +35,7 @@ tokio-io = "0.1" | |||||||
| tokio-reactor = { version = "0.1", optional = true } | tokio-reactor = { version = "0.1", optional = true } | ||||||
| tokio-tcp = { version = "0.1", optional = true } | tokio-tcp = { version = "0.1", optional = true } | ||||||
| tokio-timer = { version = "0.2", optional = true } | tokio-timer = { version = "0.2", optional = true } | ||||||
|  | tokio-threadpool = { version = "0.1", optional = true } | ||||||
| want = "0.0.6" | want = "0.0.6" | ||||||
|  |  | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| @@ -62,6 +63,7 @@ runtime = [ | |||||||
|     "tokio-reactor", |     "tokio-reactor", | ||||||
|     "tokio-tcp", |     "tokio-tcp", | ||||||
|     "tokio-timer", |     "tokio-timer", | ||||||
|  |     "tokio-threadpool", | ||||||
| ] | ] | ||||||
| nightly = [] | nightly = [] | ||||||
| __internal_flaky_tests = [] | __internal_flaky_tests = [] | ||||||
|   | |||||||
| @@ -13,6 +13,9 @@ use futures_cpupool::{Builder as CpuPoolBuilder}; | |||||||
|  |  | ||||||
| use self::sealed::GaiTask; | use self::sealed::GaiTask; | ||||||
|  |  | ||||||
|  | #[cfg(feature = "runtime")] | ||||||
|  | pub use self::blocking::{TokioThreadpoolGaiFuture, TokioThreadpoolGaiResolver}; | ||||||
|  |  | ||||||
| /// Resolve a hostname to a set of IP addresses. | /// Resolve a hostname to a set of IP addresses. | ||||||
| pub trait Resolve { | pub trait Resolve { | ||||||
|     /// The set of IP addresses to try to connect to. |     /// The set of IP addresses to try to connect to. | ||||||
| @@ -239,6 +242,50 @@ pub(super) mod sealed { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(feature = "runtime")] | ||||||
|  | mod blocking { | ||||||
|  |     use futures::{Async, Future, Poll}; | ||||||
|  |     use std::io; | ||||||
|  |     use std::net::ToSocketAddrs; | ||||||
|  |     use tokio_threadpool; | ||||||
|  |  | ||||||
|  |     use super::{Name, IpAddrs, GaiAddrs, Resolve}; | ||||||
|  |  | ||||||
|  |     /// A resolver using `getaddrinfo` calls via the `tokio_threadpool::blocking` API. | ||||||
|  |     ///  | ||||||
|  |     /// Unlike the `GaiResolver` this will not spawn dedicated threads, but only works when running on the | ||||||
|  |     /// multi-threaded Tokio runtime. | ||||||
|  |     #[derive(Clone)] | ||||||
|  |     pub struct TokioThreadpoolGaiResolver(()); | ||||||
|  |  | ||||||
|  |     pub struct TokioThreadpoolGaiFuture { | ||||||
|  |         name: Name, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl Resolve for TokioThreadpoolGaiResolver { | ||||||
|  |         type Addrs = GaiAddrs; | ||||||
|  |         type Future = TokioThreadpoolGaiFuture; | ||||||
|  |  | ||||||
|  |         fn resolve(&self, name: Name) -> TokioThreadpoolGaiFuture { | ||||||
|  |             TokioThreadpoolGaiFuture { name } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl Future for TokioThreadpoolGaiFuture { | ||||||
|  |         type Item = GaiAddrs; | ||||||
|  |         type Error = io::Error; | ||||||
|  |  | ||||||
|  |         fn poll(&mut self) -> Poll<GaiAddrs, io::Error> { | ||||||
|  |             match tokio_threadpool::blocking(|| (self.name.as_str(), 0).to_socket_addrs()) { | ||||||
|  |                 Ok(Async::Ready(Ok(iter))) => Ok(Async::Ready(GaiAddrs { inner: IpAddrs { iter } })), | ||||||
|  |                 Ok(Async::Ready(Err(e))) => Err(e), | ||||||
|  |                 Ok(Async::NotReady) => Ok(Async::NotReady), | ||||||
|  |                 Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)), | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use std::net::{Ipv4Addr, Ipv6Addr}; |     use std::net::{Ipv4Addr, Ipv6Addr}; | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ extern crate time; | |||||||
| #[cfg(feature = "runtime")] extern crate tokio_reactor; | #[cfg(feature = "runtime")] extern crate tokio_reactor; | ||||||
| #[cfg(feature = "runtime")] extern crate tokio_tcp; | #[cfg(feature = "runtime")] extern crate tokio_tcp; | ||||||
| #[cfg(feature = "runtime")] extern crate tokio_timer; | #[cfg(feature = "runtime")] extern crate tokio_timer; | ||||||
|  | #[cfg(feature = "runtime")] extern crate tokio_threadpool; | ||||||
| extern crate want; | extern crate want; | ||||||
|  |  | ||||||
| #[cfg(all(test, feature = "nightly"))] | #[cfg(all(test, feature = "nightly"))] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user