libstore: asyncify Derivation::tryResolve

Change-Id: Id00e1d2a2316ab1daafcd308ee5e48c36e9c3a43
This commit is contained in:
eldritch horrors
2025-02-23 17:18:48 +00:00
parent 645a90b3e2
commit 990b3b0cfc
5 changed files with 19 additions and 13 deletions
+1 -1
View File
@@ -410,7 +410,7 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a
}
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
auto resolvedDrv = drv.tryResolve(*store);
auto resolvedDrv = aio.blockOn(drv.tryResolve(*store));
assert(resolvedDrv && "Successfully resolved the derivation");
drv = *resolvedDrv;
}
+2 -2
View File
@@ -588,14 +588,14 @@ try {
/* We are be able to resolve this derivation based on the
now-known results of dependencies. If so, we become a
stub goal aliasing that resolved derivation goal. */
std::optional attempt = fullDrv.tryResolve(worker.store, inputDrvOutputs);
std::optional attempt = TRY_AWAIT(fullDrv.tryResolve(worker.store, inputDrvOutputs));
if (!attempt) {
/* TODO (impure derivations-induced tech debt) (see below):
The above attempt should have found it, but because we manage
inputDrvOutputs statefully, sometimes it gets out of sync with
the real source of truth (store). So we query the store
directly if there's a problem. */
attempt = fullDrv.tryResolve(worker.store, &worker.evalStore);
attempt = TRY_AWAIT(fullDrv.tryResolve(worker.store, &worker.evalStore));
}
assert(attempt);
Derivation drvResolved { std::move(*attempt) };
+12 -7
View File
@@ -1054,8 +1054,9 @@ static void rewriteDerivation(Store & store, BasicDerivation & drv, const String
}
std::optional<BasicDerivation> Derivation::tryResolve(Store & store, Store * evalStore) const
{
kj::Promise<Result<std::optional<BasicDerivation>>>
Derivation::tryResolve(Store & store, Store * evalStore) const
try {
std::map<std::pair<StorePath, std::string>, StorePath> inputDrvOutputs;
std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accum;
@@ -1072,7 +1073,9 @@ std::optional<BasicDerivation> Derivation::tryResolve(Store & store, Store * eva
for (auto & [inputDrv, node] : inputDrvs.map)
accum(inputDrv, node);
return tryResolve(store, inputDrvOutputs);
co_return TRY_AWAIT(tryResolve(store, inputDrvOutputs));
} catch (...) {
co_return result::current_exception();
}
static bool tryResolveInput(
@@ -1122,10 +1125,10 @@ static bool tryResolveInput(
return true;
}
std::optional<BasicDerivation> Derivation::tryResolve(
kj::Promise<Result<std::optional<BasicDerivation>>> Derivation::tryResolve(
Store & store,
const std::map<std::pair<StorePath, std::string>, StorePath> & inputDrvOutputs) const
{
try {
BasicDerivation resolved { *this };
// Input paths that we'll want to rewrite in the derivation
@@ -1134,11 +1137,13 @@ std::optional<BasicDerivation> Derivation::tryResolve(
for (auto & [inputDrv, inputNode] : inputDrvs.map)
if (!tryResolveInput(store, resolved.inputSrcs, inputRewrites,
nullptr, inputDrv, inputNode, inputDrvOutputs))
return std::nullopt;
co_return std::nullopt;
rewriteDerivation(store, resolved, inputRewrites);
return resolved;
co_return resolved;
} catch (...) {
co_return result::current_exception();
}
+3 -2
View File
@@ -342,14 +342,15 @@ struct Derivation : BasicDerivation
* 2. Input placeholders are replaced with realized input store
* paths.
*/
std::optional<BasicDerivation> tryResolve(Store & store, Store * evalStore = nullptr) const;
kj::Promise<Result<std::optional<BasicDerivation>>>
tryResolve(Store & store, Store * evalStore = nullptr) const;
/**
* Like the above, but instead of querying the Nix database for
* realisations, uses a given mapping from input derivation paths +
* output names to actual output store paths.
*/
std::optional<BasicDerivation> tryResolve(
kj::Promise<Result<std::optional<BasicDerivation>>> tryResolve(
Store & store,
const std::map<std::pair<StorePath, std::string>, StorePath> & inputDrvOutputs) const;
+1 -1
View File
@@ -1431,7 +1431,7 @@ try {
if (!drv.type().hasKnownOutputPaths()) {
// The build log is actually attached to the corresponding
// resolved derivation, so we need to get it first
auto resolvedDrv = drv.tryResolve(*this);
auto resolvedDrv = TRY_AWAIT(drv.tryResolve(*this));
if (resolvedDrv)
co_return TRY_AWAIT(writeDerivation(*this, *resolvedDrv, NoRepair, true));
}