diff --git a/Cargo.lock b/Cargo.lock index 46e382bdb9..0336dce282 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -997,6 +997,15 @@ dependencies = [ "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.6" @@ -1215,6 +1224,13 @@ dependencies = [ "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "retry" +version = "0.4.0" +dependencies = [ + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.14" @@ -1247,6 +1263,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "retry 0.4.0", "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2015,6 +2032,7 @@ dependencies = [ "checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" "checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" diff --git a/Cargo.toml b/Cargo.toml index cb57c58ac7..ef0e90ac23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,10 @@ wait-timeout = "0.2" walkdir = "2" xz2 = "0.1.3" +[dependencies.retry] +version = "0.4" +default-features = false + [target."cfg(windows)".dependencies] cc = "1" winreg = "0.6" @@ -100,3 +104,6 @@ path = "src/cli/main.rs" [profile.release] lto = true codegen-units = 1 + +[patch.crates-io] +retry = { path = "../retry" } \ No newline at end of file diff --git a/src/utils/utils.rs b/src/utils/utils.rs index eef794be32..e55c4158eb 100644 --- a/src/utils/utils.rs +++ b/src/utils/utils.rs @@ -11,6 +11,9 @@ use std::path::{Path, PathBuf}; use std::process::Command; use url::Url; +use retry::{retry, OperationResult}; +use retry::delay::{Fibonacci, jitter}; + #[cfg(windows)] use winapi::shared::minwindef::DWORD; @@ -651,7 +654,24 @@ pub fn toolchain_sort>(v: &mut Vec) { } fn rename(name: &'static str, src: &Path, dest: &Path) -> Result<()> { - fs::rename(src, dest).chain_err(|| ErrorKind::RenamingFile { + // https://github.com/rust-lang/rustup.rs/issues/1870 + // 21 fib steps from 1 sums to ~28 seconds, hopefully more than enough + // for our previous poor performance that avoided the race condition with + // McAfee and Norton. + retry( + Fibonacci::from_millis(1).map(jitter).take(21), || { + match fs::rename(src, dest) { + Ok(v) => OperationResult::Ok(v), + Err(e) => { + match e.kind() { + io::ErrorKind::PermissionDenied => OperationResult::Retry(e), + _ => OperationResult::Err(e) + } + } + } + } + ) + .chain_err(|| ErrorKind::RenamingFile { name, src: PathBuf::from(src), dest: PathBuf::from(dest),