mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
local-binary-cache-store: Add retry loop to upsertFile
Handle race conditions in binary cache file creation by retrying with a new temporary name on EEXIST errors. Uses existing makeTempPath which already has an atomic counter.
This commit is contained in:
parent
bc73faf88f
commit
f124293024
1 changed files with 26 additions and 7 deletions
|
@ -58,13 +58,32 @@ protected:
|
||||||
const std::string & mimeType) override
|
const std::string & mimeType) override
|
||||||
{
|
{
|
||||||
auto path2 = config->binaryCacheDir + "/" + path;
|
auto path2 = config->binaryCacheDir + "/" + path;
|
||||||
static std::atomic<int> counter{0};
|
|
||||||
Path tmp = fmt("%s.tmp.%d.%d", path2, getpid(), ++counter);
|
/* Retry loop for handling race conditions */
|
||||||
AutoDelete del(tmp, false);
|
while (true) {
|
||||||
StreamToSourceAdapter source(istream);
|
Path tmp = makeTempPath(dirOf(path2), baseNameOf(path2) + ".tmp");
|
||||||
writeFile(tmp, source);
|
AutoDelete del(tmp, false);
|
||||||
std::filesystem::rename(tmp, path2);
|
|
||||||
del.cancel();
|
StreamToSourceAdapter source(istream);
|
||||||
|
try {
|
||||||
|
writeFile(tmp, source);
|
||||||
|
} catch (Error & e) {
|
||||||
|
e.addTrace({}, "while writing to temporary file '%s' for '%s'", tmp, path2);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::filesystem::rename(tmp, path2);
|
||||||
|
del.cancel();
|
||||||
|
break; /* Success! */
|
||||||
|
} catch (std::filesystem::filesystem_error & e) {
|
||||||
|
if (e.code() == std::errc::file_exists) {
|
||||||
|
/* Race condition: another process created the same file.
|
||||||
|
Try again with a different name. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw SysError("renaming '%s' to '%s'", tmp, path2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getFile(const std::string & path, Sink & sink) override
|
void getFile(const std::string & path, Sink & sink) override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue