libstore: encapsulate worker build hook state
once goals run on multiple threads these fields must by synchronized as
one, or we try to run build hooks to often (or worse, not often enough)
Change-Id: I47860e46fe5c6db41755b2a3a1d9dbb5701c4ca4
This commit is contained in:
parent
868eb5ecde
commit
724b345eb9
|
@ -1127,21 +1127,21 @@ void DerivationGoal::resolvedFinished()
|
||||||
|
|
||||||
HookReply DerivationGoal::tryBuildHook()
|
HookReply DerivationGoal::tryBuildHook()
|
||||||
{
|
{
|
||||||
if (!worker.tryBuildHook || !useDerivation) return rpDecline;
|
if (!worker.hook.available || !useDerivation) return rpDecline;
|
||||||
|
|
||||||
if (!worker.hook)
|
if (!worker.hook.instance)
|
||||||
worker.hook = std::make_unique<HookInstance>();
|
worker.hook.instance = std::make_unique<HookInstance>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
/* Send the request to the hook. */
|
/* Send the request to the hook. */
|
||||||
worker.hook->sink
|
worker.hook.instance->sink
|
||||||
<< "try"
|
<< "try"
|
||||||
<< (worker.getNrLocalBuilds() < settings.maxBuildJobs ? 1 : 0)
|
<< (worker.getNrLocalBuilds() < settings.maxBuildJobs ? 1 : 0)
|
||||||
<< drv->platform
|
<< drv->platform
|
||||||
<< worker.store.printStorePath(drvPath)
|
<< worker.store.printStorePath(drvPath)
|
||||||
<< parsedDrv->getRequiredSystemFeatures();
|
<< parsedDrv->getRequiredSystemFeatures();
|
||||||
worker.hook->sink.flush();
|
worker.hook.instance->sink.flush();
|
||||||
|
|
||||||
/* Read the first line of input, which should be a word indicating
|
/* Read the first line of input, which should be a word indicating
|
||||||
whether the hook wishes to perform the build. */
|
whether the hook wishes to perform the build. */
|
||||||
|
@ -1149,13 +1149,13 @@ HookReply DerivationGoal::tryBuildHook()
|
||||||
while (true) {
|
while (true) {
|
||||||
auto s = [&]() {
|
auto s = [&]() {
|
||||||
try {
|
try {
|
||||||
return readLine(worker.hook->fromHook.readSide.get());
|
return readLine(worker.hook.instance->fromHook.readSide.get());
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace({}, "while reading the response from the build hook");
|
e.addTrace({}, "while reading the response from the build hook");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
if (handleJSONLogMessage(s, worker.act, worker.hook->activities, true))
|
if (handleJSONLogMessage(s, worker.act, worker.hook.instance->activities, true))
|
||||||
;
|
;
|
||||||
else if (s.substr(0, 2) == "# ") {
|
else if (s.substr(0, 2) == "# ") {
|
||||||
reply = s.substr(2);
|
reply = s.substr(2);
|
||||||
|
@ -1172,8 +1172,8 @@ HookReply DerivationGoal::tryBuildHook()
|
||||||
if (reply == "decline")
|
if (reply == "decline")
|
||||||
return rpDecline;
|
return rpDecline;
|
||||||
else if (reply == "decline-permanently") {
|
else if (reply == "decline-permanently") {
|
||||||
worker.tryBuildHook = false;
|
worker.hook.available = false;
|
||||||
worker.hook = 0;
|
worker.hook.instance.reset();
|
||||||
return rpDecline;
|
return rpDecline;
|
||||||
}
|
}
|
||||||
else if (reply == "postpone")
|
else if (reply == "postpone")
|
||||||
|
@ -1185,14 +1185,14 @@ HookReply DerivationGoal::tryBuildHook()
|
||||||
if (e.errNo == EPIPE) {
|
if (e.errNo == EPIPE) {
|
||||||
printError(
|
printError(
|
||||||
"build hook died unexpectedly: %s",
|
"build hook died unexpectedly: %s",
|
||||||
chomp(drainFD(worker.hook->fromHook.readSide.get())));
|
chomp(drainFD(worker.hook.instance->fromHook.readSide.get())));
|
||||||
worker.hook = 0;
|
worker.hook.instance.reset();
|
||||||
return rpDecline;
|
return rpDecline;
|
||||||
} else
|
} else
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
hook = std::move(worker.hook);
|
hook = std::move(worker.hook.instance);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
machineName = readLine(hook->fromHook.readSide.get());
|
machineName = readLine(hook->fromHook.readSide.get());
|
||||||
|
|
|
@ -135,7 +135,17 @@ public:
|
||||||
Store & store;
|
Store & store;
|
||||||
Store & evalStore;
|
Store & evalStore;
|
||||||
|
|
||||||
std::unique_ptr<HookInstance> hook;
|
struct HookState {
|
||||||
|
std::unique_ptr<HookInstance> instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to ask the build hook if it can build a derivation. If
|
||||||
|
* it answers with "decline-permanently", we don't try again.
|
||||||
|
*/
|
||||||
|
bool available = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
HookState hook;
|
||||||
|
|
||||||
uint64_t expectedBuilds = 0;
|
uint64_t expectedBuilds = 0;
|
||||||
uint64_t doneBuilds = 0;
|
uint64_t doneBuilds = 0;
|
||||||
|
@ -151,12 +161,6 @@ public:
|
||||||
uint64_t expectedNarSize = 0;
|
uint64_t expectedNarSize = 0;
|
||||||
uint64_t doneNarSize = 0;
|
uint64_t doneNarSize = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to ask the build hook if it can build a derivation. If
|
|
||||||
* it answers with "decline-permanently", we don't try again.
|
|
||||||
*/
|
|
||||||
bool tryBuildHook = true;
|
|
||||||
|
|
||||||
Worker(Store & store, Store & evalStore);
|
Worker(Store & store, Store & evalStore);
|
||||||
~Worker();
|
~Worker();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue