qiniu_http_client/client/retrier/
mod.rs1mod error;
2mod limited;
3mod never;
4
5use super::{Idempotent, ResponseError, RetriedStatsInfo};
6use auto_impl::auto_impl;
7use dyn_clonable::clonable;
8use qiniu_http::RequestParts as HttpRequestParts;
9use std::{
10 fmt::{self, Debug},
11 ops::{Deref, DerefMut},
12};
13
14#[clonable]
18#[auto_impl(&, &mut, Box, Rc, Arc)]
19pub trait RequestRetrier: Clone + Debug + Sync + Send {
20 fn retry(&self, request: &mut HttpRequestParts, opts: RequestRetrierOptions<'_>) -> RetryResult;
22}
23
24#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
26#[non_exhaustive]
27pub enum RetryDecision {
28 #[default]
30 DontRetry,
31
32 TryNextServer,
34
35 TryAlternativeEndpoints,
37
38 RetryRequest,
40
41 Throttled,
43}
44
45#[derive(Copy, Debug, Clone)]
47pub struct RequestRetrierOptions<'a> {
48 idempotent: Idempotent,
49 response_error: &'a ResponseError,
50 retried: &'a RetriedStatsInfo,
51}
52
53impl<'a> RequestRetrierOptions<'a> {
54 #[inline]
56 pub fn builder(
57 response_error: &'a ResponseError,
58 retried: &'a RetriedStatsInfo,
59 ) -> RequestRetrierOptionsBuilder<'a> {
60 RequestRetrierOptionsBuilder::new(response_error, retried)
61 }
62
63 #[inline]
65 pub fn idempotent(&self) -> Idempotent {
66 self.idempotent
67 }
68
69 #[inline]
71 pub fn response_error(&self) -> &ResponseError {
72 self.response_error
73 }
74
75 #[inline]
77 pub fn retried(&self) -> &RetriedStatsInfo {
78 self.retried
79 }
80}
81
82#[derive(Copy, Debug, Clone)]
84pub struct RequestRetrierOptionsBuilder<'a>(RequestRetrierOptions<'a>);
85
86impl<'a> RequestRetrierOptionsBuilder<'a> {
87 #[inline]
89 pub fn new(response_error: &'a ResponseError, retried: &'a RetriedStatsInfo) -> Self {
90 Self(RequestRetrierOptions {
91 response_error,
92 retried,
93 idempotent: Default::default(),
94 })
95 }
96
97 #[inline]
99 pub fn idempotent(&mut self, idempotent: Idempotent) -> &mut Self {
100 self.0.idempotent = idempotent;
101 self
102 }
103
104 #[inline]
106 pub fn build(&self) -> RequestRetrierOptions<'a> {
107 self.0
108 }
109}
110
111#[derive(Clone)]
113pub struct RetryResult(RetryDecision);
114
115impl RetryResult {
116 #[inline]
118 pub fn decision(&self) -> RetryDecision {
119 self.0
120 }
121
122 #[inline]
124 pub fn decision_mut(&mut self) -> &mut RetryDecision {
125 &mut self.0
126 }
127}
128
129impl From<RetryDecision> for RetryResult {
130 #[inline]
131 fn from(decision: RetryDecision) -> Self {
132 Self(decision)
133 }
134}
135
136impl From<RetryResult> for RetryDecision {
137 #[inline]
138 fn from(result: RetryResult) -> Self {
139 result.0
140 }
141}
142
143impl AsRef<RetryDecision> for RetryResult {
144 #[inline]
145 fn as_ref(&self) -> &RetryDecision {
146 &self.0
147 }
148}
149
150impl AsMut<RetryDecision> for RetryResult {
151 #[inline]
152 fn as_mut(&mut self) -> &mut RetryDecision {
153 &mut self.0
154 }
155}
156
157impl Deref for RetryResult {
158 type Target = RetryDecision;
159
160 #[inline]
161 fn deref(&self) -> &Self::Target {
162 &self.0
163 }
164}
165
166impl DerefMut for RetryResult {
167 #[inline]
168 fn deref_mut(&mut self) -> &mut Self::Target {
169 &mut self.0
170 }
171}
172
173impl Debug for RetryResult {
174 #[inline]
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 self.0.fmt(f)
177 }
178}
179
180pub use error::ErrorRetrier;
181pub use limited::LimitedRetrier;
182pub use never::NeverRetrier;