fix for asyncized lix
This commit is contained in:
committed by
eldritch horrors
parent
6482bee40b
commit
53ce7ebc33
@@ -24,6 +24,8 @@ stdenv.mkDerivation {
|
||||
ninja
|
||||
# nlohmann_json can be only discovered via cmake files
|
||||
cmake
|
||||
# XXX: ew
|
||||
nix.passthru.capnproto-lix
|
||||
] ++ (lib.optional stdenv.cc.isClang [ pkgs.clang-tools ]);
|
||||
|
||||
meta = {
|
||||
|
||||
Generated
+7
-7
@@ -47,11 +47,11 @@
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737234286,
|
||||
"narHash": "sha256-pgDJZjj4jpzkFxsqBTI/9Yb0n3gW+DvDtuv9SwQZZcs=",
|
||||
"rev": "079528098f5998ba13c88821a2eca1005c1695de",
|
||||
"lastModified": 1737857294,
|
||||
"narHash": "sha256-bzC+anLF/NlgolaMoB4uTFgSejLJlTzPcNF1Kbq/BP0=",
|
||||
"rev": "4af6b5ed9f8f2412bef5331b8e3b93f3ad305ea1",
|
||||
"type": "tarball",
|
||||
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/079528098f5998ba13c88821a2eca1005c1695de.tar.gz?rev=079528098f5998ba13c88821a2eca1005c1695de"
|
||||
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/4af6b5ed9f8f2412bef5331b8e3b93f3ad305ea1.tar.gz?rev=4af6b5ed9f8f2412bef5331b8e3b93f3ad305ea1"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
@@ -96,11 +96,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1737226685,
|
||||
"narHash": "sha256-34x0t/x5SkClo04gaG+KPBwN9JtXjFSQGTl//Yry4Gc=",
|
||||
"lastModified": 1737672001,
|
||||
"narHash": "sha256-YnHJJ19wqmibLQdUeq9xzE6CjrMA568KN/lFPuSVs4I=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bf68d76e54ac5da0d77f82656a37552996195e80",
|
||||
"rev": "035f8c0853c2977b24ffc4d0a42c74f00b182cd8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -15,5 +15,6 @@ nix_cmd_dep = dependency('lix-cmd', required: true)
|
||||
threads_dep = dependency('threads', required: true)
|
||||
nlohmann_json_dep = dependency('nlohmann_json', required: true)
|
||||
boost_dep = dependency('boost', required: true)
|
||||
kj_async_dep = dependency('kj-async', required: true)
|
||||
|
||||
subdir('src')
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
#include <lix/libutil/async.hh>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <lix/libutil/args.hh>
|
||||
@@ -11,7 +12,7 @@
|
||||
|
||||
#include "eval-args.hh"
|
||||
|
||||
MyArgs::MyArgs() : MixCommonArgs("nix-eval-jobs") {
|
||||
MyArgs::MyArgs(nix::AsyncIoRoot & aio) : MixCommonArgs("nix-eval-jobs"), aio_(aio) {
|
||||
addFlag({
|
||||
.longName = "help",
|
||||
.description = "show usage information",
|
||||
|
||||
+7
-1
@@ -3,6 +3,7 @@
|
||||
#include <lix/libexpr/flake/flake.hh>
|
||||
#include <lix/libutil/args/root.hh>
|
||||
#include <lix/libcmd/common-eval-args.hh>
|
||||
#include <lix/libutil/async.hh>
|
||||
#include <stddef.h>
|
||||
#include <lix/libmain/common-args.hh>
|
||||
#include <lix/libexpr/flake/flakeref.hh>
|
||||
@@ -13,6 +14,10 @@
|
||||
class MyArgs : virtual public nix::MixEvalArgs,
|
||||
virtual public nix::MixCommonArgs,
|
||||
virtual public nix::RootArgs {
|
||||
// intentionally hidden in this subclass because it's mondo dangerous
|
||||
// in n-e-j due to all the forking we do for worker process creation.
|
||||
nix::AsyncIoRoot & aio_;
|
||||
nix::AsyncIoRoot & aio() override { return aio_; }
|
||||
public:
|
||||
std::string releaseExpr;
|
||||
nix::Path gcRootsDir;
|
||||
@@ -31,7 +36,8 @@ class MyArgs : virtual public nix::MixEvalArgs,
|
||||
.writeLockFile = false,
|
||||
.useRegistries = false,
|
||||
.allowUnlocked = false};
|
||||
MyArgs();
|
||||
|
||||
MyArgs(nix::AsyncIoRoot & aio);
|
||||
MyArgs(const MyArgs&) = delete;
|
||||
|
||||
void parseArgs(char** argv, int argc);
|
||||
|
||||
+22
-13
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <lix/libexpr/eval-settings.hh>
|
||||
#include <lix/libmain/shared.hh>
|
||||
#include <lix/libutil/async.hh>
|
||||
#include <lix/libutil/sync.hh>
|
||||
#include <lix/libexpr/eval.hh>
|
||||
#include <lix/libutil/signals.hh>
|
||||
@@ -44,17 +45,16 @@
|
||||
using namespace nix;
|
||||
using namespace nlohmann;
|
||||
|
||||
static MyArgs myArgs;
|
||||
|
||||
using Processor = std::function<void(ref<nix::eval_cache::CachingEvaluator> state, Bindings &autoArgs,
|
||||
AutoCloseFD &to, AutoCloseFD &from, MyArgs &args)>;
|
||||
using Processor = std::function<void(
|
||||
ref<nix::eval_cache::CachingEvaluator> state, Bindings &autoArgs,
|
||||
AutoCloseFD &to, AutoCloseFD &from, MyArgs &args, AsyncIoRoot &aio)>;
|
||||
|
||||
/* Auto-cleanup of fork's process and fds. */
|
||||
struct Proc {
|
||||
AutoCloseFD to, from;
|
||||
Pid pid;
|
||||
|
||||
Proc(const Processor &proc) {
|
||||
Proc(MyArgs &myArgs, const Processor &proc) {
|
||||
Pipe toPipe, fromPipe;
|
||||
toPipe.create();
|
||||
fromPipe.create();
|
||||
@@ -65,13 +65,15 @@ struct Proc {
|
||||
std::make_shared<AutoCloseFD>(std::move(toPipe.readSide))}]() {
|
||||
debug("created worker process %d", getpid());
|
||||
try {
|
||||
AsyncIoRoot aio;
|
||||
auto evalStore = myArgs.evalStoreUrl
|
||||
? openStore(*myArgs.evalStoreUrl)
|
||||
: openStore();
|
||||
auto evaluator = nix::make_ref<nix::eval_cache::CachingEvaluator>(myArgs.searchPath,
|
||||
evalStore);
|
||||
auto evaluator =
|
||||
nix::make_ref<nix::eval_cache::CachingEvaluator>(
|
||||
aio, myArgs.searchPath, evalStore);
|
||||
Bindings &autoArgs = *myArgs.getAutoArgs(*evaluator);
|
||||
proc(evaluator, autoArgs, *to, *from, myArgs);
|
||||
proc(evaluator, autoArgs, *to, *from, myArgs, aio);
|
||||
} catch (Error &e) {
|
||||
nlohmann::json err;
|
||||
auto msg = e.msg();
|
||||
@@ -120,7 +122,8 @@ struct Thread {
|
||||
if ((s = pthread_attr_setstacksize(&attr, 64 * 1024 * 1024)) != 0) {
|
||||
throw SysError(s, "calling pthread_attr_setstacksize");
|
||||
}
|
||||
if ((s = pthread_create(&thread, &attr, Thread::init, func.release())) != 0) {
|
||||
if ((s = pthread_create(&thread, &attr, Thread::init,
|
||||
func.release())) != 0) {
|
||||
throw SysError(s, "calling pthread_launch");
|
||||
}
|
||||
if ((s = pthread_attr_destroy(&attr)) != 0) {
|
||||
@@ -135,7 +138,8 @@ struct Thread {
|
||||
throw SysError(s, "calling pthread_join");
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
static void *init(void *ptr) {
|
||||
std::unique_ptr<std::function<void(void)>> func;
|
||||
func.reset(static_cast<std::function<void(void)> *>(ptr));
|
||||
@@ -221,14 +225,15 @@ std::string joinAttrPath(json &attrPath) {
|
||||
return joined;
|
||||
}
|
||||
|
||||
void collector(Sync<State> &state_, std::condition_variable &wakeup) {
|
||||
void collector(MyArgs &myArgs, Sync<State> &state_,
|
||||
std::condition_variable &wakeup) {
|
||||
try {
|
||||
std::optional<std::unique_ptr<Proc>> proc_;
|
||||
std::optional<std::unique_ptr<LineReader>> fromReader_;
|
||||
|
||||
while (true) {
|
||||
if (!proc_.has_value()) {
|
||||
proc_ = std::make_unique<Proc>(worker);
|
||||
proc_ = std::make_unique<Proc>(myArgs, worker);
|
||||
fromReader_ =
|
||||
std::make_unique<LineReader>(proc_.value()->from.release());
|
||||
}
|
||||
@@ -344,6 +349,9 @@ int main(int argc, char **argv) {
|
||||
initNix();
|
||||
initLibExpr();
|
||||
|
||||
nix::AsyncIoRoot aio;
|
||||
MyArgs myArgs(aio);
|
||||
|
||||
myArgs.parseArgs(argv, argc);
|
||||
|
||||
/* When building a flake, use pure evaluation (no access to
|
||||
@@ -373,7 +381,8 @@ int main(int argc, char **argv) {
|
||||
std::vector<Thread> threads;
|
||||
std::condition_variable wakeup;
|
||||
for (size_t i = 0; i < myArgs.nrWorkers; i++) {
|
||||
threads.emplace_back(std::bind(collector, std::ref(state_), std::ref(wakeup)));
|
||||
threads.emplace_back(std::bind(collector, std::ref(myArgs),
|
||||
std::ref(state_), std::ref(wakeup)));
|
||||
}
|
||||
|
||||
for (auto &thread : threads)
|
||||
|
||||
+10
-9
@@ -49,8 +49,8 @@ static nix::Value *releaseExprTopLevelValue(nix::EvalState &state,
|
||||
nix::Value vTop;
|
||||
|
||||
if (args.fromArgs) {
|
||||
nix::Expr &e = state.ctx.parseExprFromString(
|
||||
args.releaseExpr, nix::CanonPath::fromCwd());
|
||||
nix::Expr &e = state.ctx.parseExprFromString(args.releaseExpr,
|
||||
nix::CanonPath::fromCwd());
|
||||
state.eval(e, vTop);
|
||||
} else {
|
||||
state.evalFile(nix::lookupFileArg(state.ctx, args.releaseExpr), vTop);
|
||||
@@ -74,18 +74,19 @@ static std::string attrPathJoin(nlohmann::json input) {
|
||||
});
|
||||
}
|
||||
|
||||
void worker(nix::ref<nix::eval_cache::CachingEvaluator> evaluator, nix::Bindings &autoArgs,
|
||||
nix::AutoCloseFD &to, nix::AutoCloseFD &from, MyArgs &args) {
|
||||
void worker(nix::ref<nix::eval_cache::CachingEvaluator> evaluator,
|
||||
nix::Bindings &autoArgs, nix::AutoCloseFD &to,
|
||||
nix::AutoCloseFD &from, MyArgs &args, nix::AsyncIoRoot &aio) {
|
||||
|
||||
nix::Value *vRoot = [&]() {
|
||||
auto state = evaluator->begin();
|
||||
auto state = evaluator->begin(aio);
|
||||
if (args.flake) {
|
||||
auto [flakeRef, fragment, outputSpec] =
|
||||
nix::parseFlakeRefWithFragmentAndExtendedOutputsSpec(
|
||||
args.releaseExpr, nix::absPath("."));
|
||||
nix::InstallableFlake flake{
|
||||
{}, evaluator, std::move(flakeRef), fragment, outputSpec,
|
||||
{}, {}, args.lockFlags};
|
||||
{}, {}, args.lockFlags};
|
||||
|
||||
return flake.toValue(*state).first;
|
||||
} else {
|
||||
@@ -94,7 +95,7 @@ void worker(nix::ref<nix::eval_cache::CachingEvaluator> evaluator, nix::Bindings
|
||||
}();
|
||||
|
||||
LineReader fromReader(from.release());
|
||||
auto state = evaluator->begin();
|
||||
auto state = evaluator->begin(aio);
|
||||
|
||||
while (true) {
|
||||
/* Wait for the collector to send us a job name. */
|
||||
@@ -160,8 +161,8 @@ void worker(nix::ref<nix::eval_cache::CachingEvaluator> evaluator, nix::Bindings
|
||||
|
||||
if (name == "recurseForDerivations" &&
|
||||
!args.forceRecurse) {
|
||||
auto attrv =
|
||||
v->attrs->get(evaluator->s.recurseForDerivations);
|
||||
auto attrv = v->attrs->get(
|
||||
evaluator->s.recurseForDerivations);
|
||||
recurse = state->forceBool(
|
||||
*attrv->value, attrv->pos,
|
||||
"while evaluating recurseForDerivations");
|
||||
|
||||
+5
-3
@@ -2,6 +2,7 @@
|
||||
#include <lix/libmain/shared.hh>
|
||||
#include <lix/libexpr/eval.hh>
|
||||
#include <lix/libexpr/eval-cache.hh>
|
||||
#include <lix/libutil/async.hh>
|
||||
|
||||
#include "eval-args.hh"
|
||||
|
||||
@@ -12,7 +13,8 @@ class AutoCloseFD;
|
||||
class Bindings;
|
||||
class EvalState;
|
||||
template <typename T> class ref;
|
||||
} // namespace nix
|
||||
} // namespace nix
|
||||
|
||||
void worker(nix::ref<nix::eval_cache::CachingEvaluator> evaluator, nix::Bindings &autoArgs,
|
||||
nix::AutoCloseFD &to, nix::AutoCloseFD &from, MyArgs &args);
|
||||
void worker(nix::ref<nix::eval_cache::CachingEvaluator> evaluator,
|
||||
nix::Bindings &autoArgs, nix::AutoCloseFD &to,
|
||||
nix::AutoCloseFD &from, MyArgs &args, nix::AsyncIoRoot &aio);
|
||||
|
||||
Reference in New Issue
Block a user