- 필수 기능
- 시작하기
- Glossary
- 표준 속성
- Guides
- Agent
- 통합
- 개방형텔레메트리
- 개발자
- Administrator's Guide
- API
- Datadog Mobile App
- CoScreen
- Cloudcraft
- 앱 내
- 서비스 관리
- 인프라스트럭처
- 애플리케이션 성능
- APM
- Continuous Profiler
- 스팬 시각화
- 데이터 스트림 모니터링
- 데이터 작업 모니터링
- 디지털 경험
- 소프트웨어 제공
- 보안
- AI Observability
- 로그 관리
- 관리
ID: ruby-best-practices/atomic-file-operations
Language: Ruby
Severity: Notice
Category: Best Practices
The rule “Prefer atomic file operations” is designed to promote the use of atomic operations when interacting with files or directories. This is important because non-atomic file operations can lead to race conditions, where the state of a file or directory changes between the time you check its state and the time you perform an operation on it. For example, if you check whether a directory exists and then try to create it if it doesn’t, another process could create the directory after you check, but before you create it, leading to an error.
In Ruby, you can avoid this problem by using methods from the FileUtils
module, which provide atomic operations. For example, instead of checking whether a directory exists and then creating it if it doesn’t, you can use the FileUtils.mkdir_p
method, which will create the directory if it doesn’t exist, and do nothing if it does.
Non-compliant code often checks for the existence of a file or directory using File.exist?
or Dir.exist?
and then performs a file operation. To fix this, replace these checks and operations with equivalent atomic operations. For example, replace unless Dir.exist?(path); FileUtils.mkdir(path); end
with FileUtils.mkdir_p(path)
. Similarly, replace if File.exist?(path); FileUtils.remove(path); end
with FileUtils.rm_f(path)
. This will ensure that your file operations are atomic, and safe from race conditions.
# The failing snippets check if a file or directory exists,
# then call a function from FileUtils on that file or directory.
unless Dir.exist?(path)
FileUtils.mkdir(path)
end
unless not File.exist?(path)
FileUtils.remove(path)
end
if File.exist?(path)
FileUtils.remove(path)
end
if !Dir.exist?(path)
FileUtils.mkdir(path)
end
# Preferred alternative to check-if-exist-then-mkdir
FileUtils.mkdir_p(path)
# Preferred alternative to check-if-exist-then-rm
FileUtils.rm_f(path)
# More than one argument to the operation
if File.exist?(path)
FileUtils.doSomething(path, arg)
end
# These use different modules or methods
unless Foo.exist?(path)
FileUtils.mkdir(path)
end
unless Dir.exists?(path)
FileUtils.mkdir(path)
end
unless Dir.exist?(path)
FileUtilities.mkdir(path)
end
# These check one thing then operate on another thing
unless Dir.exist?(path)
FileUtils.mkdir(other_path)
end
# These check one thing then operate on another thing
if File.exist?(path)
FileUtils.remove(other_path)
end