libfetchers: asyncify getRegistries, lookupInRegistries
Change-Id: I5a668ad05440e2d7d574e8a470c269b670282c6f
This commit is contained in:
@@ -363,7 +363,7 @@ void completeFlakeRef(
|
||||
Args::completeDir(completions, 0, prefix);
|
||||
|
||||
/* Look for registry entries that match the prefix. */
|
||||
for (auto & registry : fetchers::getRegistries(store)) {
|
||||
for (auto & registry : aio.blockOn(fetchers::getRegistries(store))) {
|
||||
for (auto & entry : registry->entries) {
|
||||
auto from = entry.from.to_string();
|
||||
if (!prefix.starts_with("flake:") && from.starts_with("flake:")) {
|
||||
|
||||
@@ -44,7 +44,7 @@ bool FlakeRef::operator ==(const FlakeRef & other) const
|
||||
|
||||
kj::Promise<Result<FlakeRef>> FlakeRef::resolve(ref<Store> store) const
|
||||
try {
|
||||
auto [input2, extraAttrs] = lookupInRegistries(store, input);
|
||||
auto [input2, extraAttrs] = TRY_AWAIT(lookupInRegistries(store, input));
|
||||
co_return FlakeRef(
|
||||
std::move(input2), fetchers::maybeGetStrAttr(extraAttrs, "dir").value_or(subdir)
|
||||
);
|
||||
|
||||
@@ -186,7 +186,7 @@ static void fetchTree(
|
||||
}
|
||||
|
||||
if (!evalSettings.pureEval && !input.isDirect())
|
||||
input = lookupInRegistries(state.ctx.store, input).first;
|
||||
input = state.aio.blockOn(lookupInRegistries(state.ctx.store, input)).first;
|
||||
|
||||
if (evalSettings.pureEval && !input.isLocked()) {
|
||||
state.ctx.errors.make<EvalError>("in pure evaluation mode, 'fetchTree' requires a locked input").atPos(pos).debugThrow();
|
||||
|
||||
+50
-26
@@ -1,5 +1,7 @@
|
||||
#include "lix/libfetchers/registry.hh"
|
||||
#include "lix/libfetchers/fetchers.hh"
|
||||
#include "lix/libutil/async.hh"
|
||||
#include "lix/libutil/types.hh"
|
||||
#include "lix/libutil/users.hh"
|
||||
#include "lix/libstore/globals.hh"
|
||||
#include "lix/libstore/store-api.hh"
|
||||
@@ -7,7 +9,10 @@
|
||||
|
||||
#include "lix/libfetchers/fetch-settings.hh"
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace nix::fetchers {
|
||||
|
||||
@@ -153,45 +158,62 @@ void overrideRegistry(
|
||||
flagRegistry->add(from, to, extraAttrs);
|
||||
}
|
||||
|
||||
static std::shared_ptr<Registry> getGlobalRegistry(ref<Store> store)
|
||||
{
|
||||
static auto reg = [&]() {
|
||||
static kj::Promise<Result<std::shared_ptr<Registry>>> getGlobalRegistry(ref<Store> store)
|
||||
try {
|
||||
static std::shared_mutex mtx;
|
||||
static std::shared_ptr<Registry> reg;
|
||||
|
||||
if (std::shared_lock l(mtx); reg) {
|
||||
co_return reg;
|
||||
}
|
||||
|
||||
std::scoped_lock l(mtx);
|
||||
|
||||
if (!reg) {
|
||||
auto path = fetchSettings.flakeRegistry.get();
|
||||
if (path == "") {
|
||||
return std::make_shared<Registry>(Registry::Global); // empty registry
|
||||
reg = std::make_shared<Registry>(Registry::Global); // empty registry
|
||||
} else if (path == "vendored") {
|
||||
return Registry::read(settings.nixDataDir + "/flake-registry.json", Registry::Global);
|
||||
reg = Registry::read(settings.nixDataDir + "/flake-registry.json", Registry::Global);
|
||||
} else {
|
||||
if (!path.starts_with("/")) {
|
||||
warn(
|
||||
"config option flake-registry referring to a URL is deprecated and will be "
|
||||
"removed in Lix 3.0; yours is: `%s'",
|
||||
path
|
||||
);
|
||||
|
||||
auto storePath = downloadFile(store, path, "flake-registry.json", false).storePath;
|
||||
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
store2->addPermRoot(storePath, getCacheDir() + "/nix/flake-registry.json");
|
||||
path = store->toRealPath(storePath);
|
||||
}
|
||||
|
||||
reg = Registry::read(path, Registry::Global);
|
||||
}
|
||||
};
|
||||
|
||||
if (!path.starts_with("/")) {
|
||||
warn("config option flake-registry referring to a URL is deprecated and will be removed in Lix 3.0; yours is: `%s'", path);
|
||||
|
||||
auto storePath = downloadFile(store, path, "flake-registry.json", false).storePath;
|
||||
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
store2->addPermRoot(storePath, getCacheDir() + "/nix/flake-registry.json");
|
||||
path = store->toRealPath(storePath);
|
||||
}
|
||||
|
||||
return Registry::read(path, Registry::Global);
|
||||
}();
|
||||
|
||||
return reg;
|
||||
co_return reg;
|
||||
} catch (...) {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
Registries getRegistries(ref<Store> store)
|
||||
{
|
||||
kj::Promise<Result<Registries>> getRegistries(ref<Store> store)
|
||||
try {
|
||||
Registries registries;
|
||||
registries.push_back(getFlagRegistry());
|
||||
registries.push_back(getUserRegistry());
|
||||
registries.push_back(getSystemRegistry());
|
||||
registries.push_back(getGlobalRegistry(store));
|
||||
return registries;
|
||||
registries.push_back(TRY_AWAIT(getGlobalRegistry(store)));
|
||||
co_return registries;
|
||||
} catch (...) {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
std::pair<Input, Attrs> lookupInRegistries(
|
||||
kj::Promise<Result<std::pair<Input, Attrs>>> lookupInRegistries(
|
||||
ref<Store> store,
|
||||
const Input & _input)
|
||||
{
|
||||
try {
|
||||
Attrs extraAttrs;
|
||||
int n = 0;
|
||||
Input input(_input);
|
||||
@@ -201,7 +223,7 @@ std::pair<Input, Attrs> lookupInRegistries(
|
||||
n++;
|
||||
if (n > 100) throw Error("cycle detected in flake registry for '%s'", input.to_string());
|
||||
|
||||
for (auto & registry : getRegistries(store)) {
|
||||
for (auto & registry : TRY_AWAIT(getRegistries(store))) {
|
||||
// FIXME: O(n)
|
||||
for (auto & entry : registry->entries) {
|
||||
if (entry.exact) {
|
||||
@@ -227,7 +249,9 @@ std::pair<Input, Attrs> lookupInRegistries(
|
||||
|
||||
debug("looked up '%s' -> '%s'", _input.to_string(), input.to_string());
|
||||
|
||||
return {input, extraAttrs};
|
||||
co_return {input, extraAttrs};
|
||||
} catch (...) {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,14 +54,14 @@ std::shared_ptr<Registry> getCustomRegistry(const Path & p);
|
||||
|
||||
Path getUserRegistryPath();
|
||||
|
||||
Registries getRegistries(ref<Store> store);
|
||||
kj::Promise<Result<Registries>> getRegistries(ref<Store> store);
|
||||
|
||||
void overrideRegistry(
|
||||
const Input & from,
|
||||
const Input & to,
|
||||
const Attrs & extraAttrs);
|
||||
|
||||
std::pair<Input, Attrs> lookupInRegistries(
|
||||
kj::Promise<Result<std::pair<Input, Attrs>>> lookupInRegistries(
|
||||
ref<Store> store,
|
||||
const Input & input);
|
||||
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ struct CmdRegistryList : StoreCommand
|
||||
{
|
||||
using namespace fetchers;
|
||||
|
||||
auto registries = getRegistries(store);
|
||||
auto registries = aio().blockOn(getRegistries(store));
|
||||
|
||||
for (auto & registry : registries) {
|
||||
for (auto & entry : registry->entries) {
|
||||
|
||||
Reference in New Issue
Block a user