-
Notifications
You must be signed in to change notification settings - Fork 90
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
installPkg: do no work when using cached package and annotate safely #726
Conversation
R/restore.R
Outdated
# Write it out using a temporary file so DESCRIPTION is never partial. | ||
tmpf <- tempfile(tmpdir = dirname(descFile)) | ||
write_dcf(content, tmpf) | ||
file.rename(tmpf, descFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this will emit a warning and return false on failure -- do we need to handle that scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I had dismissed the need to handle the error because the directory is known to be writable and we are not performing a cross-file-system move, but it's probably worth checking the return value.
6b35ca9
to
7cd3b61
Compare
7cd3b61
to
346c8a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No major comments from a code read. Questions that came up were answered elsewhere in the code.
One conceptual question: Do we know why the description was updated when installing from the cache? Are there any times where un-annotated descriptions can enter the cache (e.g. a package was installed via install.packages without Packrat) where we'd want to add the annotation? And if so, would the atomic updates (via renaming a temp file) be sufficient to fix the problem?
A long time ago, Packrat tried to distinguish between packages which were installed by Packrat itself, versus packages that were installed by the user. The intention here was to have a way of differentiating between packages that were "managed" or "known" to Packrat, and use that to customize the UI presented to the user in certain scenarios (e.g. helping them choose whether to snapshot or restore). In practice, users found the behavior hard to understand, so that was phased out over time. I'm not sure if we still make use of the InstallAgent annotations anywhere in the Packrat sources, but if we do, it'd be nice to drop those once and for all. |
We do still use |
Users do not enroll packages in the cache; only Packrat performs cache additions and cache-uses while installing a package. I suppose it's possible that a user could add something to the Packrat library, but that is separate from cache management. |
First, the
installPkg()
function no longer does additional work when the package was discovered in the cache. This avoids the most common situation where multiple processes performing package installation can race to theannotatePkgDesc()
andmoveInstalledPackageToCache()
calls.Second,
annotatePkgDesc()
writes its update to a temporary file before renaming to the targetDESCRIPTION
. This avoids a (now more rare) situation where a second process might see an incompletely writtenDESCRIPTION
file.As a side-effect, only the originally installing actor will annotate the
DESCRIPTION
. Previously, an update occurred even when the package was used from the cache, which overwrote an existing annotation.Update: After thinking about this problem a bit more, realized that the root cause to #720 is because
annotatePkgDesc()
was previously writing into the package cache. After callingrestoreWithCopyFromCache()
, the library contains a symlink into the cache. CallingannotatePkgDesc()
reads through the symlink and modifies the in-cacheDESCRIPTION
. This is why we saw multiple actors reading/writing the same file.Fixes #720