Struct qiniu_http_client::BackoffOptionsBuilder
source · pub struct BackoffOptionsBuilder<'a>(_);
Expand description
退避时长的选项构建器
Implementations§
source§impl<'a> BackoffOptionsBuilder<'a>
impl<'a> BackoffOptionsBuilder<'a>
sourcepub fn new(
response_error: &'a ResponseError,
retried: &'a RetriedStatsInfo
) -> Self
pub fn new(
response_error: &'a ResponseError,
retried: &'a RetriedStatsInfo
) -> Self
创建退避时长的选项构建器
sourcepub fn retry_decision(&mut self, decision: RetryDecision) -> &mut Self
pub fn retry_decision(&mut self, decision: RetryDecision) -> &mut Self
设置重试决定
Examples found in repository?
src/client/call/send_http_request.rs (line 61)
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
fn backoff(
http_request: &mut SyncHttpRequest<'_>,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
err: &TryError,
) -> Result<(), TryError> {
let delay = parts
.http_client()
.backoff()
.time(
http_request,
BackoffOptions::builder(err.response_error(), retried)
.retry_decision(err.retry_decision())
.build(),
)
.duration();
call_before_backoff_callbacks(parts, http_request, retried, delay)?;
if delay > Duration::new(0, 0) {
sleep(delay);
}
call_after_backoff_callbacks(parts, http_request, retried, delay)?;
Ok(())
}
}
fn need_backoff(err: &TryError) -> bool {
matches!(
err.retry_decision(),
RetryDecision::RetryRequest | RetryDecision::Throttled | RetryDecision::TryNextServer
)
}
fn need_retry_after_backoff(err: &TryError) -> bool {
matches!(
err.retry_decision(),
RetryDecision::RetryRequest | RetryDecision::Throttled
)
}
fn handle_response_error(
mut response_error: ResponseError,
http_parts: &mut HttpRequestParts,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
) -> TryError {
let retry_result = parts.http_client().request_retrier().retry(
http_parts,
RequestRetrierOptions::builder(&response_error, retried)
.idempotent(parts.idempotent())
.build(),
);
retried.increase_current_endpoint();
response_error = response_error.set_retry_decision(retry_result.decision());
TryError::new(response_error, retry_result)
}
#[cfg(feature = "async")]
mod async_send {
use super::{
super::{super::AsyncResponse, utils::async_judge},
*,
};
use futures_timer::Delay as AsyncDelay;
use qiniu_http::AsyncRequest as AsyncHttpRequest;
pub(in super::super) async fn async_send_http_request(
http_request: &mut AsyncHttpRequest<'_>,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
) -> Result<AsyncResponse, TryError> {
loop {
let mut response = parts
.http_client()
.http_caller()
.async_call(http_request)
.await
.map_err(ResponseError::from)
.and_then(|response| {
call_response_callbacks(parts, http_request, retried, response.parts()).map(|_| response)
})
.map(AsyncResponse::from);
if let Ok(resp) = response {
response = async_judge(resp, retried).await
};
let response = response.map_err(|err| handle_response_error(err, http_request, parts, retried));
match response {
Ok(response) => {
return Ok(response);
}
Err(mut err) => {
call_error_callbacks(parts, http_request, retried, err.response_error_mut())?;
if need_backoff(&err) {
backoff(http_request, parts, retried, &err).await?;
if need_retry_after_backoff(&err) {
continue;
}
}
return Err(err);
}
}
}
async fn backoff(
http_request: &mut AsyncHttpRequest<'_>,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
err: &TryError,
) -> Result<(), TryError> {
let delay = parts
.http_client()
.backoff()
.time(
http_request,
BackoffOptions::builder(err.response_error(), retried)
.retry_decision(err.retry_decision())
.build(),
)
.duration();
call_before_backoff_callbacks(parts, http_request, retried, delay)?;
if delay > Duration::new(0, 0) {
async_sleep(delay).await;
}
call_after_backoff_callbacks(parts, http_request, retried, delay)?;
Ok(())
}
sourcepub fn build(&self) -> BackoffOptions<'a>
pub fn build(&self) -> BackoffOptions<'a>
构建退避时长的选项
Examples found in repository?
src/client/call/send_http_request.rs (line 62)
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
fn backoff(
http_request: &mut SyncHttpRequest<'_>,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
err: &TryError,
) -> Result<(), TryError> {
let delay = parts
.http_client()
.backoff()
.time(
http_request,
BackoffOptions::builder(err.response_error(), retried)
.retry_decision(err.retry_decision())
.build(),
)
.duration();
call_before_backoff_callbacks(parts, http_request, retried, delay)?;
if delay > Duration::new(0, 0) {
sleep(delay);
}
call_after_backoff_callbacks(parts, http_request, retried, delay)?;
Ok(())
}
}
fn need_backoff(err: &TryError) -> bool {
matches!(
err.retry_decision(),
RetryDecision::RetryRequest | RetryDecision::Throttled | RetryDecision::TryNextServer
)
}
fn need_retry_after_backoff(err: &TryError) -> bool {
matches!(
err.retry_decision(),
RetryDecision::RetryRequest | RetryDecision::Throttled
)
}
fn handle_response_error(
mut response_error: ResponseError,
http_parts: &mut HttpRequestParts,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
) -> TryError {
let retry_result = parts.http_client().request_retrier().retry(
http_parts,
RequestRetrierOptions::builder(&response_error, retried)
.idempotent(parts.idempotent())
.build(),
);
retried.increase_current_endpoint();
response_error = response_error.set_retry_decision(retry_result.decision());
TryError::new(response_error, retry_result)
}
#[cfg(feature = "async")]
mod async_send {
use super::{
super::{super::AsyncResponse, utils::async_judge},
*,
};
use futures_timer::Delay as AsyncDelay;
use qiniu_http::AsyncRequest as AsyncHttpRequest;
pub(in super::super) async fn async_send_http_request(
http_request: &mut AsyncHttpRequest<'_>,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
) -> Result<AsyncResponse, TryError> {
loop {
let mut response = parts
.http_client()
.http_caller()
.async_call(http_request)
.await
.map_err(ResponseError::from)
.and_then(|response| {
call_response_callbacks(parts, http_request, retried, response.parts()).map(|_| response)
})
.map(AsyncResponse::from);
if let Ok(resp) = response {
response = async_judge(resp, retried).await
};
let response = response.map_err(|err| handle_response_error(err, http_request, parts, retried));
match response {
Ok(response) => {
return Ok(response);
}
Err(mut err) => {
call_error_callbacks(parts, http_request, retried, err.response_error_mut())?;
if need_backoff(&err) {
backoff(http_request, parts, retried, &err).await?;
if need_retry_after_backoff(&err) {
continue;
}
}
return Err(err);
}
}
}
async fn backoff(
http_request: &mut AsyncHttpRequest<'_>,
parts: &InnerRequestParts<'_>,
retried: &mut RetriedStatsInfo,
err: &TryError,
) -> Result<(), TryError> {
let delay = parts
.http_client()
.backoff()
.time(
http_request,
BackoffOptions::builder(err.response_error(), retried)
.retry_decision(err.retry_decision())
.build(),
)
.duration();
call_before_backoff_callbacks(parts, http_request, retried, delay)?;
if delay > Duration::new(0, 0) {
async_sleep(delay).await;
}
call_after_backoff_callbacks(parts, http_request, retried, delay)?;
Ok(())
}
Trait Implementations§
source§impl<'a> Clone for BackoffOptionsBuilder<'a>
impl<'a> Clone for BackoffOptionsBuilder<'a>
source§fn clone(&self) -> BackoffOptionsBuilder<'a>
fn clone(&self) -> BackoffOptionsBuilder<'a>
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl<'a> Debug for BackoffOptionsBuilder<'a>
impl<'a> Debug for BackoffOptionsBuilder<'a>
impl<'a> Copy for BackoffOptionsBuilder<'a>
Auto Trait Implementations§
impl<'a> !RefUnwindSafe for BackoffOptionsBuilder<'a>
impl<'a> Send for BackoffOptionsBuilder<'a>
impl<'a> Sync for BackoffOptionsBuilder<'a>
impl<'a> Unpin for BackoffOptionsBuilder<'a>
impl<'a> !UnwindSafe for BackoffOptionsBuilder<'a>
Blanket Implementations§
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Pipes by value. This is generally the method you want to use. Read more
source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
Borrows
self
and passes that borrow into the pipe function. Read moresource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
Mutably borrows
self
and passes that borrow into the pipe function. Read moresource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
Borrows
self
, then passes self.as_ref()
into the pipe function.source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
Mutably borrows
self
, then passes self.as_mut()
into the pipe
function.source§impl<T> Tap for T
impl<T> Tap for T
source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Immutable access to the
Borrow<B>
of a value. Read moresource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
Mutable access to the
BorrowMut<B>
of a value. Read moresource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
Immutable access to the
AsRef<R>
view of a value. Read moresource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
Mutable access to the
AsMut<R>
view of a value. Read moresource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
Immutable access to the
Deref::Target
of a value. Read moresource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Mutable access to the
Deref::Target
of a value. Read moresource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
Calls
.tap()
only in debug builds, and is erased in release builds.source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
Calls
.tap_mut()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Calls
.tap_borrow()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
Calls
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
Calls
.tap_ref()
only in debug builds, and is erased in release
builds.source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
Calls
.tap_ref_mut()
only in debug builds, and is erased in release
builds.