libstore: add "is dependency" info to goal

whether goal errors are reported via the `ex` member or just printed to
the log depends on whether the goal is a toplevel goal or a dependency.
if goals are aware of this themselves we can move error printing out of
the worker loop, and since a running worker can only be used by running
goals it's totally sufficient to keep a `Worker::running` flag for this

Change-Id: I6b5cbe6eccee1afa5fde80653c4b968554ddd16f
This commit is contained in:
eldritch horrors 2024-08-25 13:41:56 +02:00
parent bb161a96cf
commit a5c1e73fa8
11 changed files with 86 additions and 32 deletions

View file

@ -58,8 +58,8 @@
namespace nix { namespace nix {
DerivationGoal::DerivationGoal(const StorePath & drvPath, DerivationGoal::DerivationGoal(const StorePath & drvPath,
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode) const OutputsSpec & wantedOutputs, Worker & worker, bool isDependency, BuildMode buildMode)
: Goal(worker) : Goal(worker, isDependency)
, useDerivation(true) , useDerivation(true)
, drvPath(drvPath) , drvPath(drvPath)
, wantedOutputs(wantedOutputs) , wantedOutputs(wantedOutputs)
@ -76,8 +76,8 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath,
DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode) const OutputsSpec & wantedOutputs, Worker & worker, bool isDependency, BuildMode buildMode)
: Goal(worker) : Goal(worker, isDependency)
, useDerivation(false) , useDerivation(false)
, drvPath(drvPath) , drvPath(drvPath)
, wantedOutputs(wantedOutputs) , wantedOutputs(wantedOutputs)

View file

@ -234,10 +234,10 @@ struct DerivationGoal : public Goal
std::string machineName; std::string machineName;
DerivationGoal(const StorePath & drvPath, DerivationGoal(const StorePath & drvPath,
const OutputsSpec & wantedOutputs, Worker & worker, const OutputsSpec & wantedOutputs, Worker & worker, bool isDependency,
BuildMode buildMode = bmNormal); BuildMode buildMode = bmNormal);
DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
const OutputsSpec & wantedOutputs, Worker & worker, const OutputsSpec & wantedOutputs, Worker & worker, bool isDependency,
BuildMode buildMode = bmNormal); BuildMode buildMode = bmNormal);
virtual ~DerivationGoal() noexcept(false); virtual ~DerivationGoal() noexcept(false);

View file

@ -9,9 +9,10 @@ namespace nix {
DrvOutputSubstitutionGoal::DrvOutputSubstitutionGoal( DrvOutputSubstitutionGoal::DrvOutputSubstitutionGoal(
const DrvOutput & id, const DrvOutput & id,
Worker & worker, Worker & worker,
bool isDependency,
RepairFlag repair, RepairFlag repair,
std::optional<ContentAddress> ca) std::optional<ContentAddress> ca)
: Goal(worker) : Goal(worker, isDependency)
, id(id) , id(id)
{ {
state = &DrvOutputSubstitutionGoal::init; state = &DrvOutputSubstitutionGoal::init;

View file

@ -56,7 +56,13 @@ class DrvOutputSubstitutionGoal : public Goal {
bool substituterFailed = false; bool substituterFailed = false;
public: public:
DrvOutputSubstitutionGoal(const DrvOutput& id, Worker & worker, RepairFlag repair = NoRepair, std::optional<ContentAddress> ca = std::nullopt); DrvOutputSubstitutionGoal(
const DrvOutput & id,
Worker & worker,
bool isDependency,
RepairFlag repair = NoRepair,
std::optional<ContentAddress> ca = std::nullopt
);
typedef WorkResult (DrvOutputSubstitutionGoal::*GoalState)(bool inBuildSlot); typedef WorkResult (DrvOutputSubstitutionGoal::*GoalState)(bool inBuildSlot);
GoalState state; GoalState state;

View file

@ -60,6 +60,13 @@ struct Goal
*/ */
Worker & worker; Worker & worker;
/**
* Whether this goal is only a dependency of other goals. Toplevel
* goals that are also dependencies of other toplevel goals do not
* set this, only goals that are exclusively dependencies do this.
*/
const bool isDependency;
/** /**
* Goals that this goal is waiting for. * Goals that this goal is waiting for.
*/ */
@ -143,8 +150,9 @@ public:
*/ */
std::shared_ptr<Error> ex; std::shared_ptr<Error> ex;
explicit Goal(Worker & worker) explicit Goal(Worker & worker, bool isDependency)
: worker(worker) : worker(worker)
, isDependency(isDependency)
{ } { }
virtual ~Goal() noexcept(false) virtual ~Goal() noexcept(false)

View file

@ -186,6 +186,7 @@ struct LocalDerivationGoal : public DerivationGoal
const StorePath & drvPath, const StorePath & drvPath,
const OutputsSpec & wantedOutputs, const OutputsSpec & wantedOutputs,
Worker & worker, Worker & worker,
bool isDependency,
BuildMode buildMode BuildMode buildMode
); );
@ -198,6 +199,7 @@ struct LocalDerivationGoal : public DerivationGoal
const BasicDerivation & drv, const BasicDerivation & drv,
const OutputsSpec & wantedOutputs, const OutputsSpec & wantedOutputs,
Worker & worker, Worker & worker,
bool isDependency,
BuildMode buildMode BuildMode buildMode
); );

