Skip to content

Commit

Permalink
Auto merge of rust-lang#127147 - ChrisDenton:retry, r=<try>
Browse files Browse the repository at this point in the history
Bootstrap: Retry copying/linking

May be a workaround for rust-lang#127126. But it's hard to know if this works due to the error only appearing some times.

This just adds a retry loop with a fairly long pause between retries so as to give time to whatever is locking the file to give up its lock.

try-job: x86_64-msvc-ext
  • Loading branch information
bors committed Jun 30, 2024
2 parents 716752e + 1a19627 commit 0bdbe47
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
31 changes: 19 additions & 12 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use filetime::FileTime;
use sha2::digest::Digest;
use termcolor::{ColorChoice, StandardStream, WriteColor};
use utils::channel::GitInfo;
use utils::helpers::hex_encode;
use utils::helpers::{hex_encode, retry};

use crate::core::builder;
use crate::core::builder::Kind;
Expand Down Expand Up @@ -1688,18 +1688,25 @@ impl Build {
return;
}
}
if let Ok(()) = fs::hard_link(&src, dst) {
// Attempt to "easy copy" by creating a hard link
// (symlinks don't work on windows), but if that fails
// just fall back to a slow `copy` operation.
} else {
if let Err(e) = fs::copy(&src, dst) {
panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
// workaround for https://github.com/rust-lang/rust/issues/127126
// retry linking or copying up to 10 times or until success.
let result: io::Result<()> = retry(10, || {
if let Ok(()) = fs::hard_link(&src, dst) {
// Attempt to "easy copy" by creating a hard link
// (symlinks don't work on windows), but if that fails
// just fall back to a slow `copy` operation.
Ok(())
} else {
fs::copy(&src, dst)?;
t!(fs::set_permissions(dst, metadata.permissions()));
let atime = FileTime::from_last_access_time(&metadata);
let mtime = FileTime::from_last_modification_time(&metadata);
t!(filetime::set_file_times(dst, atime, mtime));
Ok(())
}
t!(fs::set_permissions(dst, metadata.permissions()));
let atime = FileTime::from_last_access_time(&metadata);
let mtime = FileTime::from_last_modification_time(&metadata);
t!(filetime::set_file_times(dst, atime, mtime));
});
if let Err(e) = result {
panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/bootstrap/src/utils/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,19 @@ pub fn git(source_dir: Option<&Path>) -> Command {

git
}

/// Retry a function up to n times, returning the last call to fun.
/// Stops early if the function returns `Ok`.
pub fn retry<T, E>(n: usize, mut fun: impl FnMut() -> Result<T, E>) -> Result<T, E> {
let mut retries = 0;
loop {
retries += 1;

let result = fun();
if result.is_ok() || retries == n {
return result;
}
// wait an arbitrary length of time.
std::thread::sleep(std::time::Duration::from_secs(1));
}
}

0 comments on commit 0bdbe47

Please sign in to comment.