From 68947e7a65721c0b84cf7b3c75b8a5afc86a0d43 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sat, 1 Feb 2025 21:24:35 +0100 Subject: [PATCH] libstore: asyncify Store::derivationFromPath Change-Id: Ic6b54642da08f258c113d5076b34b7c13096f540 --- lix/legacy/nix-build.cc | 2 +- lix/legacy/nix-store.cc | 8 ++++---- lix/libexpr/get-drvs.cc | 2 +- lix/libstore/misc.cc | 2 +- lix/libstore/store-api.cc | 12 +++++++----- lix/libstore/store-api.hh | 2 +- lix/nix/develop.cc | 2 +- perl/lib/Nix/Store.xs | 9 ++++++++- 8 files changed, 24 insertions(+), 15 deletions(-) diff --git a/lix/legacy/nix-build.cc b/lix/legacy/nix-build.cc index 78d738a2a..a1bce8172 100644 --- a/lix/legacy/nix-build.cc +++ b/lix/legacy/nix-build.cc @@ -327,7 +327,7 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a throw UsageError("nix-shell requires a single derivation"); auto & drvInfo = drvs.front(); - auto drv = evalStore->derivationFromPath(drvInfo.requireDrvPath(*state)); + auto drv = aio.blockOn(evalStore->derivationFromPath(drvInfo.requireDrvPath(*state))); std::vector pathsToBuild; RealisedPath::Set pathsToCopy; diff --git a/lix/legacy/nix-store.cc b/lix/legacy/nix-store.cc index 2ac5dd72c..c76c54b45 100644 --- a/lix/legacy/nix-store.cc +++ b/lix/legacy/nix-store.cc @@ -69,7 +69,7 @@ try { if (path.path.isDerivation()) { if (build) TRY_AWAIT(store->buildPaths({path.toDerivedPath()})); auto outputPaths = store->queryDerivationOutputMap(path.path); - Derivation drv = store->derivationFromPath(path.path); + Derivation drv = TRY_AWAIT(store->derivationFromPath(path.path)); rootNr++; /* FIXME: Encode this empty special case explicitly in the type. */ @@ -232,7 +232,7 @@ static kj::Promise> maybeUseOutputs(const StorePath & store try { if (forceRealise) TRY_AWAIT(realisePath({storePath})); if (useOutput && storePath.isDerivation()) { - auto drv = store->derivationFromPath(storePath); + auto drv = TRY_AWAIT(store->derivationFromPath(storePath)); StorePathSet outputs; if (forceRealise) co_return store->queryDerivationOutputs(storePath); @@ -394,7 +394,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs) case qBinding: for (auto & i : opArgs) { auto path = useDeriver(store->followLinksToStorePath(i)); - Derivation drv = store->derivationFromPath(path); + Derivation drv = aio.blockOn(store->derivationFromPath(path)); StringPairs::iterator j = drv.env.find(bindingName); if (j == drv.env.end()) throw Error("derivation '%s' has no environment binding named '%s'", @@ -479,7 +479,7 @@ static void opPrintEnv(AsyncIoRoot & aio, Strings opFlags, Strings opArgs) if (opArgs.size() != 1) throw UsageError("'--print-env' requires one derivation store path"); Path drvPath = opArgs.front(); - Derivation drv = store->derivationFromPath(store->parseStorePath(drvPath)); + Derivation drv = aio.blockOn(store->derivationFromPath(store->parseStorePath(drvPath))); /* Print each environment variable in the derivation in a format * that can be sourced by the shell. */ diff --git a/lix/libexpr/get-drvs.cc b/lix/libexpr/get-drvs.cc index c5900869a..d65a6dbca 100644 --- a/lix/libexpr/get-drvs.cc +++ b/lix/libexpr/get-drvs.cc @@ -25,7 +25,7 @@ DrvInfo::DrvInfo(ref store, const std::string & drvPathWithOutputs) this->drvPath = drvPath; - auto drv = store->derivationFromPath(drvPath); + auto drv = RUN_ASYNC_IN_NEW_THREAD(store->derivationFromPath(drvPath)); name = drvPath.name(); diff --git a/lix/libstore/misc.cc b/lix/libstore/misc.cc index 9b3a44032..ca62e998d 100644 --- a/lix/libstore/misc.cc +++ b/lix/libstore/misc.cc @@ -235,7 +235,7 @@ struct QueryMissingContext } if (knownOutputPaths && invalid.empty()) return; - auto drv = make_ref(store.derivationFromPath(drvPath)); + auto drv = make_ref(aio.blockOn(store.derivationFromPath(drvPath))); ParsedDerivation parsedDrv(StorePath(drvPath), *drv); if (!knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) { diff --git a/lix/libstore/store-api.cc b/lix/libstore/store-api.cc index c97877331..d59f4619c 100644 --- a/lix/libstore/store-api.cc +++ b/lix/libstore/store-api.cc @@ -937,7 +937,7 @@ StorePathSet Store::exportReferences(const StorePathSet & storePaths, const Stor for (auto & j : paths2) { if (j.isDerivation()) { - Derivation drv = derivationFromPath(j); + Derivation drv = RUN_ASYNC_IN_NEW_THREAD(derivationFromPath(j)); for (auto & k : drv.outputsAndOptPaths(*this)) { if (!k.second.second) /* FIXME: I am confused why we are calling @@ -1359,10 +1359,12 @@ std::string showPaths(const PathSet & paths) } -Derivation Store::derivationFromPath(const StorePath & drvPath) -{ - RUN_ASYNC_IN_NEW_THREAD(ensurePath(drvPath)); - return readDerivation(drvPath); +kj::Promise> Store::derivationFromPath(const StorePath & drvPath) +try { + TRY_AWAIT(ensurePath(drvPath)); + co_return readDerivation(drvPath); +} catch (...) { + co_return result::current_exception(); } Derivation readDerivationCommon(Store& store, const StorePath& drvPath, bool requireValidPath) diff --git a/lix/libstore/store-api.hh b/lix/libstore/store-api.hh index 71ccf173d..7957d00a0 100644 --- a/lix/libstore/store-api.hh +++ b/lix/libstore/store-api.hh @@ -732,7 +732,7 @@ public: * Read a derivation, after ensuring its existence through * ensurePath(). */ - Derivation derivationFromPath(const StorePath & drvPath); + kj::Promise> derivationFromPath(const StorePath & drvPath); /** * Read a derivation (which must already be valid). diff --git a/lix/nix/develop.cc b/lix/nix/develop.cc index 054e76302..5fa365ab1 100644 --- a/lix/nix/develop.cc +++ b/lix/nix/develop.cc @@ -212,7 +212,7 @@ const static std::string getEnvSh = environment to a file and exits. */ static kj::Promise> getDerivationEnvironment(ref store, ref evalStore, const StorePath & drvPath) try { - auto drv = evalStore->derivationFromPath(drvPath); + auto drv = TRY_AWAIT(evalStore->derivationFromPath(drvPath)); auto builder = baseNameOf(drv.builder); if (builder != "bash") diff --git a/perl/lib/Nix/Store.xs b/perl/lib/Nix/Store.xs index faa368ad5..7f8ca051f 100644 --- a/perl/lib/Nix/Store.xs +++ b/perl/lib/Nix/Store.xs @@ -17,6 +17,7 @@ #include "lix/libstore/globals.hh" #include "lix/libstore/store-api.hh" #include "lix/libstore/crypto.hh" +#include "lix/libutil/async.hh" #include #include @@ -39,6 +40,12 @@ static ref store() return ref(_store); } +static AsyncIoRoot & aio() +{ + static thread_local AsyncIoRoot root; + return root; +} + MODULE = Nix::Store PACKAGE = Nix::Store PROTOTYPES: ENABLE @@ -313,7 +320,7 @@ SV * derivationFromPath(char * drvPath) HV *hash; CODE: try { - Derivation drv = store()->derivationFromPath(store()->parseStorePath(drvPath)); + Derivation drv = aio().blockOn(store()->derivationFromPath(store()->parseStorePath(drvPath))); hash = newHV(); HV * outputs = newHV();