Skip to content

Commit a5dc7b3

Browse files
weatherfrogSBA
authored andcommitted
avoid race condition during chunk write
When the chunk file is first removed before the new version is moved into place, racing reads may encounter a missing chunk. Using rename() or replace() without remove() avoids the issue on Posix-Systems as the methods are atomic. The fallback of remove() -> rename() is included for Windows pre Python 3.3. Fixes zarr-developers#263
1 parent 3b50e3c commit a5dc7b3

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

zarr/storage.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -772,9 +772,18 @@ def __setitem__(self, key, value):
772772
f.write(value)
773773

774774
# move temporary file into place
775-
if os.path.exists(file_path):
776-
os.remove(file_path)
777-
os.rename(temp_path, file_path)
775+
if hasattr(os, 'replace'):
776+
# Python >= 3.3 has replace() which can replace existing
777+
# files on all platforms.
778+
os.replace(temp_path, file_path)
779+
else:
780+
# In Python < 3.3 use rename().
781+
if os.name == 'nt' and os.path.exists(file_path):
782+
# On windows, rename() can't overwrite files. So
783+
# the file is removed first.
784+
os.remove(file_path)
785+
786+
os.rename(temp_path, file_path)
778787

779788
finally:
780789
# clean up if temp file still exists for whatever reason

0 commit comments

Comments
 (0)