Skip to content

compiletest remove_and_create_dir_all may need retries #139230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jieyouxu opened this issue Apr 2, 2025 · 3 comments · Fixed by #139870
Closed

compiletest remove_and_create_dir_all may need retries #139230

jieyouxu opened this issue Apr 2, 2025 · 3 comments · Fixed by #139870
Assignees
Labels
A-compiletest Area: The compiletest test runner A-test-infra Area: test infrastructure (may span bootstrap/compiletest/more) C-enhancement Category: An issue proposing an enhancement or a PR with one. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jieyouxu
Copy link
Member

jieyouxu commented Apr 2, 2025

cf. #134351. The current impl of remove_and_create_dir_all silently ignores the remove_dir_all failure and tries to create_dir_all, which can fail if remove_dir_all fails and a directory already exists.

fn remove_and_create_dir_all(path: &Path) {
    let _ = fs::remove_dir_all(path);
    fs::create_dir_all(path).unwrap();
}

compiletest cannot paper over create_dir_all failures (esp. if due to the directory already existing) to avoid running tests against outdated/invalid artifacts. So maybe a retry mechanism is needed. However, this should not be spot-fixed, and instead the retry mechanism should be shared between bootstrap/compiletest, preferrably in build_helpers with its own tests.

@jieyouxu jieyouxu added A-compiletest Area: The compiletest test runner A-test-infra Area: test infrastructure (may span bootstrap/compiletest/more) C-enhancement Category: An issue proposing an enhancement or a PR with one. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 2, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 2, 2025
@jieyouxu jieyouxu removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 2, 2025
@Shourya742
Copy link
Contributor

@rustbot claim

@Shourya742
Copy link
Contributor

Hello @jieyouxu, Could you elaborate on the retry mechanism shared between bootstrap and compiletest? Are you suggesting creating a wrapper around methods that retries them a specific number of times until they return an Ok result, or should it simply return the output of the last attempt?
For example, are you proposing something like this?

pub fn retry_io<T, F>(func: F) -> io::Result<T>  
where  
    F: Fn() -> io::Result<T>,  
{  
    let mut attempt = 0;  
    loop {  
        match func() {  
            Ok(result) => return Ok(result),  
            Err(e) if attempt < 5 => {  
                attempt += 1;  
                thread::sleep(Duration::from_millis(10));  
            }  
            Err(e) => return Err(e),  
        }  
    }  
}

Or is the retry mechanism meant to be specific to remove_and_create_dir_all, implemented in build_helper like this?

pub fn remove_and_create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {  
    let path = path.as_ref();  
    for attempt in 0..5 {  
        if fs::remove_dir_all(path).is_ok() || !path.exists() {  
            return fs::create_dir_all(path);  
        }  
        std::thread::sleep(std::time::Duration::from_millis(60)));  
    }  
    fs::create_dir_all(path)  
}

Or both are wrong interpretation?

@jieyouxu
Copy link
Member Author

jieyouxu commented Apr 3, 2025

  • I was thinking sth like retrying remove_dir_all a few times but only if the remove_dir_all attempts don't error in NotFound.
  • I said build_helper because build_helper can be shared between bootstrap and compiletest.
  • I would not recommend retrying any I/O operations, but only for sth like remove_and_create_dir_all. Or remove_dir_all-ish cases. I would expect the outcome of the final attempt to be the final return value of this helper.
  • The implementation needs to be careful to not traverse symlinks.

See also

pub fn recursive_remove<P: AsRef<Path>>(path: P) -> io::Result<()> {
which doesn't currently perform retries.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Apr 17, 2025
…to-remove_and_create_dir_all, r=jieyouxu

add retries to remove and create dir all

closes: rust-lang#139230

r? `@jieyouxu`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Apr 17, 2025
…to-remove_and_create_dir_all, r=jieyouxu

add retries to remove and create dir all

closes: rust-lang#139230

r? ``@jieyouxu``
@bors bors closed this as completed in cecc7a4 Apr 17, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Apr 17, 2025
Rollup merge of rust-lang#139870 - Shourya742:2025-04-15-add-retries-to-remove_and_create_dir_all, r=jieyouxu

add retries to remove and create dir all

closes: rust-lang#139230

r? ```@jieyouxu```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-compiletest Area: The compiletest test runner A-test-infra Area: test infrastructure (may span bootstrap/compiletest/more) C-enhancement Category: An issue proposing an enhancement or a PR with one. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
Development

Successfully merging a pull request may close this issue.

3 participants