diff --git a/lix/libexpr/flake/flakeref.cc b/lix/libexpr/flake/flakeref.cc index a26ce741e..663c637c8 100644 --- a/lix/libexpr/flake/flakeref.cc +++ b/lix/libexpr/flake/flakeref.cc @@ -1,5 +1,6 @@ #include "lix/libexpr/flake/flakeref.hh" #include "lix/libstore/store-api.hh" +#include "lix/libutil/async.hh" #include "lix/libutil/url.hh" #include "lix/libutil/url-parts.hh" #include "lix/libfetchers/fetchers.hh" @@ -239,7 +240,7 @@ FlakeRef FlakeRef::fromAttrs(const fetchers::Attrs & attrs) std::pair FlakeRef::fetchTree(ref store) const { - auto [tree, lockedInput] = input.fetch(store); + auto [tree, lockedInput] = RUN_ASYNC_IN_NEW_THREAD(input.fetch(store)); return {std::move(tree), FlakeRef(std::move(lockedInput), subdir)}; } diff --git a/lix/libexpr/primops/fetchMercurial.cc b/lix/libexpr/primops/fetchMercurial.cc index 45f2588d9..db89cd131 100644 --- a/lix/libexpr/primops/fetchMercurial.cc +++ b/lix/libexpr/primops/fetchMercurial.cc @@ -65,7 +65,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a auto input = fetchers::Input::fromAttrs(std::move(attrs)); // FIXME: use name - auto [tree, input2] = input.fetch(state.ctx.store); + auto [tree, input2] = state.aio.blockOn(input.fetch(state.ctx.store)); auto attrs2 = state.ctx.buildBindings(8); state.ctx.paths.mkStorePathString(tree.storePath, attrs2.alloc(state.ctx.s.outPath)); diff --git a/lix/libexpr/primops/fetchTree.cc b/lix/libexpr/primops/fetchTree.cc index c81d5ae91..8c3348496 100644 --- a/lix/libexpr/primops/fetchTree.cc +++ b/lix/libexpr/primops/fetchTree.cc @@ -192,7 +192,7 @@ static void fetchTree( state.ctx.errors.make("in pure evaluation mode, 'fetchTree' requires a locked input").atPos(pos).debugThrow(); } - auto [tree, input2] = input.fetch(state.ctx.store); + auto [tree, input2] = state.aio.blockOn(input.fetch(state.ctx.store)); state.ctx.paths.allowPath(tree.storePath); diff --git a/lix/libfetchers/fetchers.cc b/lix/libfetchers/fetchers.cc index 866794f9c..703e30bce 100644 --- a/lix/libfetchers/fetchers.cc +++ b/lix/libfetchers/fetchers.cc @@ -123,8 +123,8 @@ bool Input::contains(const Input & other) const return false; } -std::pair Input::fetch(ref store) const -{ +kj::Promise>> Input::fetch(ref store) const +try { if (!scheme) throw Error("cannot fetch unsupported input '%s'", attrsToJSON(toAttrs())); @@ -135,12 +135,15 @@ std::pair Input::fetch(ref store) const try { auto storePath = computeStorePath(*store); - RUN_ASYNC_IN_NEW_THREAD(store->ensurePath(storePath)); + TRY_AWAIT(store->ensurePath(storePath)); debug("using substituted/cached input '%s' in '%s'", to_string(), store->printStorePath(storePath)); - return {Tree { .actualPath = store->toRealPath(storePath), .storePath = std::move(storePath) }, *this}; + co_return { + Tree{.actualPath = store->toRealPath(storePath), .storePath = std::move(storePath)}, + *this + }; } catch (Error & e) { debug("substitution of input '%s' failed: %s", to_string(), e.what()); } @@ -197,7 +200,9 @@ std::pair Input::fetch(ref store) const assert(input.hasAllInfo()); - return {std::move(tree), input}; + co_return {std::move(tree), input}; +} catch (...) { + co_return result::current_exception(); } Input Input::applyOverrides( diff --git a/lix/libfetchers/fetchers.hh b/lix/libfetchers/fetchers.hh index 6854c1b92..4393b78c1 100644 --- a/lix/libfetchers/fetchers.hh +++ b/lix/libfetchers/fetchers.hh @@ -1,6 +1,7 @@ #pragma once ///@file +#include "lix/libutil/result.hh" #include "lix/libutil/types.hh" #include "lix/libutil/hash.hh" #include "lix/libutil/canon-path.hh" @@ -10,6 +11,7 @@ #include "lix/libutil/ref.hh" #include "lix/libutil/strings.hh" +#include #include namespace nix { class Store; } @@ -90,7 +92,7 @@ public: * Fetch the input into the Nix store, returning the location in * the Nix store and the locked input. */ - std::pair fetch(ref store) const; + kj::Promise>> fetch(ref store) const; Input applyOverrides( std::optional ref, diff --git a/lix/nix/flake.cc b/lix/nix/flake.cc index 7c65ffb16..2b45504dd 100644 --- a/lix/nix/flake.cc +++ b/lix/nix/flake.cc @@ -1070,7 +1070,7 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun auto storePath = dryRun ? (*inputNode)->lockedRef.input.computeStorePath(*store) - : (*inputNode)->lockedRef.input.fetch(store).first.storePath; + : aio().blockOn((*inputNode)->lockedRef.input.fetch(store)).first.storePath; if (json) { auto& jsonObj3 = jsonObj2[inputName]; jsonObj3["path"] = store->printStorePath(storePath); diff --git a/lix/nix/registry.cc b/lix/nix/registry.cc index 324af5000..caba6849f 100644 --- a/lix/nix/registry.cc +++ b/lix/nix/registry.cc @@ -196,7 +196,7 @@ struct CmdRegistryPin : RegistryCommand, EvalCommand auto ref = parseFlakeRef(url); auto lockedRef = parseFlakeRef(locked); registry->remove(ref.input); - auto [tree, resolved] = lockedRef.resolve(store).input.fetch(store); + auto [tree, resolved] = aio().blockOn(lockedRef.resolve(store).input.fetch(store)); fetchers::Attrs extraAttrs; if (ref.subdir != "") extraAttrs["dir"] = ref.subdir; registry->add(ref.input, resolved, extraAttrs);