diff --git a/actix-connect/CHANGES.md b/actix-connect/CHANGES.md index 4a3e86bc1d..d1086e2a07 100644 --- a/actix-connect/CHANGES.md +++ b/actix-connect/CHANGES.md @@ -1,5 +1,11 @@ # Changes +## [0.1.3] - 2019-04-11 + +### Changed + +* Start trust-dns default resolver on first use + ## [0.1.2] - 2019-04-04 ### Added diff --git a/actix-connect/Cargo.toml b/actix-connect/Cargo.toml index ebbf0ace76..4416be302b 100644 --- a/actix-connect/Cargo.toml +++ b/actix-connect/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-connect" -version = "0.1.2" +version = "0.1.3" authors = ["Nikolay Kim "] description = "Actix Connector - tcp connector service" keywords = ["network", "framework", "async", "futures"] @@ -30,9 +30,9 @@ ssl = ["openssl", "tokio-openssl"] uri = ["http"] [dependencies] -actix-service = "0.3.4" -actix-codec = "0.1.1" -actix-utils = "0.3.4" +actix-service = "0.3.6" +actix-codec = "0.1.2" +actix-utils = "0.3.5" derive_more = "0.14.0" either = "1.5.1" futures = "0.1.25" @@ -40,7 +40,7 @@ http = { version = "0.1.16", optional = true } log = "0.4" tokio-tcp = "0.1.3" tokio-current-thread = "0.1.5" -trust-dns-resolver = { version="0.11.0-alpha.2", default-features = false } +trust-dns-resolver = { version="0.11.0-alpha.3", default-features = false } # openssl openssl = { version="0.10", optional = true } diff --git a/actix-connect/src/lib.rs b/actix-connect/src/lib.rs index 5d4a6c62fe..ccd537d94a 100644 --- a/actix-connect/src/lib.rs +++ b/actix-connect/src/lib.rs @@ -8,6 +8,8 @@ #[macro_use] extern crate log; +use std::cell::RefCell; + mod connect; mod connector; mod error; @@ -46,18 +48,34 @@ pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver resolver } -pub fn start_default_resolver() -> AsyncResolver { - let (cfg, opts) = match read_system_conf() { - Ok((cfg, opts)) => (cfg, opts), - Err(e) => { - log::error!("TRust-DNS can not load system config: {}", e); - (ResolverConfig::default(), ResolverOpts::default()) +thread_local! { + static DEFAULT_RESOLVER: RefCell> = RefCell::new(None); +} + +pub(crate) fn get_default_resolver() -> AsyncResolver { + DEFAULT_RESOLVER.with(|cell| { + if let Some(ref resolver) = *cell.borrow() { + return resolver.clone(); } - }; - let (resolver, bg) = AsyncResolver::new(cfg, opts); - tokio_current_thread::spawn(bg); - resolver + let (cfg, opts) = match read_system_conf() { + Ok((cfg, opts)) => (cfg, opts), + Err(e) => { + log::error!("TRust-DNS can not load system config: {}", e); + (ResolverConfig::default(), ResolverOpts::default()) + } + }; + + let (resolver, bg) = AsyncResolver::new(cfg, opts); + tokio_current_thread::spawn(bg); + + *cell.borrow_mut() = Some(resolver.clone()); + resolver + }) +} + +pub fn start_default_resolver() -> AsyncResolver { + get_default_resolver() } /// Create tcp connector service diff --git a/actix-connect/src/resolver.rs b/actix-connect/src/resolver.rs index 21d0c28141..aba97ad97d 100644 --- a/actix-connect/src/resolver.rs +++ b/actix-connect/src/resolver.rs @@ -10,10 +10,11 @@ use trust_dns_resolver::{AsyncResolver, Background}; use crate::connect::{Address, Connect}; use crate::error::ConnectError; +use crate::get_default_resolver; /// DNS Resolver Service factory pub struct ResolverFactory { - resolver: AsyncResolver, + resolver: Option, _t: PhantomData, } @@ -21,13 +22,18 @@ impl ResolverFactory { /// Create new resolver instance with custom configuration and options. pub fn new(resolver: AsyncResolver) -> Self { ResolverFactory { - resolver, + resolver: Some(resolver), _t: PhantomData, } } +} - pub fn resolver(&self) -> &AsyncResolver { - &self.resolver +impl Default for ResolverFactory { + fn default() -> Self { + ResolverFactory { + resolver: None, + _t: PhantomData, + } } } @@ -58,7 +64,7 @@ impl NewService for ResolverFactory { /// DNS Resolver Service pub struct Resolver { - resolver: AsyncResolver, + resolver: Option, _t: PhantomData, } @@ -66,7 +72,16 @@ impl Resolver { /// Create new resolver instance with custom configuration and options. pub fn new(resolver: AsyncResolver) -> Self { Resolver { - resolver, + resolver: Some(resolver), + _t: PhantomData, + } + } +} + +impl Default for Resolver { + fn default() -> Self { + Resolver { + resolver: None, _t: PhantomData, } } @@ -100,7 +115,10 @@ impl Service for Resolver { Either::B(ok(req)) } else { trace!("DNS resolver: resolving host {:?}", req.host()); - Either::A(ResolverFuture::new(req, &self.resolver)) + if self.resolver.is_none() { + self.resolver = Some(get_default_resolver()); + } + Either::A(ResolverFuture::new(req, self.resolver.as_ref().unwrap())) } } }