Skip to content
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

Fix directory creation race condition in Folder and SandboxFolder #4912

Conversation

sphuber
Copy link
Contributor

@sphuber sphuber commented May 5, 2021

Fixes #4911

The Folder and SandboxFolder classes of aiida.common.folders used
the following paradigm to create the required folders:

if not os.path.exists(filepath):
    os.makedirs(filepath)

However, this is susceptible to a race condition. If two processes call
the same piece of code almost at the same time, they may both evaluate
the conditional to be True if the filepath does not yet exist, but one
of the two will actually get to the creation first, causing the second
process to except with a FileExistsError.

The solution is to replace it with os.makedirs(filepath, exist_ok=True)
which will swallow the exception if the path already exists.

The `Folder` and `SandboxFolder` classes of `aiida.common.folders` used
the following paradigm to create the required folders:

    if not os.path.exists(filepath):
        os.makedirs(filepath)

However, this is susceptible to a race condition. If two processes call
the same piece of code almost at the same time, they may both evaluate
the conditional to be True if the filepath does not yet exist, but one
of the two will actually get to the creation first, causing the second
process to except with a `FileExistsError`.

The solution is to replace it with `os.makedirs(filepath, exist_ok=True)`
which will swallow the exception if the path already exists.
@sphuber sphuber requested a review from giovannipizzi May 5, 2021 12:56
@codecov
Copy link

codecov bot commented May 5, 2021

Codecov Report

Merging #4912 (74c581e) into develop (93c8896) will increase coverage by 0.01%.
The diff coverage is 66.67%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #4912      +/-   ##
===========================================
+ Coverage    80.07%   80.07%   +0.01%     
===========================================
  Files          518      518              
  Lines        36683    36680       -3     
===========================================
- Hits         29371    29369       -2     
+ Misses        7312     7311       -1     
Flag Coverage Δ
django 74.56% <66.67%> (+0.01%) ⬆️
sqlalchemy 73.47% <66.67%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
aiida/common/folders.py 66.15% <66.67%> (-<0.01%) ⬇️
aiida/transports/util.py 62.50% <0.00%> (-3.12%) ⬇️
aiida/transports/plugins/local.py 81.80% <0.00%> (+0.26%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 93c8896...74c581e. Read the comment docs.

@sphuber sphuber merged commit dc686c5 into aiidateam:develop May 5, 2021
@sphuber sphuber deleted the fix/4911/sandbox-folder-creation-race-condition branch May 5, 2021 14:42
sphuber added a commit that referenced this pull request Aug 8, 2021
…#4912)

The `Folder` and `SandboxFolder` classes of `aiida.common.folders` used
the following paradigm to create the required folders:

    if not os.path.exists(filepath):
        os.makedirs(filepath)

However, this is susceptible to a race condition. If two processes call
the same piece of code almost at the same time, they may both evaluate
the conditional to be True if the filepath does not yet exist, but one
of the two will actually get to the creation first, causing the second
process to except with a `FileExistsError`.

The solution is to replace it with `os.makedirs(filepath, exist_ok=True)`
which will swallow the exception if the path already exists.

Cherry-pick: dc686c5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AiiDA fails on concurrent sandbox creation
2 participants