View file

@ -6,8 +6,14 @@
namespace nix { namespace nix {
PathSubstitutionGoal::PathSubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair, std::optional<ContentAddress> ca) PathSubstitutionGoal::PathSubstitutionGoal(
: Goal(worker) const StorePath & storePath,
Worker & worker,
bool isDependency,
RepairFlag repair,
std::optional<ContentAddress> ca
)
: Goal(worker, isDependency)
, storePath(storePath) , storePath(storePath)
, repair(repair) , repair(repair)
, ca(ca) , ca(ca)

View file

@ -80,7 +80,13 @@ struct PathSubstitutionGoal : public Goal
std::optional<std::string> errorMsg = {}); std::optional<std::string> errorMsg = {});
public: public:
PathSubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair, std::optional<ContentAddress> ca = std::nullopt); PathSubstitutionGoal(
const StorePath & storePath,
Worker & worker,
bool isDependency,
RepairFlag repair = NoRepair,
std::optional<ContentAddress> ca = std::nullopt
);
~PathSubstitutionGoal(); ~PathSubstitutionGoal();
Finished timedOut(Error && ex) override { abort(); }; Finished timedOut(Error && ex) override { abort(); };

View file

@ -1,5 +1,6 @@
#include "charptr-cast.hh" #include "charptr-cast.hh"
#include "worker.hh" #include "worker.hh"
#include "finally.hh"
#include "substitution-goal.hh" #include "substitution-goal.hh"
#include "drv-output-substitution-goal.hh" #include "drv-output-substitution-goal.hh"
#include "local-derivation-goal.hh" #include "local-derivation-goal.hh"
@ -59,22 +60,38 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon(
std::shared_ptr<DerivationGoal> Worker::makeDerivationGoal(const StorePath & drvPath, std::shared_ptr<DerivationGoal> Worker::makeDerivationGoal(const StorePath & drvPath,
const OutputsSpec & wantedOutputs, BuildMode buildMode) const OutputsSpec & wantedOutputs, BuildMode buildMode)
{ {
return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr<DerivationGoal> { return makeDerivationGoalCommon(
return !dynamic_cast<LocalStore *>(&store) drvPath,
? std::make_shared<DerivationGoal>(drvPath, wantedOutputs, *this, buildMode) wantedOutputs,
: LocalDerivationGoal::makeLocalDerivationGoal(drvPath, wantedOutputs, *this, buildMode); [&]() -> std::shared_ptr<DerivationGoal> {
}); return !dynamic_cast<LocalStore *>(&store)
? std::make_shared<DerivationGoal>(
drvPath, wantedOutputs, *this, running, buildMode
)
: LocalDerivationGoal::makeLocalDerivationGoal(
drvPath, wantedOutputs, *this, running, buildMode
);
}
);
} }
std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath & drvPath, std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath & drvPath,
const BasicDerivation & drv, const OutputsSpec & wantedOutputs, BuildMode buildMode) const BasicDerivation & drv, const OutputsSpec & wantedOutputs, BuildMode buildMode)
{ {
return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr<DerivationGoal> { return makeDerivationGoalCommon(
return !dynamic_cast<LocalStore *>(&store) drvPath,
? std::make_shared<DerivationGoal>(drvPath, drv, wantedOutputs, *this, buildMode) wantedOutputs,
: LocalDerivationGoal::makeLocalDerivationGoal(drvPath, drv, wantedOutputs, *this, buildMode); [&]() -> std::shared_ptr<DerivationGoal> {
}); return !dynamic_cast<LocalStore *>(&store)
? std::make_shared<DerivationGoal>(
drvPath, drv, wantedOutputs, *this, running, buildMode
)
: LocalDerivationGoal::makeLocalDerivationGoal(
drvPath, drv, wantedOutputs, *this, running, buildMode
);
}
);
} }
@ -83,7 +100,7 @@ std::shared_ptr<PathSubstitutionGoal> Worker::makePathSubstitutionGoal(const Sto
std::weak_ptr<PathSubstitutionGoal> & goal_weak = substitutionGoals[path]; std::weak_ptr<PathSubstitutionGoal> & goal_weak = substitutionGoals[path];
auto goal = goal_weak.lock(); // FIXME auto goal = goal_weak.lock(); // FIXME
if (!goal) { if (!goal) {
goal = std::make_shared<PathSubstitutionGoal>(path, *this, repair, ca); goal = std::make_shared<PathSubstitutionGoal>(path, *this, running, repair, ca);
goal_weak = goal; goal_weak = goal;
wakeUp(goal); wakeUp(goal);
} }
@ -96,7 +113,7 @@ std::shared_ptr<DrvOutputSubstitutionGoal> Worker::makeDrvOutputSubstitutionGoal
std::weak_ptr<DrvOutputSubstitutionGoal> & goal_weak = drvOutputSubstitutionGoals[id]; std::weak_ptr<DrvOutputSubstitutionGoal> & goal_weak = drvOutputSubstitutionGoals[id];
auto goal = goal_weak.lock(); // FIXME auto goal = goal_weak.lock(); // FIXME
if (!goal) { if (!goal) {
goal = std::make_shared<DrvOutputSubstitutionGoal>(id, *this, repair, ca); goal = std::make_shared<DrvOutputSubstitutionGoal>(id, *this, running, repair, ca);
goal_weak = goal; goal_weak = goal;
wakeUp(goal); wakeUp(goal);
} }
@ -313,6 +330,10 @@ void Worker::run(const Goals & _topGoals)
{ {
std::vector<nix::DerivedPath> topPaths; std::vector<nix::DerivedPath> topPaths;
assert(!running);
running = true;
Finally const _stop([&] { running = false; });
for (auto & i : _topGoals) { for (auto & i : _topGoals) {
topGoals.insert(i); topGoals.insert(i);
if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) { if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) {

View file

@ -47,6 +47,8 @@ class Worker
{ {
private: private:
bool running = false;
/* Note: the worker should only have strong pointers to the /* Note: the worker should only have strong pointers to the
top-level goals. */ top-level goals. */

View file

@ -29,17 +29,18 @@ std::shared_ptr<LocalDerivationGoal> LocalDerivationGoal::makeLocalDerivationGoa
const StorePath & drvPath, const StorePath & drvPath,
const OutputsSpec & wantedOutputs, const OutputsSpec & wantedOutputs,
Worker & worker, Worker & worker,
bool isDependency,
BuildMode buildMode BuildMode buildMode
) )
{ {
#if __linux__ #if __linux__
return std::make_shared<LinuxLocalDerivationGoal>(drvPath, wantedOutputs, worker, buildMode); return std::make_shared<LinuxLocalDerivationGoal>(drvPath, wantedOutputs, worker, isDependency, buildMode);
#elif __APPLE__ #elif __APPLE__
return std::make_shared<DarwinLocalDerivationGoal>(drvPath, wantedOutputs, worker, buildMode); return std::make_shared<DarwinLocalDerivationGoal>(drvPath, wantedOutputs, worker, isDependency, buildMode);
#elif __FreeBSD__ #elif __FreeBSD__
return std::make_shared<FreeBSDLocalDerivationGoal>(drvPath, wantedOutputs, worker, buildMode); return std::make_shared<FreeBSDLocalDerivationGoal>(drvPath, wantedOutputs, worker, isDependency, buildMode);
#else #else
return std::make_shared<FallbackLocalDerivationGoal>(drvPath, wantedOutputs, worker, buildMode); return std::make_shared<FallbackLocalDerivationGoal>(drvPath, wantedOutputs, worker, isDependency, buildMode);
#endif #endif
} }
@ -48,24 +49,25 @@ std::shared_ptr<LocalDerivationGoal> LocalDerivationGoal::makeLocalDerivationGoa
const BasicDerivation & drv, const BasicDerivation & drv,
const OutputsSpec & wantedOutputs, const OutputsSpec & wantedOutputs,
Worker & worker, Worker & worker,
bool isDependency,
BuildMode buildMode BuildMode buildMode
) )
{ {
#if __linux__ #if __linux__
return std::make_shared<LinuxLocalDerivationGoal>( return std::make_shared<LinuxLocalDerivationGoal>(
drvPath, drv, wantedOutputs, worker, buildMode drvPath, drv, wantedOutputs, worker, isDependency, buildMode
); );
#elif __APPLE__ #elif __APPLE__
return std::make_shared<DarwinLocalDerivationGoal>( return std::make_shared<DarwinLocalDerivationGoal>(
drvPath, drv, wantedOutputs, worker, buildMode drvPath, drv, wantedOutputs, worker, isDependency, buildMode
); );
#elif __FreeBSD__ #elif __FreeBSD__
return std::make_shared<FreeBSDLocalDerivationGoal>( return std::make_shared<FreeBSDLocalDerivationGoal>(
drvPath, drv, wantedOutputs, worker, buildMode drvPath, drv, wantedOutputs, worker, isDependency, buildMode
); );
#else #else
return std::make_shared<FallbackLocalDerivationGoal>( return std::make_shared<FallbackLocalDerivationGoal>(
drvPath, drv, wantedOutputs, worker, buildMode drvPath, drv, wantedOutputs, worker, isDependency, buildMode
); );
#endif #endif
} }