Non-atomic file operations can cause problems that are difficult to reproduce, especially in cases of frequent file operations in parallel, such as test runs with parallel_rspec.
For example, creating a directory if there is none, has the following problems:
An exception occurs when the directory didn’t exist at the time of exist?
, but someone else created it
before mkdir
was executed.
# race condition with another process may result in an error in `mkdir`
unless Dir.exist?(path)
FileUtils.mkdir(path)
end
# race condition with another process may result in an error in `remove`
if File.exist?(path)
FileUtils.remove(path)
end
# atomic and idempotent creation
FileUtils.mkdir_p(path)
# atomic and idempotent removal
FileUtils.rm_f(path)