1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-22 17:01:08 +01:00

DrvOutputSubstitutionGoal: Don't actually fetch any store objects

We now have a nice separation of concerns: `DrvOutputSubstitutionGoal`
is *just* for getting realisations, and `PathSubstitutionGoal` is just
for fetching store objects.

The fetching of store objects that this used to do is now moved to the
caller.
This commit is contained in:
John Ericson 2025-10-14 18:10:27 -04:00
parent 4a5d960952
commit 018d6462de
3 changed files with 34 additions and 30 deletions

View file

@ -1,4 +1,5 @@
#include "nix/store/build/derivation-goal.hh" #include "nix/store/build/derivation-goal.hh"
#include "nix/store/build/drv-output-substitution-goal.hh"
#include "nix/store/build/derivation-building-goal.hh" #include "nix/store/build/derivation-building-goal.hh"
#include "nix/store/build/derivation-resolution-goal.hh" #include "nix/store/build/derivation-resolution-goal.hh"
#ifndef _WIN32 // TODO enable build hook on Windows #ifndef _WIN32 // TODO enable build hook on Windows
@ -100,9 +101,24 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
through substitutes. If that doesn't work, we'll build through substitutes. If that doesn't work, we'll build
them. */ them. */
if (settings.useSubstitutes && drvOptions.substitutesAllowed()) { if (settings.useSubstitutes && drvOptions.substitutesAllowed()) {
if (!checkResult) if (!checkResult) {
waitees.insert(upcast_goal(worker.makeDrvOutputSubstitutionGoal(DrvOutput{outputHash, wantedOutput}))); DrvOutput id{outputHash, wantedOutput};
else { auto g = worker.makeDrvOutputSubstitutionGoal(id);
waitees.insert(g);
co_await await(std::move(waitees));
if (nrFailed == 0) {
waitees.insert(upcast_goal(worker.makePathSubstitutionGoal(g->outputInfo->outPath)));
co_await await(std::move(waitees));
trace("output path substituted");
if (nrFailed == 0)
worker.store.registerDrvOutput({*g->outputInfo, id});
else
debug("The output path of the derivation output '%s' could not be substituted", id.to_string());
}
} else {
auto * cap = getDerivationCA(*drv); auto * cap = getDerivationCA(*drv);
waitees.insert(upcast_goal(worker.makePathSubstitutionGoal( waitees.insert(upcast_goal(worker.makePathSubstitutionGoal(
checkResult->first.outPath, checkResult->first.outPath,

View file

@ -19,7 +19,7 @@ Goal::Co DrvOutputSubstitutionGoal::init()
trace("init"); trace("init");
/* If the derivation already exists, were done */ /* If the derivation already exists, were done */
if (worker.store.queryRealisation(id)) { if ((outputInfo = worker.store.queryRealisation(id))) {
co_return amDone(ecSuccess); co_return amDone(ecSuccess);
} }
@ -77,12 +77,6 @@ Goal::Co DrvOutputSubstitutionGoal::init()
worker.childTerminated(this); worker.childTerminated(this);
/*
* The realisation corresponding to the given output id.
* Will be filled once we can get it.
*/
std::shared_ptr<const UnkeyedRealisation> outputInfo;
try { try {
outputInfo = promise->get_future().get(); outputInfo = promise->get_future().get();
} catch (std::exception & e) { } catch (std::exception & e) {
@ -93,21 +87,6 @@ Goal::Co DrvOutputSubstitutionGoal::init()
if (!outputInfo) if (!outputInfo)
continue; continue;
Goals waitees;
waitees.insert(worker.makePathSubstitutionGoal(outputInfo->outPath));
co_await await(std::move(waitees));
trace("output path substituted");
if (nrFailed > 0) {
debug("The output path of the derivation output '%s' could not be substituted", id.to_string());
co_return amDone(nrNoSubstituters > 0 ? ecNoSubstituters : ecFailed);
}
worker.store.registerDrvOutput({*outputInfo, id});
trace("finished"); trace("finished");
co_return amDone(ecSuccess); co_return amDone(ecSuccess);
} }

View file

@ -14,11 +14,14 @@ namespace nix {
class Worker; class Worker;
/** /**
* Substitution of a derivation output. * Fetch a `Realisation` (drv output name -> output path) from a
* This is done in three steps: * substituter.
* 1. Fetch the output info from a substituter *
* 2. Substitute the corresponding output path * If the output store object itself should also be substituted, that is
* 3. Register the output info * the responsibility of the caller to do so.
*
* @todo rename this `BuidlTraceEntryGoal`, which will make sense
* especially once `Realisation` is renamed to `BuildTraceEntry`.
*/ */
class DrvOutputSubstitutionGoal : public Goal class DrvOutputSubstitutionGoal : public Goal
{ {
@ -31,6 +34,12 @@ class DrvOutputSubstitutionGoal : public Goal
public: public:
DrvOutputSubstitutionGoal(const DrvOutput & id, Worker & worker); DrvOutputSubstitutionGoal(const DrvOutput & id, Worker & worker);
/**
* The realisation corresponding to the given output id.
* Will be filled once we can get it.
*/
std::shared_ptr<const UnkeyedRealisation> outputInfo;
Co init(); Co init();
std::string key() override; std::string key() override;