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
This commit is contained in:
@@ -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<DerivedPath> & reqs, BuildMode buildMode, std::shared_ptr<Store> 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<Error> ex;
|
||||
@@ -47,16 +45,13 @@ std::vector<KeyedBuildResult> Store::buildPathsWithResults(
|
||||
BuildMode buildMode,
|
||||
std::shared_ptr<Store> 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<KeyedBuildResult> results;
|
||||
|
||||
@@ -69,15 +64,12 @@ std::vector<KeyedBuildResult> 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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user