Skip to content

avoid race condition during chunk write #327

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

Merged
merged 8 commits into from
Dec 4, 2018

Conversation

sbalmer
Copy link
Contributor

@sbalmer sbalmer commented Nov 8, 2018

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 #263

TODO:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/tutorial.rst
  • Changes documented in docs/release.rst
  • Docs build locally (e.g., run tox -e docs)
  • AppVeyor and Travis CI passes
  • Test coverage is 100% (Coveralls passes)

zarr/storage.py Outdated
# On windows, rename() can't overwrite files. So
# the file is removed first.
os.remove(new)
os.rename(old, new)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is the case where we would want the pyosreplace package. It's a Windows only backport for os.replace on Python 2.

@alimanfoo
Copy link
Member

Just to mention that there are some potential consequences from implementing this PR that we should be aware of, described in #328. I don't think that should stop us from moving ahead with this PR, using os.replace() is clearly a better thing to do under any circumstances, but just something to be aware of.

@sbalmer
Copy link
Contributor Author

sbalmer commented Nov 14, 2018

@jakirkham I've made a guess at the setup.py changes needed for pyosreplace. I couldn't get environmental markers to work. See previous commit. Could you please have a look at it? And is something else needed?

@jakirkham
Copy link
Member

Think you had it basically right. Unfortunately there is some lack of clarity about when a colon or semicolon should be used. IIUC it should be a semicolon.

Copy link
Member

@jakirkham jakirkham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for working on this @sbalmer.

Hopefully the comment above is useful. Am personally fine with how this is. Though if you want to use environment markers instead (or others prefer this), that could be also done, but don't personally think this is critical.

@alimanfoo
Copy link
Member

Thanks @sbalmer. Could you add pyosreplace to requirements.txt and requirements_dev.txt, pinned to the latest version in the latter. I guess environment markers are needed in both.

@alimanfoo alimanfoo added this to the v2.3 milestone Nov 20, 2018
weatherfrog and others added 6 commits November 21, 2018 13:27
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
so it's not repeated on every write
Because the env markers didn't work. Just guessing at this point.
@sbalmer
Copy link
Contributor Author

sbalmer commented Nov 21, 2018

@alimanfoo pyosreplace is now in the requirement files too. I've made a guess at how the env markers should look. If I invert the predicates then pip install -r requirements.txt tries to install the package. Which means I have some confidence it should work.

@jakirkham
Copy link
Member

Thanks @sbalmer. LGTM. 😄 Let's see what @alimanfoo thinks. 😉

@jakirkham jakirkham requested a review from alimanfoo November 26, 2018 17:25
@jakirkham
Copy link
Member

I wonder if we can just drop the try...finally now.

@jakirkham jakirkham mentioned this pull request Dec 4, 2018
7 tasks
Copy link
Member

@alimanfoo alimanfoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks @sbalmer, looks good. Could you add a release note to docs/release.rst.

@alimanfoo
Copy link
Member

I wonder if we can just drop the try...finally now.

FWIW I imagine it could still be possible that some failure occurs during the attempt to write to the temporary file (e.g., device gets full or something like that), in which case an exception occurs before the value has been fully written, in which case we'd still want to clean up the temporary file.

@jakirkham
Copy link
Member

Good point.

@alimanfoo
Copy link
Member

I've resolved conflicts after merging #352 and added a release note. Will merge if CI passes.

@alimanfoo
Copy link
Member

@sbalmer apologies I didn't know your full name to include in the release note, you're credited currently just as "sbalmer", happy to leave it that way or add your full name, whichever you prefer.

@alimanfoo alimanfoo merged commit 94f7a8d into zarr-developers:master Dec 4, 2018
@jakirkham
Copy link
Member

Thanks @sbalmer 😄

@sbalmer
Copy link
Contributor Author

sbalmer commented Dec 6, 2018

Thanks @alimanfoo, @jakirkham!

Now we can use mainline again :-)

@sbalmer sbalmer deleted the atomic-update branch December 6, 2018 13:22
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.

4 participants