libstore: remove Goal::WaitForWorld

have DerivationGoal and its subclasses produce a wrapper promise for
their intermediate results instead, and return this wrapper promise.
Worker already handles promises that do not complete immediately, so
we do not have to duplicate this into an entire result type variant.

Change-Id: Iae8dbf63cfc742afda4d415922a29ac5a3f39348
This commit is contained in:
eldritch horrors 2024-09-24 00:21:16 +02:00
parent 1a52e4f755
commit 8fb642b6e0
7 changed files with 19 additions and 23 deletions

View file

@ -787,7 +787,7 @@ try {
buildResult.startTime = time(0); // inexact
state = &DerivationGoal::buildDone;
started();
return {{WaitForWorld{std::move(a.promise)}}};
return continueOrError(std::move(a.promise));
},
[&](HookReply::Postpone) -> std::optional<kj::Promise<Result<WorkResult>>> {
/* Not now; wait until at least one child finishes or
@ -1756,4 +1756,17 @@ void DerivationGoal::waiteeDone(GoalPtr waitee)
}
}
kj::Promise<Result<Goal::WorkResult>>
DerivationGoal::continueOrError(kj::Promise<Outcome<void, Goal::Finished>> p)
{
return p.then([](auto r) -> Result<WorkResult> {
if (r.has_value()) {
return ContinueImmediately{};
} else if (r.has_error()) {
return r.assume_error();
} else {
return r.assume_exception();
}
});
}
}

View file

@ -327,6 +327,8 @@ protected:
Finished tooMuchLogs();
void flushLine();
static kj::Promise<Result<WorkResult>> continueOrError(kj::Promise<Outcome<void, Goal::Finished>> p);
public:
/**
* Wrappers around the corresponding Store methods that first consult the

View file

@ -86,9 +86,7 @@ try {
});
state = &DrvOutputSubstitutionGoal::realisationFetched;
return {WaitForWorld{
pipe.promise.then([]() -> Outcome<void, Finished> { return result::success(); })
}};
return pipe.promise.then([]() -> Result<WorkResult> { return ContinueImmediately{}; });
} catch (...) {
return {std::current_exception()};
}

View file

@ -115,9 +115,6 @@ public:
struct [[nodiscard]] StillAlive {};
struct [[nodiscard]] ContinueImmediately {};
struct [[nodiscard]] WaitForWorld {
kj::Promise<Outcome<void, Finished>> promise;
};
struct [[nodiscard]] Finished {
ExitCode exitCode;
BuildResult result;
@ -131,7 +128,6 @@ public:
struct [[nodiscard]] WorkResult : std::variant<
StillAlive,
ContinueImmediately,
WaitForWorld,
Finished>
{
WorkResult() = delete;

View file

@ -251,7 +251,7 @@ try {
state = &DerivationGoal::buildDone;
started();
return {WaitForWorld{std::move(promise)}};
return continueOrError(std::move(promise));
} catch (BuildError & e) {
outputLocks.unlock();

View file

@ -240,9 +240,7 @@ try {
});
state = &PathSubstitutionGoal::finished;
return {WaitForWorld{
pipe.promise.then([]() -> Outcome<void, Finished> { return result::success(); })
}};
return pipe.promise.then([]() -> Result<WorkResult> { return ContinueImmediately{}; });
} catch (...) {
return {std::current_exception()};
}

View file

@ -202,17 +202,6 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
overloaded{
[&](Goal::StillAlive) {},
[&](Goal::ContinueImmediately) { wakeUp(goal); },
[&](Goal::WaitForWorld & w) {
childStarted(goal, w.promise.then([](auto r) -> Result<Goal::WorkResult> {
if (r.has_value()) {
return {Goal::ContinueImmediately{}};
} else if (r.has_error()) {
return {std::move(r).error()};
} else {
return r.exception();
}
}));
},
[&](Goal::Finished & f) { goalFinished(goal, f); },
},
how