libexpr: asyncify FlakeRef::fetchTree
Change-Id: I8334d8e1a9ea0e555bf2af1eb09dd9653013b28b
This commit is contained in:
@@ -203,7 +203,9 @@ SourcePath lookupFileArg(Evaluator & state, std::string_view fileArg)
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
static constexpr size_t FLAKE_LEN = std::string_view("flake:").size();
|
||||
auto flakeRef = parseFlakeRef(std::string(fileArg.substr(FLAKE_LEN)), {}, true, false);
|
||||
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first.storePath;
|
||||
auto storePath =
|
||||
RUN_ASYNC_IN_NEW_THREAD(flakeRef.resolve(state.store).fetchTree(state.store))
|
||||
.first.storePath;
|
||||
return CanonPath(state.store->toRealPath(storePath));
|
||||
} else if (fileArg.size() > 2 && fileArg.at(0) == '<' && fileArg.at(fileArg.size() - 1) == '>') {
|
||||
Path p(fileArg.substr(1, fileArg.size() - 2));
|
||||
|
||||
+3
-2
@@ -2808,8 +2808,9 @@ std::optional<std::string> EvalPaths::resolveSearchPathPath(const SearchPath::Pa
|
||||
experimentalFeatureSettings.require(Xp::Flakes);
|
||||
auto flakeRef = parseFlakeRef(value.substr(6), {}, true, false);
|
||||
debug("fetching flake search path element '%s''", value);
|
||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first.storePath;
|
||||
res = { store->toRealPath(storePath) };
|
||||
auto storePath =
|
||||
RUN_ASYNC_IN_NEW_THREAD(flakeRef.resolve(store).fetchTree(store)).first.storePath;
|
||||
res = {store->toRealPath(storePath)};
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "lix/libexpr/eval-inline.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
#include "lix/libfetchers/fetchers.hh"
|
||||
#include "lix/libutil/async.hh"
|
||||
#include "lix/libutil/finally.hh"
|
||||
#include "lix/libfetchers/fetch-settings.hh"
|
||||
#include "lix/libutil/terminal.hh"
|
||||
@@ -36,23 +37,25 @@ static std::optional<FetchedFlake> lookupInFlakeCache(
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static std::tuple<fetchers::Tree, FlakeRef, FlakeRef> fetchOrSubstituteTree(
|
||||
static kj::Promise<Result<std::tuple<fetchers::Tree, FlakeRef, FlakeRef>>> fetchOrSubstituteTree(
|
||||
Evaluator & state,
|
||||
const FlakeRef & originalRef,
|
||||
bool allowLookup,
|
||||
FlakeCache & flakeCache)
|
||||
{
|
||||
try {
|
||||
auto fetched = lookupInFlakeCache(flakeCache, originalRef);
|
||||
FlakeRef resolvedRef = originalRef;
|
||||
|
||||
if (!fetched) {
|
||||
if (originalRef.input.isDirect()) {
|
||||
fetched.emplace(originalRef.fetchTree(state.store));
|
||||
fetched.emplace(TRY_AWAIT(originalRef.fetchTree(state.store)));
|
||||
} else {
|
||||
if (allowLookup) {
|
||||
resolvedRef = originalRef.resolve(state.store);
|
||||
auto fetchedResolved = lookupInFlakeCache(flakeCache, originalRef);
|
||||
if (!fetchedResolved) fetchedResolved.emplace(resolvedRef.fetchTree(state.store));
|
||||
if (!fetchedResolved) {
|
||||
fetchedResolved.emplace(TRY_AWAIT(resolvedRef.fetchTree(state.store)));
|
||||
}
|
||||
flakeCache.push_back({resolvedRef, *fetchedResolved});
|
||||
fetched.emplace(*fetchedResolved);
|
||||
}
|
||||
@@ -72,7 +75,9 @@ static std::tuple<fetchers::Tree, FlakeRef, FlakeRef> fetchOrSubstituteTree(
|
||||
|
||||
assert(!originalRef.input.getNarHash() || tree.storePath == originalRef.input.computeStorePath(*state.store));
|
||||
|
||||
return {std::move(tree), resolvedRef, lockedRef};
|
||||
co_return {std::move(tree), resolvedRef, lockedRef};
|
||||
} catch (...) {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos)
|
||||
@@ -216,8 +221,8 @@ static Flake getFlake(
|
||||
FlakeCache & flakeCache,
|
||||
InputPath lockRootPath)
|
||||
{
|
||||
auto [sourceInfo, resolvedRef, lockedRef] = fetchOrSubstituteTree(
|
||||
state.ctx, originalRef, allowLookup, flakeCache);
|
||||
auto [sourceInfo, resolvedRef, lockedRef] =
|
||||
state.aio.blockOn(fetchOrSubstituteTree(state.ctx, originalRef, allowLookup, flakeCache));
|
||||
|
||||
// We need to guard against symlink attacks, but before we start doing
|
||||
// filesystem operations we should make sure there's a flake.nix in the
|
||||
@@ -633,8 +638,10 @@ LockedFlake lockFlake(
|
||||
}
|
||||
|
||||
else {
|
||||
auto [sourceInfo, resolvedRef, lockedRef] = fetchOrSubstituteTree(
|
||||
state.ctx, *input.ref, useRegistries, flakeCache);
|
||||
auto [sourceInfo, resolvedRef, lockedRef] =
|
||||
state.aio.blockOn(fetchOrSubstituteTree(
|
||||
state.ctx, *input.ref, useRegistries, flakeCache
|
||||
));
|
||||
|
||||
auto childNode = make_ref<LockedNode>(lockedRef, ref, false);
|
||||
|
||||
|
||||
@@ -238,10 +238,12 @@ FlakeRef FlakeRef::fromAttrs(const fetchers::Attrs & attrs)
|
||||
fetchers::maybeGetStrAttr(attrs, "dir").value_or(""));
|
||||
}
|
||||
|
||||
std::pair<fetchers::Tree, FlakeRef> FlakeRef::fetchTree(ref<Store> store) const
|
||||
{
|
||||
auto [tree, lockedInput] = RUN_ASYNC_IN_NEW_THREAD(input.fetch(store));
|
||||
return {std::move(tree), FlakeRef(std::move(lockedInput), subdir)};
|
||||
kj::Promise<Result<std::pair<fetchers::Tree, FlakeRef>>> FlakeRef::fetchTree(ref<Store> store) const
|
||||
try {
|
||||
auto [tree, lockedInput] = TRY_AWAIT(input.fetch(store));
|
||||
co_return {std::move(tree), FlakeRef(std::move(lockedInput), subdir)};
|
||||
} catch (...) {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
std::tuple<FlakeRef, std::string, ExtendedOutputsSpec> parseFlakeRefWithFragmentAndExtendedOutputsSpec(
|
||||
|
||||
@@ -62,7 +62,7 @@ struct FlakeRef
|
||||
|
||||
static FlakeRef fromAttrs(const fetchers::Attrs & attrs);
|
||||
|
||||
std::pair<fetchers::Tree, FlakeRef> fetchTree(ref<Store> store) const;
|
||||
kj::Promise<Result<std::pair<fetchers::Tree, FlakeRef>>> fetchTree(ref<Store> store) const;
|
||||
};
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
|
||||
|
||||
+1
-1
@@ -1449,7 +1449,7 @@ struct CmdFlakePrefetch : FlakeCommand, MixJSON
|
||||
{
|
||||
auto originalRef = getFlakeRef();
|
||||
auto resolvedRef = originalRef.resolve(store);
|
||||
auto [tree, lockedRef] = resolvedRef.fetchTree(store);
|
||||
auto [tree, lockedRef] = aio().blockOn(resolvedRef.fetchTree(store));
|
||||
auto hash = store->queryPathInfo(tree.storePath)->narHash;
|
||||
|
||||
if (json) {
|
||||
|
||||
Reference in New Issue
Block a user