diff --git a/lix/libstore/build/entry-points.cc b/lix/libstore/build/entry-points.cc index 4dd471e40..065a23d59 100644 --- a/lix/libstore/build/entry-points.cc +++ b/lix/libstore/build/entry-points.cc @@ -76,11 +76,20 @@ kj::Promise> Store::buildDerivation(const StorePath & drvPat try { try { auto results = TRY_AWAIT(processGoals(*this, *this, [&](GoalFactory & gf) { - Worker::Targets goals; - goals.emplace_back( - gf.makeBasicDerivationGoal(drvPath, drv, OutputsSpec::All{}, buildMode) - ); - return goals; + // sometimes clang lints are really annoying. this would be safe without + // the explicit coroutine param captures, but clang-tidy does not see it + return [](auto && gf, auto && drvPath, auto && drv, auto buildMode + ) -> kj::Promise> { + try { + Worker::Targets goals; + goals.emplace_back(TRY_AWAIT( + gf.makeBasicDerivationGoal(drvPath, drv, OutputsSpec::All{}, buildMode) + )); + co_return goals; + } catch (...) { + co_return result::current_exception(); + } + }(gf, drvPath, drv, buildMode); })); auto & result = results.goals.begin()->second; co_return result.result.restrictTo(DerivedPath::Built { diff --git a/lix/libstore/build/worker.cc b/lix/libstore/build/worker.cc index e3e9b7849..ff8ba2ab4 100644 --- a/lix/libstore/build/worker.cc +++ b/lix/libstore/build/worker.cc @@ -135,18 +135,20 @@ std::pair, kj::Promise> } -std::pair, kj::Promise>> Worker::makeBasicDerivationGoal( +kj::Promise< + Result, kj::Promise>>>> +Worker::makeBasicDerivationGoal( const StorePath & drvPath, const BasicDerivation & drv, const OutputsSpec & wantedOutputs, BuildMode buildMode ) -{ +try { /* Prevent the .chroot directory from being garbage-collected. (See isActiveTempFile() in gc.cc.) */ store.addTempRoot(drvPath); - return makeGoalCommon( + co_return makeGoalCommon( derivationGoals, drvPath, [&]() -> std::unique_ptr { @@ -160,6 +162,8 @@ std::pair, kj::Promise> }, [&](DerivationGoal & g) { return g.addWantedOutputs(wantedOutputs); } ); +} catch (...) { + co_return result::current_exception(); } @@ -232,10 +236,8 @@ try { co_return result::current_exception(); } -kj::Promise> Worker::run(std::function req) +kj::Promise> Worker::run(Targets topGoals) try { - auto topGoals = req(goalFactory()); - assert(!running); running = true; Finally const _stop([&] { running = false; }); diff --git a/lix/libstore/build/worker.hh b/lix/libstore/build/worker.hh index c742c80ed..7fc3d1fe9 100644 --- a/lix/libstore/build/worker.hh +++ b/lix/libstore/build/worker.hh @@ -5,6 +5,7 @@ #include "lix/libutil/async-semaphore.hh" #include "lix/libutil/concepts.hh" #include "lix/libutil/notifying-counter.hh" +#include "lix/libutil/result.hh" #include "lix/libutil/types.hh" #include "lix/libstore/lock.hh" #include "lix/libstore/store-api.hh" @@ -35,7 +36,8 @@ public: makeDerivationGoal( const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal ) = 0; - virtual std::pair, kj::Promise>> + virtual kj::Promise< + Result, kj::Promise>>>> makeBasicDerivationGoal( const StorePath & drvPath, const BasicDerivation & drv, @@ -245,9 +247,14 @@ private: std::pair, kj::Promise>> makeDerivationGoal( const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override; - std::pair, kj::Promise>> makeBasicDerivationGoal( - const StorePath & drvPath, const BasicDerivation & drv, - const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override; + kj::Promise< + Result, kj::Promise>>>> + makeBasicDerivationGoal( + const StorePath & drvPath, + const BasicDerivation & drv, + const OutputsSpec & wantedOutputs, + BuildMode buildMode = bmNormal + ) override; /** * @ref SubstitutionGoal "substitution goal" @@ -274,11 +281,25 @@ private: std::pair>> makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) override; + kj::Promise> run(Targets topGoals); + public: /** * Loop until the specified top-level goals have finished. */ - kj::Promise> run(std::function req); + kj::Promise> run(std::function>(GoalFactory &)> req) + try { + co_return co_await run(TRY_AWAIT(req(goalFactory()))); + } catch (...) { + co_return result::current_exception(); + } + + kj::Promise> run(std::function req) + try { + return run(req(goalFactory())); + } catch (...) { + return {result::current_exception()}; + } /** * Check whether the given valid path exists and has the right