Retry download of rustc-perf in opt-dist
This should help resolving spurious network errors. It also increases the timeout for the archive download.
diff --git a/src/tools/opt-dist/src/environment/windows.rs b/src/tools/opt-dist/src/environment/windows.rs
index 67f63c7..7939939 100644
--- a/src/tools/opt-dist/src/environment/windows.rs
+++ b/src/tools/opt-dist/src/environment/windows.rs
@@ -1,8 +1,10 @@
use crate::environment::Environment;
use crate::exec::cmd;
use crate::utils::io::move_directory;
+use crate::utils::retry_action;
use camino::Utf8PathBuf;
use std::io::Cursor;
+use std::time::Duration;
use zip::ZipArchive;
pub(super) struct WindowsEnvironment {
@@ -43,7 +45,15 @@ fn prepare_rustc_perf(&self) -> anyhow::Result<()> {
const PERF_COMMIT: &str = "8b2ac3042e1ff2c0074455a0a3618adef97156b1";
let url = format!("https://ci-mirrors.rust-lang.org/rustc/rustc-perf-{PERF_COMMIT}.zip");
- let response = reqwest::blocking::get(url)?.error_for_status()?.bytes()?.to_vec();
+ let client = reqwest::blocking::Client::builder()
+ .timeout(Duration::from_secs(60 * 2))
+ .connect_timeout(Duration::from_secs(60 * 2))
+ .build()?;
+ let response = retry_action(
+ || Ok(client.get(&url).send()?.error_for_status()?.bytes()?.to_vec()),
+ "Download rustc-perf archive",
+ 5,
+ )?;
let mut archive = ZipArchive::new(Cursor::new(response))?;
archive.extract(self.rustc_perf_dir())?;
diff --git a/src/tools/opt-dist/src/utils/mod.rs b/src/tools/opt-dist/src/utils/mod.rs
index 9a3df15..2af2807 100644
--- a/src/tools/opt-dist/src/utils/mod.rs
+++ b/src/tools/opt-dist/src/utils/mod.rs
@@ -3,6 +3,7 @@
use crate::environment::Environment;
use crate::utils::io::{delete_directory, get_files_from_dir};
use humansize::{format_size, BINARY};
+use std::time::Duration;
use sysinfo::{DiskExt, RefreshKind, System, SystemExt};
pub fn format_env_variables() -> String {
@@ -70,6 +71,24 @@ pub fn with_log_group<F: FnOnce() -> R, R>(group: &str, func: F) -> R {
}
}
+#[allow(unused)]
+pub fn retry_action<F: Fn() -> anyhow::Result<R>, R>(
+ action: F,
+ name: &str,
+ count: u64,
+) -> anyhow::Result<R> {
+ for attempt in 0..count {
+ match action() {
+ Ok(result) => return Ok(result),
+ Err(error) => {
+ log::error!("Failed to perform action `{name}`, attempt #{attempt}: {error:?}");
+ std::thread::sleep(Duration::from_secs(5));
+ }
+ }
+ }
+ Err(anyhow::anyhow!("Failed to perform action `{name}` after {count} retries"))
+}
+
fn is_in_ci() -> bool {
std::env::var("GITHUB_ACTIONS").is_ok()
}