prefetch-npm-deps: add retry

This commit is contained in:
XYenon 2023-06-19 00:34:48 +08:00
parent ae56181605
commit 4915de2600

View File

@ -5,8 +5,11 @@ use serde_json::{Map, Value};
use std::{ use std::{
fs, io, fs, io,
process::{Command, Stdio}, process::{Command, Stdio},
thread,
time::Duration,
}; };
use tempfile::{tempdir, TempDir}; use tempfile::{tempdir, TempDir};
use ureq::{Error, ErrorKind, Response};
use url::Url; use url::Url;
pub mod lock; pub mod lock;
@ -103,7 +106,7 @@ impl Package {
let specifics = match get_hosted_git_url(&resolved)? { let specifics = match get_hosted_git_url(&resolved)? {
Some(hosted) => { Some(hosted) => {
let mut body = ureq::get(hosted.as_str()).call()?.into_reader(); let mut body = get_response(hosted.as_str())?.into_reader();
let workdir = tempdir()?; let workdir = tempdir()?;
@ -154,8 +157,7 @@ impl Package {
Specifics::Registry { .. } => { Specifics::Registry { .. } => {
let mut body = Vec::new(); let mut body = Vec::new();
ureq::get(self.url.as_str()) get_response(self.url.as_str())?
.call()?
.into_reader() .into_reader()
.read_to_end(&mut body)?; .read_to_end(&mut body)?;
@ -189,6 +191,31 @@ impl Package {
} }
} }
#[allow(clippy::result_large_err)]
fn get_response(url: &str) -> Result<Response, Error> {
for _ in 0..4 {
match ureq::get(url).call() {
Err(Error::Status(503 | 429, r)) => {
let retry: Option<u64> = r.header("retry-after").and_then(|h| h.parse().ok());
let retry = retry.unwrap_or(5);
eprintln!("{} for {}, retry in {}", r.status(), r.get_url(), retry);
thread::sleep(Duration::from_secs(retry));
}
Err(Error::Transport(t)) => match t.kind() {
ErrorKind::ConnectionFailed | ErrorKind::Dns | ErrorKind::Io => {
let retry = 5;
eprintln!("{} for {}, retry in {}", t.kind(), url, retry);
thread::sleep(Duration::from_secs(retry));
}
_ => return Err(Error::Transport(t)),
},
result => return result,
};
}
// Ran out of retries; try one last time and return whatever result we get.
ureq::get(url).call()
}
#[allow(clippy::case_sensitive_file_extension_comparisons)] #[allow(clippy::case_sensitive_file_extension_comparisons)]
fn get_hosted_git_url(url: &Url) -> anyhow::Result<Option<Url>> { fn get_hosted_git_url(url: &Url) -> anyhow::Result<Option<Url>> {
if ["git", "git+ssh", "git+https", "ssh"].contains(&url.scheme()) { if ["git", "git+ssh", "git+https", "ssh"].contains(&url.scheme()) {