libstore: asyncify Store::queryPathFromHashPart

Change-Id: I7ba33a0a27542350f4b89ce1cfe0afbd39134bce
This commit is contained in:
eldritch horrors
2025-03-05 18:49:45 +01:00
parent 7d9fad0cf1
commit 3fe2be1bcf
13 changed files with 67 additions and 32 deletions
+7 -4
View File
@@ -333,15 +333,18 @@ bool BinaryCacheStore::isValidPathUncached(const StorePath & storePath)
return fileExists(narInfoFileFor(storePath));
}
std::optional<StorePath> BinaryCacheStore::queryPathFromHashPart(const std::string & hashPart)
{
kj::Promise<Result<std::optional<StorePath>>>
BinaryCacheStore::queryPathFromHashPart(const std::string & hashPart)
try {
auto pseudoPath = StorePath(hashPart + "-" + MissingName);
try {
auto info = queryPathInfo(pseudoPath);
return info->path;
co_return info->path;
} catch (InvalidPath &) {
return std::nullopt;
co_return std::nullopt;
}
} catch (...) {
co_return result::current_exception();
}
box_ptr<Source> BinaryCacheStore::narFromPath(const StorePath & storePath)
+2 -1
View File
@@ -113,7 +113,8 @@ public:
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override;
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) override;
kj::Promise<Result<void>> addToStore(const ValidPathInfo & info, AsyncInputStream & narSource,
RepairFlag repair, CheckSigsFlag checkSigs) override;
+7 -2
View File
@@ -1079,8 +1079,13 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor
co_return result::current_exception();
}
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override
{ throw Error("queryPathFromHashPart"); }
kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) override
try {
throw Error("queryPathFromHashPart");
} catch (...) {
return {result::current_exception()};
}
kj::Promise<Result<StorePath>> addToStoreRecursive(
std::string_view name,
+1 -1
View File
@@ -396,7 +396,7 @@ static void performOp(AsyncIoRoot & aio, TunnelLogger * logger, ref<Store> store
case WorkerProto::Op::QueryPathFromHashPart: {
auto hashPart = readString(from);
logger->startWork();
auto path = store->queryPathFromHashPart(hashPart);
auto path = aio.blockOn(store->queryPathFromHashPart(hashPart));
logger->stopWork();
to << (path ? store->printStorePath(*path) : "");
break;
+7 -2
View File
@@ -51,8 +51,13 @@ struct DummyStore final : public Store
return {"dummy"};
}
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override
{ unsupported("queryPathFromHashPart"); }
kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) override
try {
unsupported("queryPathFromHashPart");
} catch (...) {
return {result::current_exception()};
}
kj::Promise<Result<void>> addToStore(const ValidPathInfo & info, AsyncInputStream & source,
RepairFlag repair, CheckSigsFlag checkSigs) override
+7 -2
View File
@@ -259,8 +259,13 @@ struct LegacySSHStore final : public Store
}(std::move(conn)));
}
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override
{ unsupported("queryPathFromHashPart"); }
kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) override
try {
unsupported("queryPathFromHashPart");
} catch (...) {
return {result::current_exception()};
}
kj::Promise<Result<StorePath>> addToStoreRecursive(
std::string_view name,
+20 -11
View File
@@ -25,6 +25,7 @@
#include <memory>
#include <mutex>
#include <new>
#include <optional>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
@@ -1085,24 +1086,32 @@ LocalStore::queryStaticPartialDerivationOutputMap(const StorePath & path)
}, always_progresses);
}
std::optional<StorePath> LocalStore::queryPathFromHashPart(const std::string & hashPart)
{
kj::Promise<Result<std::optional<StorePath>>>
LocalStore::queryPathFromHashPart(const std::string & hashPart)
try {
if (hashPart.size() != StorePath::HashLen) throw Error("invalid hash part");
Path prefix = config_.storeDir + "/" + hashPart;
return retrySQLite([&]() -> std::optional<StorePath> {
auto state = dbPool.get();
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
co_return TRY_AWAIT(retrySQLite([&]() -> kj::Promise<Result<std::optional<StorePath>>> {
try {
auto state = dbPool.get();
auto useQueryPathFromHashPart(state->stmts->QueryPathFromHashPart.use()(prefix));
auto useQueryPathFromHashPart(state->stmts->QueryPathFromHashPart.use()(prefix));
if (!useQueryPathFromHashPart.next()) return {};
if (!useQueryPathFromHashPart.next()) co_return std::nullopt;
auto s = useQueryPathFromHashPart.getStrNullable(0);
if (s.has_value() && s->starts_with(prefix))
return parseStorePath(*s);
return {};
}, always_progresses);
auto s = useQueryPathFromHashPart.getStrNullable(0);
if (s.has_value() && s->starts_with(prefix))
co_return parseStorePath(*s);
co_return std::nullopt;
} catch (...) {
co_return result::current_exception();
}
}));
} catch (...) {
co_return result::current_exception();
}
+2 -1
View File
@@ -204,7 +204,8 @@ public:
std::map<std::string, std::optional<StorePath>> queryStaticPartialDerivationOutputMap(const StorePath & path) override;
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) override;
kj::Promise<Result<StorePathSet>> querySubstitutablePaths(const StorePathSet & paths) override;
+8 -4
View File
@@ -25,6 +25,7 @@
#include <kj/async.h>
#include <nlohmann/json.hpp>
#include <optional>
namespace nix {
@@ -379,14 +380,17 @@ try {
co_return result::current_exception();
}
std::optional<StorePath> RemoteStore::queryPathFromHashPart(const std::string & hashPart)
{
kj::Promise<Result<std::optional<StorePath>>>
RemoteStore::queryPathFromHashPart(const std::string & hashPart)
try {
auto conn(getConnection());
conn->to << WorkerProto::Op::QueryPathFromHashPart << hashPart;
conn.processStderr();
Path path = readString(conn->from);
if (path.empty()) return {};
return parseStorePath(path);
if (path.empty()) co_return std::nullopt;
co_return parseStorePath(path);
} catch (...) {
co_return result::current_exception();
}
+2 -1
View File
@@ -67,7 +67,8 @@ public:
kj::Promise<Result<std::map<std::string, std::optional<StorePath>>>>
queryPartialDerivationOutputMap(const StorePath & path, Store * evalStore = nullptr) override;
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) override;
kj::Promise<Result<StorePathSet>> querySubstitutablePaths(const StorePathSet & paths) override;
+2 -1
View File
@@ -477,7 +477,8 @@ public:
* Query the full store path given the hash part of a valid store
* path, or empty if the path doesn't exist.
*/
virtual std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) = 0;
virtual kj::Promise<Result<std::optional<StorePath>>>
queryPathFromHashPart(const std::string & hashPart) = 0;
/**
* Query which of the given paths have substitutes.
+1 -1
View File
@@ -29,7 +29,7 @@ struct CmdPathFromHashPart : StoreCommand
void run(ref<Store> store) override
{
if (auto storePath = store->queryPathFromHashPart(hashPart))
if (auto storePath = aio().blockOn(store->queryPathFromHashPart(hashPart)))
logger->cout(store->printStorePath(*storePath));
else
throw Error("there is no store path corresponding to '%s'", hashPart);
+1 -1
View File
@@ -147,7 +147,7 @@ SV * queryRawRealisation(char * outputId)
SV * queryPathFromHashPart(char * hashPart)
PPCODE:
try {
auto path = store()->queryPathFromHashPart(hashPart);
auto path = aio().blockOn(store()->queryPathFromHashPart(hashPart));
XPUSHs(sv_2mortal(newSVpv(path ? store()->printStorePath(*path).c_str() : "", 0)));
} catch (Error & e) {
croak("%s", e.what());