libstore: make Worker::childStarted private

this can be a proper WorkResult now. childTerminated is unfortunately a
lot more stubborn and won't be made private for quite a while yet. once
we can get rid of the Worker poll loop that *should* be possible though

Change-Id: I2218df202da5cb84e852f6a37e4c20367495b617
This commit is contained in:
eldritch horrors 2024-08-14 12:32:26 +02:00 committed by jade
parent fca523d661
commit b40369942c
9 changed files with 35 additions and 31 deletions

View file

@ -646,7 +646,7 @@ Goal::WorkResult DerivationGoal::inputsRealised(bool inBuildSlot)
return ContinueImmediately{};
}
Goal::WorkResult DerivationGoal::started()
void DerivationGoal::started()
{
auto msg = fmt(
buildMode == bmRepair ? "repairing outputs of '%s'" :
@ -657,7 +657,6 @@ Goal::WorkResult DerivationGoal::started()
act = std::make_unique<Activity>(*logger, lvlInfo, actBuild, msg,
Logger::Fields{worker.store.printStorePath(drvPath), hook ? machineName : "", 1, 1});
mcRunningBuilds = std::make_unique<MaintainCount<uint64_t>>(worker.runningBuilds);
return StillAlive{};
}
Goal::WorkResult DerivationGoal::tryToBuild(bool inBuildSlot)
@ -735,13 +734,14 @@ Goal::WorkResult DerivationGoal::tryToBuild(bool inBuildSlot)
auto hookReply = tryBuildHook(inBuildSlot);
auto result = std::visit(
overloaded{
[&](HookReply::Accept) -> std::optional<WorkResult> {
[&](HookReply::Accept & a) -> std::optional<WorkResult> {
/* Yes, it has started doing so. Wait until we get
EOF from the hook. */
actLock.reset();
buildResult.startTime = time(0); // inexact
state = &DerivationGoal::buildDone;
return started();
started();
return WaitForWorld{std::move(a.fds), false};
},
[&](HookReply::Postpone) -> std::optional<WorkResult> {
/* Not now; wait until at least one child finishes or
@ -1222,9 +1222,8 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
fds.insert(hook->fromHook.get());
fds.insert(hook->builderOut.get());
builderOutFD = &hook->builderOut;
worker.childStarted(shared_from_this(), fds, false);
return HookReply::Accept{};
return HookReply::Accept{std::move(fds)};
}

View file

@ -15,7 +15,9 @@ using std::map;
struct HookInstance;
struct HookReplyBase {
struct [[nodiscard]] Accept {};
struct [[nodiscard]] Accept {
std::set<int> fds;
};
struct [[nodiscard]] Decline {};
struct [[nodiscard]] Postpone {};
};
@ -345,7 +347,7 @@ struct DerivationGoal : public Goal
WorkResult repairClosure();
WorkResult started();
void started();
Finished done(
BuildResult::Status status,

View file

@ -75,10 +75,8 @@ Goal::WorkResult DrvOutputSubstitutionGoal::tryNext(bool inBuildSlot)
return sub->queryRealisation(id);
});
worker.childStarted(shared_from_this(), {downloadState->outPipe.readSide.get()}, true);
state = &DrvOutputSubstitutionGoal::realisationFetched;
return StillAlive{};
return WaitForWorld{{downloadState->outPipe.readSide.get()}, true};
}
Goal::WorkResult DrvOutputSubstitutionGoal::realisationFetched(bool inBuildSlot)

View file

@ -112,6 +112,10 @@ public:
struct [[nodiscard]] WaitForGoals {
Goals goals;
};
struct [[nodiscard]] WaitForWorld {
std::set<int> fds;
bool inBuildSlot;
};
struct [[nodiscard]] Finished {
ExitCode result;
std::unique_ptr<Error> ex;
@ -127,6 +131,7 @@ public:
WaitForAWhile,
ContinueImmediately,
WaitForGoals,
WaitForWorld,
Finished>
{
WorkResult() = delete;

View file

@ -230,7 +230,14 @@ Goal::WorkResult LocalDerivationGoal::tryLocalBuild(bool inBuildSlot)
try {
/* Okay, we have to build. */
startBuilder();
auto fds = startBuilder();
/* This state will be reached when we get EOF on the child's
log pipe. */
state = &DerivationGoal::buildDone;
started();
return WaitForWorld{std::move(fds), true};
} catch (BuildError & e) {
outputLocks.unlock();
@ -239,12 +246,6 @@ Goal::WorkResult LocalDerivationGoal::tryLocalBuild(bool inBuildSlot)
report.permanentFailure = true;
return report;
}
/* This state will be reached when we get EOF on the child's
log pipe. */
state = &DerivationGoal::buildDone;
return started();
}
@ -374,7 +375,7 @@ void LocalDerivationGoal::cleanupPostOutputsRegisteredModeNonCheck()
cleanupPostOutputsRegisteredModeCheck();
}
void LocalDerivationGoal::startBuilder()
std::set<int> LocalDerivationGoal::startBuilder()
{
if ((buildUser && buildUser->getUIDCount() != 1)
#if __linux__
@ -753,7 +754,7 @@ void LocalDerivationGoal::startBuilder()
msgs.push_back(std::move(msg));
}
worker.childStarted(shared_from_this(), {builderOutPTY.get()}, true);
return {builderOutPTY.get()};
}

View file

@ -216,7 +216,7 @@ struct LocalDerivationGoal : public DerivationGoal
/**
* Start building a derivation.
*/
void startBuilder();
std::set<int> startBuilder();
/**
* Fill in the environment for the builder.

View file

@ -221,10 +221,8 @@ Goal::WorkResult PathSubstitutionGoal::tryToRun(bool inBuildSlot)
}
});
worker.childStarted(shared_from_this(), {outPipe.readSide.get()}, true);
state = &PathSubstitutionGoal::finished;
return StillAlive{};
return WaitForWorld{{outPipe.readSide.get()}, true};
}

View file

@ -198,6 +198,7 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
dep->waiters.insert(goal);
}
},
[&](Goal::WaitForWorld & w) { childStarted(goal, w.fds, w.inBuildSlot); },
[&](Goal::Finished & f) { goalFinished(goal, f); },
},
how

View file

@ -157,6 +157,13 @@ private:
*/
void removeGoal(GoalPtr goal);
/**
* Registers a running child process. `inBuildSlot` means that
* the process counts towards the jobs limit.
*/
void childStarted(GoalPtr goal, const std::set<int> & fds,
bool inBuildSlot);
public:
const Activity act;
@ -228,13 +235,6 @@ public:
*/
GoalPtr makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal);
/**
* Registers a running child process. `inBuildSlot` means that
* the process counts towards the jobs limit.
*/
void childStarted(GoalPtr goal, const std::set<int> & fds,
bool inBuildSlot);
/**
* Unregisters a running child process.
*/