Skip to content

Don't use lockfile to protect updates to selfcheck file. #6879

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 4 commits into from
Sep 15, 2019

Conversation

chrahunt
Copy link
Member

@chrahunt chrahunt commented Aug 15, 2019

Previously, we were using lockfile.LockFile to protect updates to <cache dir>/selfcheck.json.

This uses hard links to create file locks, which are not supported in several contexts (as raised in various issues).

Now, we securely create a temporary file next to the target file, write to it, and rename it to the target path (removing the target path first if it exists).

In general we are graceful to failure, retrying several times over the course of 1 second before giving up. The only expected failure here should be on Windows if another process has an open file handle, and since this file is not very large it is reasonable that another pip instance will be done reading within that time period - otherwise we silently pass.

Closes #6954.

@pradyunsg
Copy link
Member

pradyunsg commented Aug 15, 2019

I spent some more time looking at all the options @uranusjr listed -- vistir's (pipenv) helper looks best suited for this to me.

@uranusjr Do you reckon it'd be fine to factor it out into a (yet another) dedicated "atomic file writes via temporary file" library?

@pradyunsg
Copy link
Member

(for folks following via email, I removed the incorrect paste in my previous comment)

@chrahunt
Copy link
Member Author

chrahunt commented Aug 15, 2019

Just to make some differences explicit, so we can decide on their value:

  1. Do we want to retry on failure to rename the file? I think this would be more relevant for the HTTP cache use case since it seems more reasonable that another pip process may have it open.
  2. Do file permissions for the tempfile matter?
  3. On the off chance that all renaming operations fail, do we want to try to remove the temporary file afterwards?

@uranusjr
Copy link
Member

Do you reckon it'd be fine to factor it out into a (yet another) dedicated "atomic file writes via temporary file" library?

Sure; would this be more suited to be explicitly hosted by PyPA? (also cc @techalchemy)

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Aug 22, 2019
@pradyunsg
Copy link
Member

would this be more suited to be explicitly hosted by PyPA?

It's not exactly a packaging-related tool so I'd prefer it live somewhere else.

@chrahunt chrahunt force-pushed the bugfix/dont-lock-selfcheck branch from 92ec15d to ea8da73 Compare September 3, 2019 23:56
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Sep 3, 2019
@chrahunt chrahunt force-pushed the bugfix/dont-lock-selfcheck branch from ea8da73 to 4728a8f Compare September 4, 2019 00:07
@chrahunt
Copy link
Member Author

chrahunt commented Sep 4, 2019

In #6970 there is an example of a likely race condition from concurrent cache access. This kind of usage will cause the move after write to fail, so I think we should retry a few times so as to not lose work we would've already done.

The pipenv helper construction does not support this kind of usage as-is and IMO adding retry-related options to it may be irrelevant for most use cases. I would feel more comfortable proceeding with the current implementation for this and the HTTP cache use case and then factoring it out afterwards if it still looks substantial enough to be worth it. Definitely open to any thoughts on this approach.

@chrahunt chrahunt force-pushed the bugfix/dont-lock-selfcheck branch from cab9c74 to 93fbb08 Compare September 7, 2019 04:11
@chrahunt chrahunt marked this pull request as ready for review September 7, 2019 04:17
@chrahunt
Copy link
Member Author

chrahunt commented Sep 7, 2019

Rebased. This should be ready for review!

Copy link
Member

@pradyunsg pradyunsg left a comment

Choose a reason for hiding this comment

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

OK with this in principle.

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Sep 8, 2019
@chrahunt chrahunt force-pushed the bugfix/dont-lock-selfcheck branch from 93fbb08 to 68e6feb Compare September 8, 2019 13:30
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Sep 8, 2019
@chrahunt
Copy link
Member Author

Anything else needed here in order to merge?

@pradyunsg
Copy link
Member

One of us clicking merge. :)

@pradyunsg pradyunsg merged commit ab250e3 into pypa:master Sep 15, 2019
@chrahunt chrahunt deleted the bugfix/dont-lock-selfcheck branch September 15, 2019 13:55
@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Oct 15, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Don't use file locking to protect selfcheck state file
7 participants