From 3fe2be1bcf47f417feffc1f4d57c9f89df932146 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Tue, 4 Mar 2025 23:08:34 +0100 Subject: [PATCH] libstore: asyncify Store::queryPathFromHashPart Change-Id: I7ba33a0a27542350f4b89ce1cfe0afbd39134bce --- lix/libstore/binary-cache-store.cc | 11 +++++--- lix/libstore/binary-cache-store.hh | 3 +- lix/libstore/build/local-derivation-goal.cc | 9 ++++-- lix/libstore/daemon.cc | 2 +- lix/libstore/dummy-store.cc | 9 ++++-- lix/libstore/legacy-ssh-store.cc | 9 ++++-- lix/libstore/local-store.cc | 31 +++++++++++++-------- lix/libstore/local-store.hh | 3 +- lix/libstore/remote-store.cc | 12 +++++--- lix/libstore/remote-store.hh | 3 +- lix/libstore/store-api.hh | 3 +- lix/nix/path-from-hash-part.cc | 2 +- perl/lib/Nix/Store.xs | 2 +- 13 files changed, 67 insertions(+), 32 deletions(-) diff --git a/lix/libstore/binary-cache-store.cc b/lix/libstore/binary-cache-store.cc index 5bbdd74ac..7b97cc181 100644 --- a/lix/libstore/binary-cache-store.cc +++ b/lix/libstore/binary-cache-store.cc @@ -333,15 +333,18 @@ bool BinaryCacheStore::isValidPathUncached(const StorePath & storePath) return fileExists(narInfoFileFor(storePath)); } -std::optional BinaryCacheStore::queryPathFromHashPart(const std::string & hashPart) -{ +kj::Promise>> +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 BinaryCacheStore::narFromPath(const StorePath & storePath) diff --git a/lix/libstore/binary-cache-store.hh b/lix/libstore/binary-cache-store.hh index 9da939b85..ea22c9a3a 100644 --- a/lix/libstore/binary-cache-store.hh +++ b/lix/libstore/binary-cache-store.hh @@ -113,7 +113,8 @@ public: std::shared_ptr queryPathInfoUncached(const StorePath & path) override; - std::optional queryPathFromHashPart(const std::string & hashPart) override; + kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) override; kj::Promise> addToStore(const ValidPathInfo & info, AsyncInputStream & narSource, RepairFlag repair, CheckSigsFlag checkSigs) override; diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index d928efb60..fdb619f12 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -1079,8 +1079,13 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor co_return result::current_exception(); } - std::optional queryPathFromHashPart(const std::string & hashPart) override - { throw Error("queryPathFromHashPart"); } + kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) override + try { + throw Error("queryPathFromHashPart"); + } catch (...) { + return {result::current_exception()}; + } kj::Promise> addToStoreRecursive( std::string_view name, diff --git a/lix/libstore/daemon.cc b/lix/libstore/daemon.cc index adee7a528..f90d63704 100644 --- a/lix/libstore/daemon.cc +++ b/lix/libstore/daemon.cc @@ -396,7 +396,7 @@ static void performOp(AsyncIoRoot & aio, TunnelLogger * logger, ref 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; diff --git a/lix/libstore/dummy-store.cc b/lix/libstore/dummy-store.cc index 794759112..5bc8dbac6 100644 --- a/lix/libstore/dummy-store.cc +++ b/lix/libstore/dummy-store.cc @@ -51,8 +51,13 @@ struct DummyStore final : public Store return {"dummy"}; } - std::optional queryPathFromHashPart(const std::string & hashPart) override - { unsupported("queryPathFromHashPart"); } + kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) override + try { + unsupported("queryPathFromHashPart"); + } catch (...) { + return {result::current_exception()}; + } kj::Promise> addToStore(const ValidPathInfo & info, AsyncInputStream & source, RepairFlag repair, CheckSigsFlag checkSigs) override diff --git a/lix/libstore/legacy-ssh-store.cc b/lix/libstore/legacy-ssh-store.cc index 303a13d1f..514bc8f7c 100644 --- a/lix/libstore/legacy-ssh-store.cc +++ b/lix/libstore/legacy-ssh-store.cc @@ -259,8 +259,13 @@ struct LegacySSHStore final : public Store }(std::move(conn))); } - std::optional queryPathFromHashPart(const std::string & hashPart) override - { unsupported("queryPathFromHashPart"); } + kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) override + try { + unsupported("queryPathFromHashPart"); + } catch (...) { + return {result::current_exception()}; + } kj::Promise> addToStoreRecursive( std::string_view name, diff --git a/lix/libstore/local-store.cc b/lix/libstore/local-store.cc index f005a0d08..532c3a540 100644 --- a/lix/libstore/local-store.cc +++ b/lix/libstore/local-store.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1085,24 +1086,32 @@ LocalStore::queryStaticPartialDerivationOutputMap(const StorePath & path) }, always_progresses); } -std::optional LocalStore::queryPathFromHashPart(const std::string & hashPart) -{ +kj::Promise>> +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 { - auto state = dbPool.get(); + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) + co_return TRY_AWAIT(retrySQLite([&]() -> kj::Promise>> { + 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(); } diff --git a/lix/libstore/local-store.hh b/lix/libstore/local-store.hh index 711793ae7..b9ba9c339 100644 --- a/lix/libstore/local-store.hh +++ b/lix/libstore/local-store.hh @@ -204,7 +204,8 @@ public: std::map> queryStaticPartialDerivationOutputMap(const StorePath & path) override; - std::optional queryPathFromHashPart(const std::string & hashPart) override; + kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) override; kj::Promise> querySubstitutablePaths(const StorePathSet & paths) override; diff --git a/lix/libstore/remote-store.cc b/lix/libstore/remote-store.cc index 5fa0c2418..1db697cab 100644 --- a/lix/libstore/remote-store.cc +++ b/lix/libstore/remote-store.cc @@ -25,6 +25,7 @@ #include #include +#include namespace nix { @@ -379,14 +380,17 @@ try { co_return result::current_exception(); } -std::optional RemoteStore::queryPathFromHashPart(const std::string & hashPart) -{ +kj::Promise>> +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(); } diff --git a/lix/libstore/remote-store.hh b/lix/libstore/remote-store.hh index b672e0e36..c5d12028e 100644 --- a/lix/libstore/remote-store.hh +++ b/lix/libstore/remote-store.hh @@ -67,7 +67,8 @@ public: kj::Promise>>> queryPartialDerivationOutputMap(const StorePath & path, Store * evalStore = nullptr) override; - std::optional queryPathFromHashPart(const std::string & hashPart) override; + kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) override; kj::Promise> querySubstitutablePaths(const StorePathSet & paths) override; diff --git a/lix/libstore/store-api.hh b/lix/libstore/store-api.hh index 416b0bc79..76d840480 100644 --- a/lix/libstore/store-api.hh +++ b/lix/libstore/store-api.hh @@ -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 queryPathFromHashPart(const std::string & hashPart) = 0; + virtual kj::Promise>> + queryPathFromHashPart(const std::string & hashPart) = 0; /** * Query which of the given paths have substitutes. diff --git a/lix/nix/path-from-hash-part.cc b/lix/nix/path-from-hash-part.cc index da5e582e5..8e3f0b7be 100644 --- a/lix/nix/path-from-hash-part.cc +++ b/lix/nix/path-from-hash-part.cc @@ -29,7 +29,7 @@ struct CmdPathFromHashPart : StoreCommand void run(ref 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); diff --git a/perl/lib/Nix/Store.xs b/perl/lib/Nix/Store.xs index be9979a55..133f5b2ba 100644 --- a/perl/lib/Nix/Store.xs +++ b/perl/lib/Nix/Store.xs @@ -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());