libstore: turn HookReply into a variant type

we'll need this once we want to pass extra information out of accepting
replies, such as fd sets or possibly even async output reader promises.

Change-Id: I5e2f18cdb80b0d2faf3067703cc18bd263329b3f
This commit is contained in:
eldritch horrors 2024-08-14 11:55:58 +02:00
parent 5e9db09761
commit fca523d661
2 changed files with 47 additions and 26 deletions

View file

@ -732,25 +732,34 @@ Goal::WorkResult DerivationGoal::tryToBuild(bool inBuildSlot)
&& settings.maxBuildJobs.get() != 0; && settings.maxBuildJobs.get() != 0;
if (!buildLocally) { if (!buildLocally) {
switch (tryBuildHook(inBuildSlot)) { auto hookReply = tryBuildHook(inBuildSlot);
case rpAccept: auto result = std::visit(
/* Yes, it has started doing so. Wait until we get overloaded{
EOF from the hook. */ [&](HookReply::Accept) -> std::optional<WorkResult> {
actLock.reset(); /* Yes, it has started doing so. Wait until we get
buildResult.startTime = time(0); // inexact EOF from the hook. */
state = &DerivationGoal::buildDone; actLock.reset();
return started(); buildResult.startTime = time(0); // inexact
case rpPostpone: state = &DerivationGoal::buildDone;
/* Not now; wait until at least one child finishes or return started();
the wake-up timeout expires. */ },
if (!actLock) [&](HookReply::Postpone) -> std::optional<WorkResult> {
actLock = std::make_unique<Activity>(*logger, lvlTalkative, actBuildWaiting, /* Not now; wait until at least one child finishes or
fmt("waiting for a machine to build '%s'", Magenta(worker.store.printStorePath(drvPath)))); the wake-up timeout expires. */
outputLocks.unlock(); if (!actLock)
return WaitForAWhile{}; actLock = std::make_unique<Activity>(*logger, lvlTalkative, actBuildWaiting,
case rpDecline: fmt("waiting for a machine to build '%s'", Magenta(worker.store.printStorePath(drvPath))));
/* We should do it ourselves. */ outputLocks.unlock();
break; return WaitForAWhile{};
},
[&](HookReply::Decline) -> std::optional<WorkResult> {
/* We should do it ourselves. */
return std::nullopt;
},
},
hookReply);
if (result) {
return std::move(*result);
} }
} }
@ -1113,7 +1122,7 @@ Goal::WorkResult DerivationGoal::resolvedFinished(bool inBuildSlot)
HookReply DerivationGoal::tryBuildHook(bool inBuildSlot) HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
{ {
if (!worker.hook.available || !useDerivation) return rpDecline; if (!worker.hook.available || !useDerivation) return HookReply::Decline{};
if (!worker.hook.instance) if (!worker.hook.instance)
worker.hook.instance = std::make_unique<HookInstance>(); worker.hook.instance = std::make_unique<HookInstance>();
@ -1156,14 +1165,14 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
debug("hook reply is '%1%'", reply); debug("hook reply is '%1%'", reply);
if (reply == "decline") if (reply == "decline")
return rpDecline; return HookReply::Decline{};
else if (reply == "decline-permanently") { else if (reply == "decline-permanently") {
worker.hook.available = false; worker.hook.available = false;
worker.hook.instance.reset(); worker.hook.instance.reset();
return rpDecline; return HookReply::Decline{};
} }
else if (reply == "postpone") else if (reply == "postpone")
return rpPostpone; return HookReply::Postpone{};
else if (reply != "accept") else if (reply != "accept")
throw Error("bad hook reply '%s'", reply); throw Error("bad hook reply '%s'", reply);
@ -1173,7 +1182,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
"build hook died unexpectedly: %s", "build hook died unexpectedly: %s",
chomp(drainFD(worker.hook.instance->fromHook.get()))); chomp(drainFD(worker.hook.instance->fromHook.get())));
worker.hook.instance.reset(); worker.hook.instance.reset();
return rpDecline; return HookReply::Decline{};
} else } else
throw; throw;
} }
@ -1215,7 +1224,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
builderOutFD = &hook->builderOut; builderOutFD = &hook->builderOut;
worker.childStarted(shared_from_this(), fds, false); worker.childStarted(shared_from_this(), fds, false);
return rpAccept; return HookReply::Accept{};
} }

View file

@ -14,7 +14,19 @@ using std::map;
struct HookInstance; struct HookInstance;
typedef enum {rpAccept, rpDecline, rpPostpone} HookReply; struct HookReplyBase {
struct [[nodiscard]] Accept {};
struct [[nodiscard]] Decline {};
struct [[nodiscard]] Postpone {};
};
struct [[nodiscard]] HookReply
: HookReplyBase,
std::variant<HookReplyBase::Accept, HookReplyBase::Decline, HookReplyBase::Postpone>
{
HookReply() = delete;
using variant::variant;
};
/** /**
* Unless we are repairing, we don't both to test validity and just assume it, * Unless we are repairing, we don't both to test validity and just assume it,