From 0275b9a92fdc65bb31276b38873673f30f82c200 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Thu, 23 Jan 2025 23:38:07 +0100 Subject: [PATCH] async: open the floodgates. this will let us add AsyncIoRoots to the toplevel objects and functions. eventually we'll get rid of all offloading again byt covering the entire space between main() and the worker entry points with promises. it won't be a quick and easy journey; we have somewhere around 200 functions that must be converted to async code, and some building blocks that are fully incompatible with event loops on their own. this ranges from simple bits like thread pools (which we can wrap in promise-fulfiller pairs), bigger bits like the curl wrapper (which we can make async, but not easily), or even impossible bits (like the libarchive wrapper, which can't be turned into async code at all. not to worry though, we have *plans* for those.) Change-Id: I95b91b0545659ece4ec1b85214df1ce2f1bc0164 --- lix/libstore/build/entry-points.cc | 40 ++++++++++-------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/lix/libstore/build/entry-points.cc b/lix/libstore/build/entry-points.cc index fc29aae39..db4c3f891 100644 --- a/lix/libstore/build/entry-points.cc +++ b/lix/libstore/build/entry-points.cc @@ -2,21 +2,19 @@ #include "lix/libstore/build/substitution-goal.hh" #include "lix/libstore/build/derivation-goal.hh" #include "lix/libstore/local-store.hh" +#include "lix/libutil/async.hh" #include "lix/libutil/strings.hh" namespace nix { void Store::buildPaths(const std::vector & reqs, BuildMode buildMode, std::shared_ptr evalStore) { - auto kjaio = kj::setupAsyncIo(); - AsyncContext aio(kjaio); - - auto results = processGoals(*this, evalStore ? *evalStore : *this, [&](GoalFactory & gf) { + auto results = RUN_ASYNC_IN_NEW_THREAD(processGoals(*this, evalStore ? *evalStore : *this, [&](GoalFactory & gf) { Worker::Targets goals; for (auto & br : reqs) goals.emplace_back(gf.makeGoal(br, buildMode)); return goals; - }).wait(kjaio.waitScope).value(); + })); StringSet failed; std::shared_ptr ex; @@ -47,16 +45,13 @@ std::vector Store::buildPathsWithResults( BuildMode buildMode, std::shared_ptr evalStore) { - auto kjaio = kj::setupAsyncIo(); - AsyncContext aio(kjaio); - - auto goals = processGoals(*this, evalStore ? *evalStore : *this, [&](GoalFactory & gf) { + auto goals = RUN_ASYNC_IN_NEW_THREAD(processGoals(*this, evalStore ? *evalStore : *this, [&](GoalFactory & gf) { Worker::Targets goals; for (const auto & req : reqs) { goals.emplace_back(gf.makeGoal(req, buildMode)); } return goals; - }).wait(kjaio.waitScope).value().goals; + })).goals; std::vector results; @@ -69,15 +64,12 @@ std::vector Store::buildPathsWithResults( BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivation & drv, BuildMode buildMode) { - auto kjaio = kj::setupAsyncIo(); - AsyncContext aio(kjaio); - try { - auto results = processGoals(*this, *this, [&](GoalFactory & gf) { + auto results = RUN_ASYNC_IN_NEW_THREAD(processGoals(*this, *this, [&](GoalFactory & gf) { Worker::Targets goals; goals.emplace_back(gf.makeBasicDerivationGoal(drvPath, drv, OutputsSpec::All{}, buildMode)); return goals; - }).wait(kjaio.waitScope).value(); + })); auto & result = results.goals.begin()->second; return result.result.restrictTo(DerivedPath::Built { .drvPath = makeConstantStorePathRef(drvPath), @@ -97,14 +89,11 @@ void Store::ensurePath(const StorePath & path) /* If the path is already valid, we're done. */ if (isValidPath(path)) return; - auto kjaio = kj::setupAsyncIo(); - AsyncContext aio(kjaio); - - auto results = processGoals(*this, *this, [&](GoalFactory & gf) { + auto results = RUN_ASYNC_IN_NEW_THREAD(processGoals(*this, *this, [&](GoalFactory & gf) { Worker::Targets goals; goals.emplace_back(gf.makePathSubstitutionGoal(path)); return goals; - }).wait(kjaio.waitScope).value(); + })); auto & result = results.goals.begin()->second; if (result.exitCode != Goal::ecSuccess) { @@ -119,14 +108,11 @@ void Store::ensurePath(const StorePath & path) void Store::repairPath(const StorePath & path) { - auto kjaio = kj::setupAsyncIo(); - AsyncContext aio(kjaio); - - auto results = processGoals(*this, *this, [&](GoalFactory & gf) { + auto results = RUN_ASYNC_IN_NEW_THREAD(processGoals(*this, *this, [&](GoalFactory & gf) { Worker::Targets goals; goals.emplace_back(gf.makePathSubstitutionGoal(path, Repair)); return goals; - }).wait(kjaio.waitScope).value(); + })); auto & result = results.goals.begin()->second; if (result.exitCode != Goal::ecSuccess) { @@ -134,7 +120,7 @@ void Store::repairPath(const StorePath & path) deriver, then rebuild the deriver. */ auto info = queryPathInfo(path); if (info->deriver && isValidPath(*info->deriver)) { - processGoals(*this, *this, [&](GoalFactory & gf) { + RUN_ASYNC_IN_NEW_THREAD(processGoals(*this, *this, [&](GoalFactory & gf) { Worker::Targets goals; goals.emplace_back(gf.makeGoal( DerivedPath::Built{ @@ -145,7 +131,7 @@ void Store::repairPath(const StorePath & path) bmRepair )); return goals; - }).wait(kjaio.waitScope).value(); + })); } else throw Error(results.failingExitStatus, "cannot repair path '%s'", printStorePath(path)); }