Trait qiniu_http_client::Resolver
source · pub trait Resolver: DynClone + Debug + Sync + Send {
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult;
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult> { ... }
}
Expand description
域名解析的接口
同时提供阻塞接口和异步接口,异步接口则需要启用 async
功能
Required Methods§
sourcefn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
解析域名
该方法的异步版本为 Self::async_resolve
。
Provided Methods§
sourcefn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
Available on crate feature
async
only.异步解析域名
Examples found in repository?
More examples
src/client/resolver/timeout.rs (line 50)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
fn _resolve<R: Resolver + Clone + 'static>(
resolver: &TimeoutResolver<R>,
domain: &str,
opts: ResolveOptions,
) -> ResolveResult {
async_std::task::block_on(async move { resolver.async_resolve(domain, opts).await })
}
#[cfg(not(feature = "async"))]
fn _resolve<R: Resolver + Clone + 'static>(
resolver: &TimeoutResolver<R>,
domain: &str,
opts: ResolveOptions,
) -> ResolveResult {
use super::{super::super::spawn::spawn, owned_resolver_options::OwnedResolveOptions};
use crossbeam_channel::{bounded, Select, SelectTimeoutError};
use log::warn;
let (sender, receiver) = bounded(0);
{
let inner = resolver.to_owned();
let domain = domain.to_owned();
let opts = OwnedResolveOptions::from(opts);
if let Err(err) = spawn(
"qiniu.rust-sdk.http-client.resolver.TimeoutResolver.resolve".into(),
move || {
let opts = ResolveOptions::from(&opts);
sender.send(inner.resolver.resolve(&domain, opts)).ok();
},
) {
warn!("Timeout Resolver was failed to spawn thread to resolve domain: {}", err);
}
}
let mut sel = Select::new();
let op1 = sel.recv(&receiver);
let oper = sel.select_timeout(resolver.timeout);
return match oper {
Ok(op) => match op.index() {
i if i == op1 => op.recv(&receiver).unwrap(),
_ => unreachable!(),
},
Err(err) => Err(make_timeout_error(err, opts)),
};
fn make_timeout_error(err: SelectTimeoutError, opts: ResolveOptions) -> ResponseError {
let mut err = ResponseError::new(HttpResponseErrorKind::TimeoutError.into(), err);
if let Some(retried) = opts.retried() {
err = err.retried(retried);
}
err
}
}
}
#[cfg(feature = "async")]
#[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
fn async_resolve<'a>(&'a self, domain: &'a str, opts: ResolveOptions<'a>) -> BoxFuture<'a, ResolveResult> {
use futures::{pin_mut, select};
return Box::pin(async move {
let resolve_task = self.resolver.async_resolve(domain, opts).fuse();
let timeout_task = AsyncDelay::new(self.timeout).fuse();
pin_mut!(resolve_task);
pin_mut!(timeout_task);
select! {
resolve_result = resolve_task => resolve_result,
_ = timeout_task => Err(make_timeout_error(self.timeout, opts)),
}
});
fn make_timeout_error(timeout: Duration, opts: ResolveOptions) -> ResponseError {
let mut err = ResponseError::new_with_msg(
HttpResponseErrorKind::TimeoutError.into(),
format!("Failed to resolve domain in {timeout:?}"),
);
if let Some(retried) = opts.retried() {
err = err.retried(retried);
}
err
}
}
src/client/resolver/chained.rs (line 44)
40 41 42 43 44 45 46 47 48 49 50 51
fn async_resolve<'a>(&'a self, domain: &'a str, opts: ResolveOptions<'a>) -> BoxFuture<'a, ResolveResult> {
Box::pin(async move {
let mut last_result: Option<ResolveResult> = None;
for resolver in self.resolvers.iter() {
match resolver.async_resolve(domain, opts).await {
Ok(answers) if !answers.ip_addrs().is_empty() => return Ok(answers),
result => last_result = Some(result),
}
}
last_result.unwrap_or_else(|| Err(no_try_error(opts)))
})
}
src/client/call/utils.rs (lines 467-470)
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
pub(in super::super) async fn async_resolve(
parts: &InnerRequestParts<'_>,
domain_with_port: &DomainWithPort,
extensions: &mut Extensions,
retried: &RetriedStatsInfo,
) -> Result<Vec<IpAddrWithPort>, TryError> {
let answers = with_resolve_domain(parts, domain_with_port.domain(), extensions, retried, || async {
parts
.http_client()
.resolver()
.async_resolve(
domain_with_port.domain(),
ResolveOptions::builder().retried(retried).build(),
)
.await
});
return Ok(answers
.await?
.into_ip_addrs()
.iter()
.map(|&ip| IpAddrWithPort::new(ip, domain_with_port.port()))
.collect());
async fn with_resolve_domain<F: FnOnce() -> Fu, Fu: Future<Output = ResolveResult>>(
parts: &InnerRequestParts<'_>,
domain: &str,
extensions: &mut Extensions,
retried: &RetriedStatsInfo,
f: F,
) -> Result<ResolveAnswers, TryError> {
call_to_resolve_domain_callbacks(parts, domain, extensions, retried)?;
let answers = f()
.await
.map_err(|err| TryError::new(err, RetryDecision::TryNextServer.into()))?;
call_domain_resolved_callbacks(parts, domain, &answers, extensions, retried)?;
Ok(answers)
}
}
Trait Implementations§
Implementations on Foreign Types§
source§impl<'b, T: 'b + Resolver + ?Sized> Resolver for &'b Twhere
&'b T: DynClone + Debug + Sync + Send,
impl<'b, T: 'b + Resolver + ?Sized> Resolver for &'b Twhere
&'b T: DynClone + Debug + Sync + Send,
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
source§fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
Available on crate feature
async
only.source§impl<'b, T: 'b + Resolver + ?Sized> Resolver for &'b mut Twhere
&'b mut T: DynClone + Debug + Sync + Send,
impl<'b, T: 'b + Resolver + ?Sized> Resolver for &'b mut Twhere
&'b mut T: DynClone + Debug + Sync + Send,
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
source§fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
Available on crate feature
async
only.source§impl<T: Resolver + ?Sized> Resolver for Box<T>where
Box<T>: DynClone + Debug + Sync + Send,
impl<T: Resolver + ?Sized> Resolver for Box<T>where
Box<T>: DynClone + Debug + Sync + Send,
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
source§fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
Available on crate feature
async
only.source§impl<T: Resolver + ?Sized> Resolver for Rc<T>where
Rc<T>: DynClone + Debug + Sync + Send,
impl<T: Resolver + ?Sized> Resolver for Rc<T>where
Rc<T>: DynClone + Debug + Sync + Send,
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
source§fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
Available on crate feature
async
only.source§impl<T: Resolver + ?Sized> Resolver for Arc<T>where
Arc<T>: DynClone + Debug + Sync + Send,
impl<T: Resolver + ?Sized> Resolver for Arc<T>where
Arc<T>: DynClone + Debug + Sync + Send,
fn resolve(&self, domain: &str, opts: ResolveOptions<'_>) -> ResolveResult
source§fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
fn async_resolve<'a>(
&'a self,
domain: &'a str,
opts: ResolveOptions<'a>
) -> BoxFuture<'a, ResolveResult>
Available on crate feature
async
only.