libstore: asyncify Derivation::tryResolve
Change-Id: Id00e1d2a2316ab1daafcd308ee5e48c36e9c3a43
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user