libstore: have goals promise WorkResults, not void
Change-Id: Idd218ec1572eda84dc47accc0dcd8a954d36f098
This commit is contained in:
parent
a9f2aab226
commit
7ef4466018
|
@ -267,7 +267,7 @@ try {
|
||||||
/* We are first going to try to create the invalid output paths
|
/* We are first going to try to create the invalid output paths
|
||||||
through substitutes. If that doesn't work, we'll build
|
through substitutes. If that doesn't work, we'll build
|
||||||
them. */
|
them. */
|
||||||
kj::Vector<std::pair<GoalPtr, kj::Promise<void>>> dependencies;
|
kj::Vector<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies;
|
||||||
if (settings.useSubstitutes) {
|
if (settings.useSubstitutes) {
|
||||||
if (parsedDrv->substitutesAllowed()) {
|
if (parsedDrv->substitutesAllowed()) {
|
||||||
for (auto & [outputName, status] : initialOutputs) {
|
for (auto & [outputName, status] : initialOutputs) {
|
||||||
|
@ -376,7 +376,7 @@ try {
|
||||||
produced using a substitute. So we have to build instead. */
|
produced using a substitute. So we have to build instead. */
|
||||||
kj::Promise<Result<Goal::WorkResult>> DerivationGoal::gaveUpOnSubstitution() noexcept
|
kj::Promise<Result<Goal::WorkResult>> DerivationGoal::gaveUpOnSubstitution() noexcept
|
||||||
try {
|
try {
|
||||||
kj::Vector<std::pair<GoalPtr, kj::Promise<void>>> dependencies;
|
kj::Vector<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies;
|
||||||
|
|
||||||
/* At this point we are building all outputs, so if more are wanted there
|
/* At this point we are building all outputs, so if more are wanted there
|
||||||
is no need to restart. */
|
is no need to restart. */
|
||||||
|
@ -482,7 +482,7 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check each path (slow!). */
|
/* Check each path (slow!). */
|
||||||
kj::Vector<std::pair<GoalPtr, kj::Promise<void>>> dependencies;
|
kj::Vector<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies;
|
||||||
for (auto & i : outputClosure) {
|
for (auto & i : outputClosure) {
|
||||||
if (worker.pathContentsGood(i)) continue;
|
if (worker.pathContentsGood(i)) continue;
|
||||||
printError(
|
printError(
|
||||||
|
|
|
@ -103,7 +103,7 @@ try {
|
||||||
co_return co_await tryNext();
|
co_return co_await tryNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
kj::Vector<std::pair<GoalPtr, kj::Promise<void>>> dependencies;
|
kj::Vector<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies;
|
||||||
for (const auto & [depId, depPath] : outputInfo->dependentRealisations) {
|
for (const auto & [depId, depPath] : outputInfo->dependentRealisations) {
|
||||||
if (depId != id) {
|
if (depId != id) {
|
||||||
if (auto localOutputInfo = worker.store.queryRealisation(depId);
|
if (auto localOutputInfo = worker.store.queryRealisation(depId);
|
||||||
|
|
|
@ -29,7 +29,7 @@ try {
|
||||||
exitCode = result.exitCode;
|
exitCode = result.exitCode;
|
||||||
ex = result.ex;
|
ex = result.ex;
|
||||||
|
|
||||||
notify->fulfill();
|
notify->fulfill(result);
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
co_return std::move(result);
|
co_return std::move(result);
|
||||||
|
@ -38,24 +38,25 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
kj::Promise<Result<void>>
|
kj::Promise<Result<void>>
|
||||||
Goal::waitForGoals(kj::Array<std::pair<GoalPtr, kj::Promise<void>>> dependencies) noexcept
|
Goal::waitForGoals(kj::Array<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies) noexcept
|
||||||
try {
|
try {
|
||||||
auto left = dependencies.size();
|
auto left = dependencies.size();
|
||||||
for (auto & [dep, p] : dependencies) {
|
for (auto & [dep, p] : dependencies) {
|
||||||
p = p.then([this, dep, &left] {
|
p = p.then([this, dep, &left](auto _result) {
|
||||||
left--;
|
left--;
|
||||||
trace(fmt("waitee '%s' done; %d left", dep->name, left));
|
trace(fmt("waitee '%s' done; %d left", dep->name, left));
|
||||||
|
|
||||||
if (dep->exitCode != Goal::ecSuccess) ++nrFailed;
|
if (dep->exitCode != Goal::ecSuccess) ++nrFailed;
|
||||||
if (dep->exitCode == Goal::ecNoSubstituters) ++nrNoSubstituters;
|
if (dep->exitCode == Goal::ecNoSubstituters) ++nrNoSubstituters;
|
||||||
if (dep->exitCode == Goal::ecIncompleteClosure) ++nrIncompleteClosure;
|
if (dep->exitCode == Goal::ecIncompleteClosure) ++nrIncompleteClosure;
|
||||||
|
return _result;
|
||||||
}).eagerlyEvaluate(nullptr);
|
}).eagerlyEvaluate(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto collectDeps = asyncCollect(std::move(dependencies));
|
auto collectDeps = asyncCollect(std::move(dependencies));
|
||||||
|
|
||||||
while (auto item = co_await collectDeps.next()) {
|
while (auto item = co_await collectDeps.next()) {
|
||||||
auto & dep = *item;
|
auto & [dep, _result] = *item;
|
||||||
|
|
||||||
waiteeDone(dep);
|
waiteeDone(dep);
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,10 @@ struct Goal
|
||||||
*/
|
*/
|
||||||
BuildResult buildResult;
|
BuildResult buildResult;
|
||||||
|
|
||||||
|
struct WorkResult;
|
||||||
|
|
||||||
// for use by Worker and Goal only. will go away once work() is a promise.
|
// for use by Worker and Goal only. will go away once work() is a promise.
|
||||||
kj::Own<kj::PromiseFulfiller<void>> notify;
|
kj::Own<kj::PromiseFulfiller<Result<WorkResult>>> notify;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AsyncSemaphore::Token slotToken;
|
AsyncSemaphore::Token slotToken;
|
||||||
|
@ -112,13 +114,15 @@ public:
|
||||||
protected:
|
protected:
|
||||||
kj::Promise<void> waitForAWhile();
|
kj::Promise<void> waitForAWhile();
|
||||||
kj::Promise<Result<void>>
|
kj::Promise<Result<void>>
|
||||||
waitForGoals(kj::Array<std::pair<GoalPtr, kj::Promise<void>>> dependencies) noexcept;
|
waitForGoals(kj::Array<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies) noexcept;
|
||||||
|
|
||||||
template<std::derived_from<Goal>... G>
|
template<std::derived_from<Goal>... G>
|
||||||
kj::Promise<Result<void>>
|
kj::Promise<Result<void>>
|
||||||
waitForGoals(std::pair<std::shared_ptr<G>, kj::Promise<void>>... goals) noexcept
|
waitForGoals(std::pair<std::shared_ptr<G>, kj::Promise<Result<WorkResult>>>... goals) noexcept
|
||||||
{
|
{
|
||||||
return waitForGoals(kj::arrOf<std::pair<GoalPtr, kj::Promise<void>>>(std::move(goals)...));
|
return waitForGoals(
|
||||||
|
kj::arrOf<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>>(std::move(goals)...)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual kj::Promise<Result<WorkResult>> workImpl() noexcept = 0;
|
virtual kj::Promise<Result<WorkResult>> workImpl() noexcept = 0;
|
||||||
|
|
|
@ -157,7 +157,7 @@ try {
|
||||||
|
|
||||||
/* To maintain the closure invariant, we first have to realise the
|
/* To maintain the closure invariant, we first have to realise the
|
||||||
paths referenced by this one. */
|
paths referenced by this one. */
|
||||||
kj::Vector<std::pair<GoalPtr, kj::Promise<void>>> dependencies;
|
kj::Vector<std::pair<GoalPtr, kj::Promise<Result<WorkResult>>>> dependencies;
|
||||||
for (auto & i : info->references)
|
for (auto & i : info->references)
|
||||||
if (i != storePath) /* ignore self-references */
|
if (i != storePath) /* ignore self-references */
|
||||||
dependencies.add(worker.goalFactory().makePathSubstitutionGoal(i));
|
dependencies.add(worker.goalFactory().makePathSubstitutionGoal(i));
|
||||||
|
|
|
@ -53,7 +53,7 @@ Worker::~Worker()
|
||||||
|
|
||||||
|
|
||||||
template<typename ID, std::derived_from<Goal> G>
|
template<typename ID, std::derived_from<Goal> G>
|
||||||
std::pair<std::shared_ptr<G>, kj::Promise<void>> Worker::makeGoalCommon(
|
std::pair<std::shared_ptr<G>, kj::Promise<Result<Goal::WorkResult>>> Worker::makeGoalCommon(
|
||||||
std::map<ID, CachedGoal<G>> & map,
|
std::map<ID, CachedGoal<G>> & map,
|
||||||
const ID & key,
|
const ID & key,
|
||||||
InvocableR<std::unique_ptr<G>> auto create,
|
InvocableR<std::unique_ptr<G>> auto create,
|
||||||
|
@ -89,7 +89,7 @@ std::pair<std::shared_ptr<G>, kj::Promise<void>> Worker::makeGoalCommon(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeDerivationGoal(
|
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<Result<Goal::WorkResult>>> Worker::makeDerivationGoal(
|
||||||
const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode
|
const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeDeriva
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeBasicDerivationGoal(
|
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<Result<Goal::WorkResult>>> Worker::makeBasicDerivationGoal(
|
||||||
const StorePath & drvPath,
|
const StorePath & drvPath,
|
||||||
const BasicDerivation & drv,
|
const BasicDerivation & drv,
|
||||||
const OutputsSpec & wantedOutputs,
|
const OutputsSpec & wantedOutputs,
|
||||||
|
@ -134,7 +134,7 @@ std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeBasicD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::shared_ptr<PathSubstitutionGoal>, kj::Promise<void>>
|
std::pair<std::shared_ptr<PathSubstitutionGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
Worker::makePathSubstitutionGoal(
|
Worker::makePathSubstitutionGoal(
|
||||||
const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca
|
const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca
|
||||||
)
|
)
|
||||||
|
@ -148,7 +148,7 @@ Worker::makePathSubstitutionGoal(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::shared_ptr<DrvOutputSubstitutionGoal>, kj::Promise<void>>
|
std::pair<std::shared_ptr<DrvOutputSubstitutionGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
Worker::makeDrvOutputSubstitutionGoal(
|
Worker::makeDrvOutputSubstitutionGoal(
|
||||||
const DrvOutput & id, RepairFlag repair, std::optional<ContentAddress> ca
|
const DrvOutput & id, RepairFlag repair, std::optional<ContentAddress> ca
|
||||||
)
|
)
|
||||||
|
@ -162,16 +162,16 @@ Worker::makeDrvOutputSubstitutionGoal(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<GoalPtr, kj::Promise<void>> Worker::makeGoal(const DerivedPath & req, BuildMode buildMode)
|
std::pair<GoalPtr, kj::Promise<Result<Goal::WorkResult>>> Worker::makeGoal(const DerivedPath & req, BuildMode buildMode)
|
||||||
{
|
{
|
||||||
return std::visit(overloaded {
|
return std::visit(overloaded {
|
||||||
[&](const DerivedPath::Built & bfd) -> std::pair<GoalPtr, kj::Promise<void>> {
|
[&](const DerivedPath::Built & bfd) -> std::pair<GoalPtr, kj::Promise<Result<Goal::WorkResult>>> {
|
||||||
if (auto bop = std::get_if<DerivedPath::Opaque>(&*bfd.drvPath))
|
if (auto bop = std::get_if<DerivedPath::Opaque>(&*bfd.drvPath))
|
||||||
return makeDerivationGoal(bop->path, bfd.outputs, buildMode);
|
return makeDerivationGoal(bop->path, bfd.outputs, buildMode);
|
||||||
else
|
else
|
||||||
throw UnimplementedError("Building dynamic derivations in one shot is not yet implemented.");
|
throw UnimplementedError("Building dynamic derivations in one shot is not yet implemented.");
|
||||||
},
|
},
|
||||||
[&](const DerivedPath::Opaque & bo) -> std::pair<GoalPtr, kj::Promise<void>> {
|
[&](const DerivedPath::Opaque & bo) -> std::pair<GoalPtr, kj::Promise<Result<Goal::WorkResult>>> {
|
||||||
return makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair);
|
return makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair);
|
||||||
},
|
},
|
||||||
}, req.raw());
|
}, req.raw());
|
||||||
|
|
|
@ -30,10 +30,12 @@ struct HookInstance;
|
||||||
class GoalFactory
|
class GoalFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> makeDerivationGoal(
|
virtual std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
|
makeDerivationGoal(
|
||||||
const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal
|
const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal
|
||||||
) = 0;
|
) = 0;
|
||||||
virtual std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> makeBasicDerivationGoal(
|
virtual std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
|
makeBasicDerivationGoal(
|
||||||
const StorePath & drvPath,
|
const StorePath & drvPath,
|
||||||
const BasicDerivation & drv,
|
const BasicDerivation & drv,
|
||||||
const OutputsSpec & wantedOutputs,
|
const OutputsSpec & wantedOutputs,
|
||||||
|
@ -43,13 +45,13 @@ public:
|
||||||
/**
|
/**
|
||||||
* @ref SubstitutionGoal "substitution goal"
|
* @ref SubstitutionGoal "substitution goal"
|
||||||
*/
|
*/
|
||||||
virtual std::pair<std::shared_ptr<PathSubstitutionGoal>, kj::Promise<void>>
|
virtual std::pair<std::shared_ptr<PathSubstitutionGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
makePathSubstitutionGoal(
|
makePathSubstitutionGoal(
|
||||||
const StorePath & storePath,
|
const StorePath & storePath,
|
||||||
RepairFlag repair = NoRepair,
|
RepairFlag repair = NoRepair,
|
||||||
std::optional<ContentAddress> ca = std::nullopt
|
std::optional<ContentAddress> ca = std::nullopt
|
||||||
) = 0;
|
) = 0;
|
||||||
virtual std::pair<std::shared_ptr<DrvOutputSubstitutionGoal>, kj::Promise<void>>
|
virtual std::pair<std::shared_ptr<DrvOutputSubstitutionGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
makeDrvOutputSubstitutionGoal(
|
makeDrvOutputSubstitutionGoal(
|
||||||
const DrvOutput & id,
|
const DrvOutput & id,
|
||||||
RepairFlag repair = NoRepair,
|
RepairFlag repair = NoRepair,
|
||||||
|
@ -62,7 +64,7 @@ public:
|
||||||
* It will be a `DerivationGoal` for a `DerivedPath::Built` or
|
* It will be a `DerivationGoal` for a `DerivedPath::Built` or
|
||||||
* a `SubstitutionGoal` for a `DerivedPath::Opaque`.
|
* a `SubstitutionGoal` for a `DerivedPath::Opaque`.
|
||||||
*/
|
*/
|
||||||
virtual std::pair<GoalPtr, kj::Promise<void>>
|
virtual std::pair<GoalPtr, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) = 0;
|
makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,12 +97,12 @@ private:
|
||||||
struct CachedGoal
|
struct CachedGoal
|
||||||
{
|
{
|
||||||
std::weak_ptr<G> goal;
|
std::weak_ptr<G> goal;
|
||||||
kj::Own<kj::ForkedPromise<void>> promise;
|
kj::Own<kj::ForkedPromise<Result<Goal::WorkResult>>> promise;
|
||||||
kj::Own<kj::PromiseFulfiller<void>> fulfiller;
|
kj::Own<kj::PromiseFulfiller<Result<Goal::WorkResult>>> fulfiller;
|
||||||
|
|
||||||
CachedGoal()
|
CachedGoal()
|
||||||
{
|
{
|
||||||
auto pf = kj::newPromiseAndFulfiller<void>();
|
auto pf = kj::newPromiseAndFulfiller<Result<Goal::WorkResult>>();
|
||||||
promise = kj::heap(pf.promise.fork());
|
promise = kj::heap(pf.promise.fork());
|
||||||
fulfiller = std::move(pf.fulfiller);
|
fulfiller = std::move(pf.fulfiller);
|
||||||
}
|
}
|
||||||
|
@ -236,29 +238,29 @@ public:
|
||||||
*/
|
*/
|
||||||
private:
|
private:
|
||||||
template<typename ID, std::derived_from<Goal> G>
|
template<typename ID, std::derived_from<Goal> G>
|
||||||
std::pair<std::shared_ptr<G>, kj::Promise<void>> makeGoalCommon(
|
std::pair<std::shared_ptr<G>, kj::Promise<Result<Goal::WorkResult>>> makeGoalCommon(
|
||||||
std::map<ID, CachedGoal<G>> & map,
|
std::map<ID, CachedGoal<G>> & map,
|
||||||
const ID & key,
|
const ID & key,
|
||||||
InvocableR<std::unique_ptr<G>> auto create,
|
InvocableR<std::unique_ptr<G>> auto create,
|
||||||
InvocableR<bool, G &> auto modify
|
InvocableR<bool, G &> auto modify
|
||||||
);
|
);
|
||||||
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> makeDerivationGoal(
|
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<Result<Goal::WorkResult>>> makeDerivationGoal(
|
||||||
const StorePath & drvPath,
|
const StorePath & drvPath,
|
||||||
const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override;
|
const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override;
|
||||||
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> makeBasicDerivationGoal(
|
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<Result<Goal::WorkResult>>> makeBasicDerivationGoal(
|
||||||
const StorePath & drvPath, const BasicDerivation & drv,
|
const StorePath & drvPath, const BasicDerivation & drv,
|
||||||
const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override;
|
const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ref SubstitutionGoal "substitution goal"
|
* @ref SubstitutionGoal "substitution goal"
|
||||||
*/
|
*/
|
||||||
std::pair<std::shared_ptr<PathSubstitutionGoal>, kj::Promise<void>>
|
std::pair<std::shared_ptr<PathSubstitutionGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
makePathSubstitutionGoal(
|
makePathSubstitutionGoal(
|
||||||
const StorePath & storePath,
|
const StorePath & storePath,
|
||||||
RepairFlag repair = NoRepair,
|
RepairFlag repair = NoRepair,
|
||||||
std::optional<ContentAddress> ca = std::nullopt
|
std::optional<ContentAddress> ca = std::nullopt
|
||||||
) override;
|
) override;
|
||||||
std::pair<std::shared_ptr<DrvOutputSubstitutionGoal>, kj::Promise<void>>
|
std::pair<std::shared_ptr<DrvOutputSubstitutionGoal>, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
makeDrvOutputSubstitutionGoal(
|
makeDrvOutputSubstitutionGoal(
|
||||||
const DrvOutput & id,
|
const DrvOutput & id,
|
||||||
RepairFlag repair = NoRepair,
|
RepairFlag repair = NoRepair,
|
||||||
|
@ -271,11 +273,11 @@ private:
|
||||||
* It will be a `DerivationGoal` for a `DerivedPath::Built` or
|
* It will be a `DerivationGoal` for a `DerivedPath::Built` or
|
||||||
* a `SubstitutionGoal` for a `DerivedPath::Opaque`.
|
* a `SubstitutionGoal` for a `DerivedPath::Opaque`.
|
||||||
*/
|
*/
|
||||||
std::pair<GoalPtr, kj::Promise<void>>
|
std::pair<GoalPtr, kj::Promise<Result<Goal::WorkResult>>>
|
||||||
makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) override;
|
makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Targets = std::map<GoalPtr, kj::Promise<void>>;
|
using Targets = std::map<GoalPtr, kj::Promise<Result<Goal::WorkResult>>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loop until the specified top-level goals have finished.
|
* Loop until the specified top-level goals have finished.
|
||||||
|
|
Loading…
Reference in a new issue