libstore: move Goal::waiteeDone into Worker::goalFinished
this begins a long and arduous journey to remove all result state from
Goal, to eventually drop the std::enable_shared_from_this base, and to
completely eliminate all unsynchronized modification of states of both
Goal and Worker. by the end of this we will hopefully be able to start
and reap multiple derivation builds in parallel, which should speed up
the process quite a bit (at least for short local builds, others might
not notice a large difference. the build hooks will remain a problem.)
Change-Id: I57dcd9b2cab4636ed4aa24cdec67124fef883345
This commit is contained in:
parent
32ca194ebf
commit
66469fc281
|
@ -1541,10 +1541,8 @@ Goal::Finished DerivationGoal::done(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DerivationGoal::waiteeDone(GoalPtr waitee, ExitCode result)
|
void DerivationGoal::waiteeDone(GoalPtr waitee)
|
||||||
{
|
{
|
||||||
Goal::waiteeDone(waitee, result);
|
|
||||||
|
|
||||||
if (!useDerivation) return;
|
if (!useDerivation) return;
|
||||||
|
|
||||||
auto * dg = dynamic_cast<DerivationGoal *>(&*waitee);
|
auto * dg = dynamic_cast<DerivationGoal *>(&*waitee);
|
||||||
|
|
|
@ -332,7 +332,7 @@ struct DerivationGoal : public Goal
|
||||||
SingleDrvOutputs builtOutputs = {},
|
SingleDrvOutputs builtOutputs = {},
|
||||||
std::optional<Error> ex = {});
|
std::optional<Error> ex = {});
|
||||||
|
|
||||||
void waiteeDone(GoalPtr waitee, ExitCode result) override;
|
void waiteeDone(GoalPtr waitee) override;
|
||||||
|
|
||||||
StorePathSet exportReferences(const StorePathSet & storePaths);
|
StorePathSet exportReferences(const StorePathSet & storePaths);
|
||||||
|
|
||||||
|
|
|
@ -18,33 +18,6 @@ void Goal::addWaitee(GoalPtr waitee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
|
|
||||||
{
|
|
||||||
assert(waitees.count(waitee));
|
|
||||||
waitees.erase(waitee);
|
|
||||||
|
|
||||||
trace(fmt("waitee '%s' done; %d left", waitee->name, waitees.size()));
|
|
||||||
|
|
||||||
if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
|
|
||||||
|
|
||||||
if (result == ecNoSubstituters) ++nrNoSubstituters;
|
|
||||||
|
|
||||||
if (result == ecIncompleteClosure) ++nrIncompleteClosure;
|
|
||||||
|
|
||||||
if (waitees.empty() || (result == ecFailed && !settings.keepGoing)) {
|
|
||||||
|
|
||||||
/* If we failed and keepGoing is not set, we remove all
|
|
||||||
remaining waitees. */
|
|
||||||
for (auto & goal : waitees) {
|
|
||||||
goal->waiters.extract(shared_from_this());
|
|
||||||
}
|
|
||||||
waitees.clear();
|
|
||||||
|
|
||||||
worker.wakeUp(shared_from_this());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Goal::trace(std::string_view s)
|
void Goal::trace(std::string_view s)
|
||||||
{
|
{
|
||||||
debug("%1%: %2%", name, s);
|
debug("%1%: %2%", name, s);
|
||||||
|
|
|
@ -135,7 +135,7 @@ public:
|
||||||
|
|
||||||
void addWaitee(GoalPtr waitee);
|
void addWaitee(GoalPtr waitee);
|
||||||
|
|
||||||
virtual void waiteeDone(GoalPtr waitee, ExitCode result);
|
virtual void waiteeDone(GoalPtr waitee) { }
|
||||||
|
|
||||||
virtual WorkResult handleChildOutput(int fd, std::string_view data)
|
virtual WorkResult handleChildOutput(int fd, std::string_view data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -154,7 +154,27 @@ void Worker::goalFinished(GoalPtr goal, Goal::Finished & f)
|
||||||
|
|
||||||
for (auto & i : goal->waiters) {
|
for (auto & i : goal->waiters) {
|
||||||
if (GoalPtr waiting = i.lock()) {
|
if (GoalPtr waiting = i.lock()) {
|
||||||
waiting->waiteeDone(goal, f.result);
|
assert(waiting->waitees.count(goal));
|
||||||
|
waiting->waitees.erase(goal);
|
||||||
|
|
||||||
|
waiting->trace(fmt("waitee '%s' done; %d left", goal->name, waiting->waitees.size()));
|
||||||
|
|
||||||
|
if (f.result != Goal::ecSuccess) ++waiting->nrFailed;
|
||||||
|
if (f.result == Goal::ecNoSubstituters) ++waiting->nrNoSubstituters;
|
||||||
|
if (f.result == Goal::ecIncompleteClosure) ++waiting->nrIncompleteClosure;
|
||||||
|
|
||||||
|
if (waiting->waitees.empty() || (f.result == Goal::ecFailed && !settings.keepGoing)) {
|
||||||
|
/* If we failed and keepGoing is not set, we remove all
|
||||||
|
remaining waitees. */
|
||||||
|
for (auto & i : waiting->waitees) {
|
||||||
|
i->waiters.extract(waiting);
|
||||||
|
}
|
||||||
|
waiting->waitees.clear();
|
||||||
|
|
||||||
|
wakeUp(waiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
waiting->waiteeDone(goal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goal->waiters.clear();
|
goal->waiters.clear();
|
||||||
|
|
Loading…
Reference in a new issue