forked from lix-project/lix
Fix tests on systems with a non-master git defaultBranch #1
|
@ -134,9 +134,9 @@ Goal::Finished DerivationGoal::timedOut(Error && ex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
kj::Promise<Result<Goal::WorkResult>> DerivationGoal::work(bool inBuildSlot) noexcept
|
kj::Promise<Result<Goal::WorkResult>> DerivationGoal::work() noexcept
|
||||||
{
|
{
|
||||||
return (this->*state)(inBuildSlot);
|
return (this->*state)(slotToken.valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
|
void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
|
||||||
|
@ -783,7 +783,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), false}}};
|
return {{WaitForWorld{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
|
||||||
|
@ -980,6 +980,7 @@ kj::Promise<Result<Goal::WorkResult>> DerivationGoal::buildDone(bool inBuildSlot
|
||||||
try {
|
try {
|
||||||
trace("build done");
|
trace("build done");
|
||||||
|
|
||||||
|
slotToken = {};
|
||||||
Finally releaseBuildUser([&](){ this->cleanupHookFinally(); });
|
Finally releaseBuildUser([&](){ this->cleanupHookFinally(); });
|
||||||
|
|
||||||
cleanupPreChildKill();
|
cleanupPreChildKill();
|
||||||
|
|
|
@ -249,7 +249,7 @@ struct DerivationGoal : public Goal
|
||||||
|
|
||||||
std::string key() override;
|
std::string key() override;
|
||||||
|
|
||||||
kj::Promise<Result<WorkResult>> work(bool inBuildSlot) noexcept override;
|
kj::Promise<Result<WorkResult>> work() noexcept override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add wanted outputs to an already existing derivation goal.
|
* Add wanted outputs to an already existing derivation goal.
|
||||||
|
|
|
@ -42,7 +42,10 @@ try {
|
||||||
trace("trying next substituter");
|
trace("trying next substituter");
|
||||||
|
|
||||||
if (!inBuildSlot) {
|
if (!inBuildSlot) {
|
||||||
return {WaitForSlot{}};
|
return worker.substitutions.acquire().then([this](auto token) {
|
||||||
|
slotToken = std::move(token);
|
||||||
|
return work();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
maintainRunningSubstitutions = worker.runningSubstitutions.addTemporarily(1);
|
maintainRunningSubstitutions = worker.runningSubstitutions.addTemporarily(1);
|
||||||
|
@ -81,7 +84,7 @@ try {
|
||||||
|
|
||||||
state = &DrvOutputSubstitutionGoal::realisationFetched;
|
state = &DrvOutputSubstitutionGoal::realisationFetched;
|
||||||
return {WaitForWorld{
|
return {WaitForWorld{
|
||||||
pipe.promise.then([]() -> Outcome<void, Finished> { return result::success(); }), true
|
pipe.promise.then([]() -> Outcome<void, Finished> { return result::success(); })
|
||||||
}};
|
}};
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return {std::current_exception()};
|
return {std::current_exception()};
|
||||||
|
@ -90,6 +93,7 @@ try {
|
||||||
kj::Promise<Result<Goal::WorkResult>> DrvOutputSubstitutionGoal::realisationFetched(bool inBuildSlot) noexcept
|
kj::Promise<Result<Goal::WorkResult>> DrvOutputSubstitutionGoal::realisationFetched(bool inBuildSlot) noexcept
|
||||||
try {
|
try {
|
||||||
maintainRunningSubstitutions.reset();
|
maintainRunningSubstitutions.reset();
|
||||||
|
slotToken = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
outputInfo = downloadState->result.get();
|
outputInfo = downloadState->result.get();
|
||||||
|
@ -168,9 +172,9 @@ std::string DrvOutputSubstitutionGoal::key()
|
||||||
return "a$" + std::string(id.to_string());
|
return "a$" + std::string(id.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
kj::Promise<Result<Goal::WorkResult>> DrvOutputSubstitutionGoal::work(bool inBuildSlot) noexcept
|
kj::Promise<Result<Goal::WorkResult>> DrvOutputSubstitutionGoal::work() noexcept
|
||||||
{
|
{
|
||||||
return (this->*state)(inBuildSlot);
|
return (this->*state)(slotToken.valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
|
|
||||||
std::string key() override;
|
std::string key() override;
|
||||||
|
|
||||||
kj::Promise<Result<WorkResult>> work(bool inBuildSlot) noexcept override;
|
kj::Promise<Result<WorkResult>> work() noexcept override;
|
||||||
|
|
||||||
JobCategory jobCategory() const override {
|
JobCategory jobCategory() const override {
|
||||||
return JobCategory::Substitution;
|
return JobCategory::Substitution;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
|
#include "async-semaphore.hh"
|
||||||
#include "result.hh"
|
#include "result.hh"
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
@ -112,19 +113,20 @@ struct Goal
|
||||||
*/
|
*/
|
||||||
BuildResult buildResult;
|
BuildResult buildResult;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AsyncSemaphore::Token slotToken;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Finished;
|
struct Finished;
|
||||||
|
|
||||||
struct [[nodiscard]] StillAlive {};
|
struct [[nodiscard]] StillAlive {};
|
||||||
struct [[nodiscard]] WaitForSlot {};
|
|
||||||
struct [[nodiscard]] ContinueImmediately {};
|
struct [[nodiscard]] ContinueImmediately {};
|
||||||
struct [[nodiscard]] WaitForGoals {
|
struct [[nodiscard]] WaitForGoals {
|
||||||
Goals goals;
|
Goals goals;
|
||||||
};
|
};
|
||||||
struct [[nodiscard]] WaitForWorld {
|
struct [[nodiscard]] WaitForWorld {
|
||||||
kj::Promise<Outcome<void, Finished>> promise;
|
kj::Promise<Outcome<void, Finished>> promise;
|
||||||
bool inBuildSlot;
|
|
||||||
};
|
};
|
||||||
struct [[nodiscard]] Finished {
|
struct [[nodiscard]] Finished {
|
||||||
ExitCode exitCode;
|
ExitCode exitCode;
|
||||||
|
@ -138,7 +140,6 @@ public:
|
||||||
|
|
||||||
struct [[nodiscard]] WorkResult : std::variant<
|
struct [[nodiscard]] WorkResult : std::variant<
|
||||||
StillAlive,
|
StillAlive,
|
||||||
WaitForSlot,
|
|
||||||
ContinueImmediately,
|
ContinueImmediately,
|
||||||
WaitForGoals,
|
WaitForGoals,
|
||||||
WaitForWorld,
|
WaitForWorld,
|
||||||
|
@ -168,7 +169,7 @@ public:
|
||||||
trace("goal destroyed");
|
trace("goal destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual kj::Promise<Result<WorkResult>> work(bool inBuildSlot) noexcept = 0;
|
virtual kj::Promise<Result<WorkResult>> work() noexcept = 0;
|
||||||
|
|
||||||
virtual void waiteeDone(GoalPtr waitee) { }
|
virtual void waiteeDone(GoalPtr waitee) { }
|
||||||
|
|
||||||
|
|
|
@ -156,8 +156,11 @@ try {
|
||||||
if (!inBuildSlot) {
|
if (!inBuildSlot) {
|
||||||
state = &DerivationGoal::tryToBuild;
|
state = &DerivationGoal::tryToBuild;
|
||||||
outputLocks.unlock();
|
outputLocks.unlock();
|
||||||
if (0U != settings.maxBuildJobs) {
|
if (worker.localBuilds.capacity() > 0) {
|
||||||
return {WaitForSlot{}};
|
return worker.localBuilds.acquire().then([this](auto token) {
|
||||||
|
slotToken = std::move(token);
|
||||||
|
return work();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (getMachines().empty()) {
|
if (getMachines().empty()) {
|
||||||
throw Error(
|
throw Error(
|
||||||
|
@ -248,7 +251,7 @@ try {
|
||||||
state = &DerivationGoal::buildDone;
|
state = &DerivationGoal::buildDone;
|
||||||
|
|
||||||
started();
|
started();
|
||||||
return {WaitForWorld{std::move(promise), true}};
|
return {WaitForWorld{std::move(promise)}};
|
||||||
|
|
||||||
} catch (BuildError & e) {
|
} catch (BuildError & e) {
|
||||||
outputLocks.unlock();
|
outputLocks.unlock();
|
||||||
|
|
|
@ -45,9 +45,9 @@ Goal::Finished PathSubstitutionGoal::done(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
kj::Promise<Result<Goal::WorkResult>> PathSubstitutionGoal::work(bool inBuildSlot) noexcept
|
kj::Promise<Result<Goal::WorkResult>> PathSubstitutionGoal::work() noexcept
|
||||||
{
|
{
|
||||||
return (this->*state)(inBuildSlot);
|
return (this->*state)(slotToken.valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,7 +203,10 @@ try {
|
||||||
trace("trying to run");
|
trace("trying to run");
|
||||||
|
|
||||||
if (!inBuildSlot) {
|
if (!inBuildSlot) {
|
||||||
return {WaitForSlot{}};
|
return worker.substitutions.acquire().then([this](auto token) {
|
||||||
|
slotToken = std::move(token);
|
||||||
|
return work();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
maintainRunningSubstitutions = worker.runningSubstitutions.addTemporarily(1);
|
maintainRunningSubstitutions = worker.runningSubstitutions.addTemporarily(1);
|
||||||
|
@ -236,7 +239,7 @@ try {
|
||||||
|
|
||||||
state = &PathSubstitutionGoal::finished;
|
state = &PathSubstitutionGoal::finished;
|
||||||
return {WaitForWorld{
|
return {WaitForWorld{
|
||||||
pipe.promise.then([]() -> Outcome<void, Finished> { return result::success(); }), true
|
pipe.promise.then([]() -> Outcome<void, Finished> { return result::success(); })
|
||||||
}};
|
}};
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return {std::current_exception()};
|
return {std::current_exception()};
|
||||||
|
@ -248,6 +251,7 @@ try {
|
||||||
trace("substitute finished");
|
trace("substitute finished");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
slotToken = {};
|
||||||
thr.get();
|
thr.get();
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
printError(e.what());
|
printError(e.what());
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
return "a$" + std::string(storePath.name()) + "$" + worker.store.printStorePath(storePath);
|
return "a$" + std::string(storePath.name()) + "$" + worker.store.printStorePath(storePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
kj::Promise<Result<WorkResult>> work(bool inBuildSlot) noexcept override;
|
kj::Promise<Result<WorkResult>> work() noexcept override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The states.
|
* The states.
|
||||||
|
|
|
@ -27,11 +27,13 @@ Worker::Worker(Store & store, Store & evalStore, kj::AsyncIoContext & aio)
|
||||||
, store(store)
|
, store(store)
|
||||||
, evalStore(evalStore)
|
, evalStore(evalStore)
|
||||||
, aio(aio)
|
, aio(aio)
|
||||||
|
/* Make sure that we are always allowed to run at least one substitution.
|
||||||
|
This prevents infinite waiting. */
|
||||||
|
, substitutions(std::max<unsigned>(1, settings.maxSubstitutionJobs))
|
||||||
|
, localBuilds(settings.maxBuildJobs)
|
||||||
, children(errorHandler)
|
, children(errorHandler)
|
||||||
{
|
{
|
||||||
/* Debugging: prevent recursive workers. */
|
/* Debugging: prevent recursive workers. */
|
||||||
nrLocalBuilds = 0;
|
|
||||||
nrSubstitutions = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,7 +212,6 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
|
||||||
std::visit(
|
std::visit(
|
||||||
overloaded{
|
overloaded{
|
||||||
[&](Goal::StillAlive) {},
|
[&](Goal::StillAlive) {},
|
||||||
[&](Goal::WaitForSlot) { waitForBuildSlot(goal); },
|
|
||||||
[&](Goal::ContinueImmediately) { wakeUp(goal); },
|
[&](Goal::ContinueImmediately) { wakeUp(goal); },
|
||||||
[&](Goal::WaitForGoals & w) {
|
[&](Goal::WaitForGoals & w) {
|
||||||
for (auto & dep : w.goals) {
|
for (auto & dep : w.goals) {
|
||||||
|
@ -219,19 +220,15 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](Goal::WaitForWorld & w) {
|
[&](Goal::WaitForWorld & w) {
|
||||||
childStarted(
|
childStarted(goal, w.promise.then([](auto r) -> Result<Goal::WorkResult> {
|
||||||
goal,
|
if (r.has_value()) {
|
||||||
w.promise.then([](auto r) -> Result<Goal::WorkResult> {
|
return {Goal::ContinueImmediately{}};
|
||||||
if (r.has_value()) {
|
} else if (r.has_error()) {
|
||||||
return {Goal::ContinueImmediately{}};
|
return {std::move(r).error()};
|
||||||
} else if (r.has_error()) {
|
} else {
|
||||||
return {std::move(r).error()};
|
return r.exception();
|
||||||
} else {
|
}
|
||||||
return r.exception();
|
}));
|
||||||
}
|
|
||||||
}),
|
|
||||||
w.inBuildSlot
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
[&](Goal::Finished & f) { goalFinished(goal, f); },
|
[&](Goal::Finished & f) { goalFinished(goal, f); },
|
||||||
},
|
},
|
||||||
|
@ -268,8 +265,7 @@ void Worker::wakeUp(GoalPtr goal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> promise,
|
void Worker::childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> promise)
|
||||||
bool inBuildSlot)
|
|
||||||
{
|
{
|
||||||
children.add(promise
|
children.add(promise
|
||||||
.then([this, goal](auto result) {
|
.then([this, goal](auto result) {
|
||||||
|
@ -279,64 +275,17 @@ void Worker::childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> pr
|
||||||
childException = result.assume_error();
|
childException = result.assume_error();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.attach(Finally{[this, goal, inBuildSlot] {
|
.attach(Finally{[this, goal] {
|
||||||
childTerminated(goal, inBuildSlot);
|
childTerminated(goal);
|
||||||
}}));
|
}}));
|
||||||
if (inBuildSlot) {
|
|
||||||
switch (goal->jobCategory()) {
|
|
||||||
case JobCategory::Substitution:
|
|
||||||
nrSubstitutions++;
|
|
||||||
break;
|
|
||||||
case JobCategory::Build:
|
|
||||||
nrLocalBuilds++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::childTerminated(GoalPtr goal, bool inBuildSlot)
|
void Worker::childTerminated(GoalPtr goal)
|
||||||
{
|
{
|
||||||
if (childFinished) {
|
if (childFinished) {
|
||||||
childFinished->fulfill();
|
childFinished->fulfill();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inBuildSlot) {
|
|
||||||
switch (goal->jobCategory()) {
|
|
||||||
case JobCategory::Substitution:
|
|
||||||
assert(nrSubstitutions > 0);
|
|
||||||
nrSubstitutions--;
|
|
||||||
break;
|
|
||||||
case JobCategory::Build:
|
|
||||||
assert(nrLocalBuilds > 0);
|
|
||||||
nrLocalBuilds--;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wake up goals waiting for a build slot. */
|
|
||||||
for (auto & j : wantingToBuild) {
|
|
||||||
GoalPtr goal = j.lock();
|
|
||||||
if (goal) wakeUp(goal);
|
|
||||||
}
|
|
||||||
|
|
||||||
wantingToBuild.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Worker::waitForBuildSlot(GoalPtr goal)
|
|
||||||
{
|
|
||||||
goal->trace("wait for build slot");
|
|
||||||
bool isSubstitutionGoal = goal->jobCategory() == JobCategory::Substitution;
|
|
||||||
if ((!isSubstitutionGoal && nrLocalBuilds < settings.maxBuildJobs) ||
|
|
||||||
(isSubstitutionGoal && nrSubstitutions < settings.maxSubstitutionJobs))
|
|
||||||
wakeUp(goal); /* we can do it right away */
|
|
||||||
else
|
|
||||||
wantingToBuild.insert(goal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,16 +343,11 @@ Goals Worker::run(std::function<Goals (GoalFactory &)> req)
|
||||||
awake.clear();
|
awake.clear();
|
||||||
for (auto & goal : awake2) {
|
for (auto & goal : awake2) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
/* Make sure that we are always allowed to run at least one substitution.
|
auto result = goal->work();
|
||||||
This prevents infinite waiting. */
|
|
||||||
const bool inSlot = goal->jobCategory() == JobCategory::Substitution
|
|
||||||
? nrSubstitutions < std::max(1U, (unsigned int) settings.maxSubstitutionJobs)
|
|
||||||
: nrLocalBuilds < settings.maxBuildJobs;
|
|
||||||
auto result = goal->work(inSlot);
|
|
||||||
if (result.poll(aio.waitScope)) {
|
if (result.poll(aio.waitScope)) {
|
||||||
handleWorkResult(goal, result.wait(aio.waitScope).value());
|
handleWorkResult(goal, result.wait(aio.waitScope).value());
|
||||||
} else {
|
} else {
|
||||||
childStarted(goal, std::move(result), false);
|
childStarted(goal, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topGoals.empty()) break; // stuff may have been cancelled
|
if (topGoals.empty()) break; // stuff may have been cancelled
|
||||||
|
@ -428,7 +372,6 @@ Goals Worker::run(std::function<Goals (GoalFactory &)> req)
|
||||||
exited while some of its subgoals were still active. But if
|
exited while some of its subgoals were still active. But if
|
||||||
--keep-going *is* set, then they must all be finished now. */
|
--keep-going *is* set, then they must all be finished now. */
|
||||||
assert(!settings.keepGoing || awake.empty());
|
assert(!settings.keepGoing || awake.empty());
|
||||||
assert(!settings.keepGoing || wantingToBuild.empty());
|
|
||||||
assert(!settings.keepGoing || children.isEmpty());
|
assert(!settings.keepGoing || children.isEmpty());
|
||||||
|
|
||||||
return _topGoals;
|
return _topGoals;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
|
#include "async-semaphore.hh"
|
||||||
#include "notifying-counter.hh"
|
#include "notifying-counter.hh"
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "lock.hh"
|
#include "lock.hh"
|
||||||
|
@ -93,22 +94,6 @@ private:
|
||||||
*/
|
*/
|
||||||
WeakGoals awake;
|
WeakGoals awake;
|
||||||
|
|
||||||
/**
|
|
||||||
* Goals waiting for a build slot.
|
|
||||||
*/
|
|
||||||
WeakGoals wantingToBuild;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of build slots occupied. This includes local builds but does not
|
|
||||||
* include substitutions or remote builds via the build hook.
|
|
||||||
*/
|
|
||||||
unsigned int nrLocalBuilds;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of substitution slots occupied.
|
|
||||||
*/
|
|
||||||
unsigned int nrSubstitutions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps used to prevent multiple instantiations of a goal for the
|
* Maps used to prevent multiple instantiations of a goal for the
|
||||||
* same derivation / path.
|
* same derivation / path.
|
||||||
|
@ -148,12 +133,6 @@ private:
|
||||||
|
|
||||||
kj::Own<kj::PromiseFulfiller<void>> childFinished;
|
kj::Own<kj::PromiseFulfiller<void>> childFinished;
|
||||||
|
|
||||||
/**
|
|
||||||
* Put `goal` to sleep until a build slot becomes available (which
|
|
||||||
* might be right away).
|
|
||||||
*/
|
|
||||||
void waitForBuildSlot(GoalPtr goal);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wake up a goal (i.e., there is something for it to do).
|
* Wake up a goal (i.e., there is something for it to do).
|
||||||
*/
|
*/
|
||||||
|
@ -170,16 +149,14 @@ private:
|
||||||
void removeGoal(GoalPtr goal);
|
void removeGoal(GoalPtr goal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a running child process. `inBuildSlot` means that
|
* Registers a running child process.
|
||||||
* the process counts towards the jobs limit.
|
|
||||||
*/
|
*/
|
||||||
void childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> promise,
|
void childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> promise);
|
||||||
bool inBuildSlot);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters a running child process.
|
* Unregisters a running child process.
|
||||||
*/
|
*/
|
||||||
void childTerminated(GoalPtr goal, bool inBuildSlot);
|
void childTerminated(GoalPtr goal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass current stats counters to the logger for progress bar updates.
|
* Pass current stats counters to the logger for progress bar updates.
|
||||||
|
@ -205,6 +182,7 @@ public:
|
||||||
Store & store;
|
Store & store;
|
||||||
Store & evalStore;
|
Store & evalStore;
|
||||||
kj::AsyncIoContext & aio;
|
kj::AsyncIoContext & aio;
|
||||||
|
AsyncSemaphore substitutions, localBuilds;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
kj::TaskSet children;
|
kj::TaskSet children;
|
||||||
|
|
Loading…
Reference in a new issue