libstore: asyncify BinaryCacheStore::fileExists

Change-Id: I7574f61bf222389606be87bbaff486b386cdbecd
This commit is contained in:
eldritch horrors
2025-06-15 13:36:31 +00:00
parent c108f339f5
commit c76f0467b2
5 changed files with 33 additions and 18 deletions
+15 -6
View File
@@ -19,6 +19,7 @@
#include "lix/libutil/strings.hh"
#include <chrono>
#include <functional>
#include <regex>
#include <fstream>
#include <sstream>
@@ -214,7 +215,10 @@ try {
ThreadPool threadPool("write debuginfo pool", 25);
auto doFile = [&](std::string member, std::string key, std::string target) {
auto doFile = [&](AsyncIoRoot & aio,
std::string member,
std::string key,
std::string target) {
checkInterrupt();
JSON json;
@@ -223,7 +227,9 @@ try {
// FIXME: or should we overwrite? The previous link may point
// to a GC'ed file, so overwriting might be useful...
if (fileExists(key)) return;
if (aio.blockOn(fileExists(key))) {
return;
}
printMsg(lvlTalkative, "creating debuginfo link from '%s' to '%s'", key, target);
@@ -251,7 +257,9 @@ try {
std::string key = "debuginfo/" + buildId;
std::string target = "../" + narInfo->url;
threadPool.enqueue(std::bind(doFile, std::string(debugPath, 1), key, target));
threadPool.enqueueWithAio(std::bind(
doFile, std::placeholders::_1, std::string(debugPath, 1), key, target
));
}
}
@@ -260,13 +268,14 @@ try {
}
/* Atomically write the NAR file. */
if (repair || !fileExists(narInfo->url)) {
if (repair || !TRY_AWAIT(fileExists(narInfo->url))) {
stats.narWrite++;
upsertFile(narInfo->url,
std::make_shared<std::fstream>(fnTemp, std::ios_base::in | std::ios_base::binary),
"application/x-nix-nar");
} else
} else {
stats.narWriteAverted++;
}
stats.narWriteBytes += info.narSize;
stats.narWriteCompressedBytes += fileSize;
@@ -347,7 +356,7 @@ try {
// FIXME: this only checks whether a .narinfo with a matching hash
// part exists. So f4kb...-foo matches f4kb...-bar, even
// though they shouldn't. Not easily fixed.
co_return fileExists(narInfoFileFor(storePath));
co_return TRY_AWAIT(fileExists(narInfoFileFor(storePath)));
} catch (...) {
co_return result::current_exception();
}
+1 -1
View File
@@ -73,7 +73,7 @@ public:
BinaryCacheStoreConfig & config() override = 0;
const BinaryCacheStoreConfig & config() const override = 0;
virtual bool fileExists(const std::string & path) = 0;
virtual kj::Promise<Result<bool>> fileExists(const std::string & path) = 0;
virtual void upsertFile(const std::string & path,
std::shared_ptr<std::basic_iostream<char>> istream,
+5 -3
View File
@@ -120,16 +120,18 @@ protected:
throw SubstituterDisabled("substituter '%s' is disabled", getUri());
}
bool fileExists(const std::string & path) override
{
kj::Promise<Result<bool>> fileExists(const std::string & path) override
try {
checkEnabled();
try {
return getFileTransfer()->exists(makeURI(path));
co_return getFileTransfer()->exists(makeURI(path));
} catch (FileTransferError & e) {
maybeDisable();
throw;
}
} catch (...) {
co_return result::current_exception();
}
void upsertFile(const std::string & path,
+6 -4
View File
@@ -57,7 +57,7 @@ public:
protected:
bool fileExists(const std::string & path) override;
kj::Promise<Result<bool>> fileExists(const std::string & path) override;
void upsertFile(const std::string & path,
std::shared_ptr<std::basic_iostream<char>> istream,
@@ -125,9 +125,11 @@ try {
co_return result::current_exception();
}
bool LocalBinaryCacheStore::fileExists(const std::string & path)
{
return pathExists(binaryCacheDir + "/" + path);
kj::Promise<Result<bool>> LocalBinaryCacheStore::fileExists(const std::string & path)
try {
return {pathExists(binaryCacheDir + "/" + path)};
} catch (...) {
return {result::current_exception()};
}
std::set<std::string> LocalBinaryCacheStore::uriSchemes()
+6 -4
View File
@@ -324,8 +324,8 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
co_return result::current_exception();
}
bool fileExists(const std::string & path) override
{
kj::Promise<Result<bool>> fileExists(const std::string & path) override
try {
stats.head++;
auto res = s3Helper.client->HeadObject(
@@ -339,11 +339,13 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|| error.GetErrorType() == Aws::S3::S3Errors::NO_SUCH_KEY
// If bucket listing is disabled, 404s turn into 403s
|| error.GetErrorType() == Aws::S3::S3Errors::ACCESS_DENIED)
return false;
return {false};
throw Error("AWS error fetching '%s': %s", path, error.GetMessage());
}
return true;
return {true};
} catch (...) {
return {result::current_exception()};
}
std::shared_ptr<TransferManager> transferManager;