diff options
Diffstat (limited to 'src/libstore/build/worker.cc')
-rw-r--r-- | src/libstore/build/worker.cc | 98 |
1 files changed, 70 insertions, 28 deletions
diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc index 5c3fe2f57..0f2ade348 100644 --- a/src/libstore/build/worker.cc +++ b/src/libstore/build/worker.cc @@ -1,14 +1,15 @@ #include "machines.hh" #include "worker.hh" #include "substitution-goal.hh" -#include "derivation-goal.hh" +#include "drv-output-substitution-goal.hh" +#include "local-derivation-goal.hh" #include "hook-instance.hh" #include <poll.h> namespace nix { -Worker::Worker(LocalStore & store) +Worker::Worker(Store & store) : act(*logger, actRealise) , actDerivations(*logger, actBuilds) , actSubstitutions(*logger, actCopyPaths) @@ -43,16 +44,13 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon( const StringSet & wantedOutputs, std::function<std::shared_ptr<DerivationGoal>()> mkDrvGoal) { - WeakGoalPtr & abstract_goal_weak = derivationGoals[drvPath]; - GoalPtr abstract_goal = abstract_goal_weak.lock(); // FIXME - std::shared_ptr<DerivationGoal> goal; - if (!abstract_goal) { + std::weak_ptr<DerivationGoal> & goal_weak = derivationGoals[drvPath]; + std::shared_ptr<DerivationGoal> goal = goal_weak.lock(); + if (!goal) { goal = mkDrvGoal(); - abstract_goal_weak = goal; + goal_weak = goal; wakeUp(goal); } else { - goal = std::dynamic_pointer_cast<DerivationGoal>(abstract_goal); - assert(goal); goal->addWantedOutputs(wantedOutputs); } return goal; @@ -62,8 +60,10 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon( std::shared_ptr<DerivationGoal> Worker::makeDerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs, BuildMode buildMode) { - return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() { - return std::make_shared<DerivationGoal>(drvPath, wantedOutputs, *this, buildMode); + return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr<DerivationGoal> { + return !dynamic_cast<LocalStore *>(&store) + ? std::make_shared</* */DerivationGoal>(drvPath, wantedOutputs, *this, buildMode) + : std::make_shared<LocalDerivationGoal>(drvPath, wantedOutputs, *this, buildMode); }); } @@ -71,32 +71,46 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoal(const StorePath & drv std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, const StringSet & wantedOutputs, BuildMode buildMode) { - return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() { - return std::make_shared<DerivationGoal>(drvPath, drv, wantedOutputs, *this, buildMode); + return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr<DerivationGoal> { + return !dynamic_cast<LocalStore *>(&store) + ? std::make_shared</* */DerivationGoal>(drvPath, drv, wantedOutputs, *this, buildMode) + : std::make_shared<LocalDerivationGoal>(drvPath, drv, wantedOutputs, *this, buildMode); }); } -GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca) +std::shared_ptr<PathSubstitutionGoal> Worker::makePathSubstitutionGoal(const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca) { - WeakGoalPtr & goal_weak = substitutionGoals[path]; - GoalPtr goal = goal_weak.lock(); // FIXME + std::weak_ptr<PathSubstitutionGoal> & goal_weak = substitutionGoals[path]; + auto goal = goal_weak.lock(); // FIXME if (!goal) { - goal = std::make_shared<SubstitutionGoal>(path, *this, repair, ca); + goal = std::make_shared<PathSubstitutionGoal>(path, *this, repair, ca); goal_weak = goal; wakeUp(goal); } return goal; } +std::shared_ptr<DrvOutputSubstitutionGoal> Worker::makeDrvOutputSubstitutionGoal(const DrvOutput& id, RepairFlag repair, std::optional<ContentAddress> ca) +{ + std::weak_ptr<DrvOutputSubstitutionGoal> & goal_weak = drvOutputSubstitutionGoals[id]; + auto goal = goal_weak.lock(); // FIXME + if (!goal) { + goal = std::make_shared<DrvOutputSubstitutionGoal>(id, *this, repair, ca); + goal_weak = goal; + wakeUp(goal); + } + return goal; +} -static void removeGoal(GoalPtr goal, WeakGoalMap & goalMap) +template<typename K, typename G> +static void removeGoal(std::shared_ptr<G> goal, std::map<K, std::weak_ptr<G>> & goalMap) { /* !!! inefficient */ - for (WeakGoalMap::iterator i = goalMap.begin(); + for (auto i = goalMap.begin(); i != goalMap.end(); ) if (i->second.lock() == goal) { - WeakGoalMap::iterator j = i; ++j; + auto j = i; ++j; goalMap.erase(i); i = j; } @@ -106,8 +120,15 @@ static void removeGoal(GoalPtr goal, WeakGoalMap & goalMap) void Worker::removeGoal(GoalPtr goal) { - nix::removeGoal(goal, derivationGoals); - nix::removeGoal(goal, substitutionGoals); + if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal)) + nix::removeGoal(drvGoal, derivationGoals); + else if (auto subGoal = std::dynamic_pointer_cast<PathSubstitutionGoal>(goal)) + nix::removeGoal(subGoal, substitutionGoals); + else if (auto subGoal = std::dynamic_pointer_cast<DrvOutputSubstitutionGoal>(goal)) + nix::removeGoal(subGoal, drvOutputSubstitutionGoals); + else + assert(false); + if (topGoals.find(goal) != topGoals.end()) { topGoals.erase(goal); /* If a top-level goal failed, then kill all other goals @@ -206,7 +227,21 @@ void Worker::waitForAWhile(GoalPtr goal) void Worker::run(const Goals & _topGoals) { - for (auto & i : _topGoals) topGoals.insert(i); + std::vector<nix::DerivedPath> topPaths; + + for (auto & i : _topGoals) { + topGoals.insert(i); + if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) { + topPaths.push_back(DerivedPath::Built{goal->drvPath, goal->wantedOutputs}); + } else if (auto goal = dynamic_cast<PathSubstitutionGoal *>(i.get())) { + topPaths.push_back(DerivedPath::Opaque{goal->storePath}); + } + } + + /* Call queryMissing() efficiently query substitutes. */ + StorePathSet willBuild, willSubstitute, unknown; + uint64_t downloadSize, narSize; + store.queryMissing(topPaths, willBuild, willSubstitute, unknown, downloadSize, narSize); debug("entered goal loop"); @@ -214,7 +249,9 @@ void Worker::run(const Goals & _topGoals) checkInterrupt(); - store.autoGC(false); + // TODO GC interface? + if (auto localStore = dynamic_cast<LocalStore *>(&store)) + localStore->autoGC(false); /* Call every wake goal (in the ordering established by CompareGoalPtrs). */ @@ -439,10 +476,7 @@ bool Worker::pathContentsGood(const StorePath & path) } pathContentsGoodCache.insert_or_assign(path, res); if (!res) - logError({ - .name = "Corrupted path", - .hint = hintfmt("path '%s' is corrupted or missing!", store.printStorePath(path)) - }); + printError("path '%s' is corrupted or missing!", store.printStorePath(path)); return res; } @@ -452,4 +486,12 @@ void Worker::markContentsGood(const StorePath & path) pathContentsGoodCache.insert_or_assign(path, true); } + +GoalPtr upcast_goal(std::shared_ptr<PathSubstitutionGoal> subGoal) { + return subGoal; +} +GoalPtr upcast_goal(std::shared_ptr<DrvOutputSubstitutionGoal> subGoal) { + return subGoal; +} + } |