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 buildResult.startTime = time(0); // inexact
state = &DerivationGoal::buildDone; state = &DerivationGoal::buildDone;
started(); started();
return {{WaitForWorld{std::move(a.promise)}}}; return continueOrError(std::move(a.promise));
}, },
[&](HookReply::Postpone) -> std::optional<kj::Promise<Result<WorkResult>>> { [&](HookReply::Postpone) -> std::optional<kj::Promise<Result<WorkResult>>> {
/* Not now; wait until at least one child finishes or /* 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(); Finished tooMuchLogs();
void flushLine(); void flushLine();
static kj::Promise<Result<WorkResult>> continueOrError(kj::Promise<Outcome<void, Goal::Finished>> p);
public: public:
/** /**
* Wrappers around the corresponding Store methods that first consult the * Wrappers around the corresponding Store methods that first consult the

View file

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

View file

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

View file

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

View file

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

View file

@ -202,17 +202,6 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
overloaded{ overloaded{
[&](Goal::StillAlive) {}, [&](Goal::StillAlive) {},
[&](Goal::ContinueImmediately) { wakeUp(goal); }, [&](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); }, [&](Goal::Finished & f) { goalFinished(goal, f); },
}, },
how how