Skip to content

Commit cdc321b

Browse files
feat: Retry all HTTP requests (#2523)
Fixes #2209
1 parent dbdeba7 commit cdc321b

File tree

1 file changed

+11
-60
lines changed

1 file changed

+11
-60
lines changed

src/api/mod.rs

Lines changed: 11 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ lazy_static! {
6565
static ref API: Mutex<Option<Arc<Api>>> = Mutex::new(None);
6666
}
6767

68+
const RETRY_STATUS_CODES: &[u32] = &[
69+
http::HTTP_STATUS_502_BAD_GATEWAY,
70+
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
71+
http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
72+
http::HTTP_STATUS_507_INSUFFICIENT_STORAGE,
73+
];
74+
6875
/// Helper for the API access.
6976
/// Implements the low-level API access methods, and provides high-level implementations for interacting
7077
/// with portions of the API that do not require authentication via an auth token.
@@ -113,8 +120,6 @@ pub struct ApiRequest {
113120
is_authenticated: bool,
114121
body: Option<Vec<u8>>,
115122
progress_bar_mode: ProgressBarMode,
116-
max_retries: u32,
117-
retry_on_statuses: &'static [u32],
118123
}
119124

120125
/// Represents an API response.
@@ -395,14 +400,6 @@ impl Api {
395400
let request = self
396401
.request(Method::Post, url, None)?
397402
.with_form_data(form)?
398-
.with_retry(
399-
self.config.max_retries(),
400-
&[
401-
http::HTTP_STATUS_502_BAD_GATEWAY,
402-
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
403-
http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
404-
],
405-
)
406403
.progress_bar_mode(progress_bar_mode);
407404

408405
// The request is performed to an absolute URL. Thus, `Self::request()` will
@@ -967,14 +964,6 @@ impl<'a> AuthenticatedApi<'a> {
967964

968965
self.request(Method::Post, &url)?
969966
.with_json_body(request)?
970-
.with_retry(
971-
self.api.config.max_retries(),
972-
&[
973-
http::HTTP_STATUS_502_BAD_GATEWAY,
974-
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
975-
http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
976-
],
977-
)
978967
.send()?
979968
.convert_rnf(ApiErrorKind::ProjectNotFound)
980969
}
@@ -1000,14 +989,6 @@ impl<'a> AuthenticatedApi<'a> {
1000989
version: None,
1001990
dist: None,
1002991
})?
1003-
.with_retry(
1004-
self.api.config.max_retries(),
1005-
&[
1006-
http::HTTP_STATUS_502_BAD_GATEWAY,
1007-
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
1008-
http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
1009-
],
1010-
)
1011992
.send()?
1012993
.convert_rnf(ApiErrorKind::ReleaseNotFound)
1013994
}
@@ -1031,14 +1012,6 @@ impl<'a> AuthenticatedApi<'a> {
10311012
version,
10321013
dist,
10331014
})?
1034-
.with_retry(
1035-
self.api.config.max_retries(),
1036-
&[
1037-
http::HTTP_STATUS_502_BAD_GATEWAY,
1038-
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
1039-
http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
1040-
],
1041-
)
10421015
.send()?
10431016
.convert_rnf(ApiErrorKind::ReleaseNotFound)
10441017
}
@@ -1407,10 +1380,6 @@ impl RegionSpecificApi<'_> {
14071380
form.part("file").file(file).add()?;
14081381
self.request(Method::Post, &path)?
14091382
.with_form_data(form)?
1410-
.with_retry(
1411-
self.api.api.config.max_retries(),
1412-
&[http::HTTP_STATUS_507_INSUFFICIENT_STORAGE],
1413-
)
14141383
.progress_bar_mode(ProgressBarMode::Request)
14151384
.send()?
14161385
.convert()
@@ -1466,14 +1435,6 @@ impl RegionSpecificApi<'_> {
14661435
let resp = self
14671436
.request(Method::Post, &path)?
14681437
.with_form_data(form)?
1469-
.with_retry(
1470-
self.api.api.config.max_retries(),
1471-
&[
1472-
http::HTTP_STATUS_502_BAD_GATEWAY,
1473-
http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
1474-
http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
1475-
],
1476-
)
14771438
.progress_bar_mode(progress_bar_mode)
14781439
.send()?;
14791440
if resp.status() == 409 {
@@ -1661,8 +1622,6 @@ impl ApiRequest {
16611622
is_authenticated: false,
16621623
body: None,
16631624
progress_bar_mode: ProgressBarMode::Disabled,
1664-
max_retries: 0,
1665-
retry_on_statuses: &[],
16661625
};
16671626

16681627
let request = match auth {
@@ -1736,13 +1695,6 @@ impl ApiRequest {
17361695
self
17371696
}
17381697

1739-
pub fn with_retry(mut self, max_retries: u32, retry_on_statuses: &'static [u32]) -> Self {
1740-
self.max_retries = max_retries;
1741-
self.retry_on_statuses = retry_on_statuses;
1742-
1743-
self
1744-
}
1745-
17461698
/// Get a copy of the header list
17471699
fn get_headers(&self) -> curl::easy::List {
17481700
let mut result = curl::easy::List::new();
@@ -1771,18 +1723,17 @@ impl ApiRequest {
17711723

17721724
/// Sends the request and reads the response body into the response object.
17731725
pub fn send(mut self) -> ApiResult<ApiResponse> {
1726+
let max_retries = Config::current().max_retries();
1727+
17741728
let mut backoff = get_default_backoff();
17751729
let mut retry_number = 0;
17761730

17771731
loop {
17781732
let mut out = vec![];
1779-
debug!(
1780-
"retry number {}, max retries: {}",
1781-
retry_number, self.max_retries,
1782-
);
1733+
debug!("retry number {retry_number}, max retries: {max_retries}",);
17831734

17841735
let mut rv = self.send_into(&mut out)?;
1785-
if retry_number >= self.max_retries || !self.retry_on_statuses.contains(&rv.status) {
1736+
if retry_number >= max_retries || !RETRY_STATUS_CODES.contains(&rv.status) {
17861737
rv.body = Some(out);
17871738
return Ok(rv);
17881739
}

0 commit comments

Comments
 (0)