From 34b1f362cd696a61367878cc099b55945f0daff8 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sat, 11 Oct 2025 21:59:56 +0200 Subject: [PATCH] libutil: wrap activity updates in macros we'll eventually want to yield to flush buffers from the non-sync versions. Change-Id: I8bcbb1c4c8af39c7d7ebf5a76e1ce1dc98067e00 --- lix/libstore/build/derivation-goal.cc | 4 ++-- lix/libstore/build/worker.cc | 12 +++++----- lix/libstore/optimise-store.cc | 5 +++-- lix/libstore/remote-store.cc | 2 +- lix/libstore/store-api.cc | 21 +++++++++--------- lix/libutil/logging.hh | 32 +++++++++++++++++++++++++++ lix/nix/verify.cc | 11 ++++++--- 7 files changed, 64 insertions(+), 23 deletions(-) diff --git a/lix/libstore/build/derivation-goal.cc b/lix/libstore/build/derivation-goal.cc index 41f068a24..e043c6525 100644 --- a/lix/libstore/build/derivation-goal.cc +++ b/lix/libstore/build/derivation-goal.cc @@ -892,7 +892,7 @@ try { const std::string_view data{buffer.data(), *got}; for (auto c : data) { if (c == '\n') { - act.result(resPostBuildLogLine, currentLine); + ACTIVITY_RESULT(act, resPostBuildLogLine, currentLine); currentLine.clear(); } else { currentLine += c; @@ -902,7 +902,7 @@ try { if (currentLine != "") { currentLine += '\n'; - act.result(resPostBuildLogLine, currentLine); + ACTIVITY_RESULT(act, resPostBuildLogLine, currentLine); } wait.run(); diff --git a/lix/libstore/build/worker.cc b/lix/libstore/build/worker.cc index d7323ba02..ba45f60fe 100644 --- a/lix/libstore/build/worker.cc +++ b/lix/libstore/build/worker.cc @@ -6,6 +6,7 @@ #include "lix/libutil/finally.hh" #include "lix/libstore/build/substitution-goal.hh" #include "lix/libstore/build/local-derivation-goal.hh" +#include "lix/libutil/logging.hh" #include "lix/libutil/signals.hh" #include "lix/libstore/build/hook-instance.hh" // IWYU pragma: keep #include @@ -290,17 +291,18 @@ try { // only update progress info while running. this notably excludes updating // progress info while destroying, which causes the progress bar to assert - actDerivations.progress( - doneBuilds, expectedBuilds + doneBuilds, runningBuilds, failedBuilds + ACTIVITY_PROGRESS( + actDerivations, doneBuilds, expectedBuilds + doneBuilds, runningBuilds, failedBuilds ); - actSubstitutions.progress( + ACTIVITY_PROGRESS( + actSubstitutions, doneSubstitutions, expectedSubstitutions + doneSubstitutions, runningSubstitutions, failedSubstitutions ); - act.setExpected(actFileTransfer, expectedDownloadSize + doneDownloadSize); - act.setExpected(actCopyPath, expectedNarSize + doneNarSize); + ACTIVITY_SET_EXPECTED(act, actFileTransfer, expectedDownloadSize + doneDownloadSize); + ACTIVITY_SET_EXPECTED(act, actCopyPath, expectedNarSize + doneNarSize); // limit to 50fps. that should be more than good enough for anything we do co_await AIO().provider.getTimer().afterDelay(20 * kj::MILLISECONDS); diff --git a/lix/libstore/optimise-store.cc b/lix/libstore/optimise-store.cc index 49c34a1f7..40d70b7c4 100644 --- a/lix/libstore/optimise-store.cc +++ b/lix/libstore/optimise-store.cc @@ -2,6 +2,7 @@ #include "lix/libstore/globals.hh" #include "lix/libutil/async.hh" #include "lix/libutil/c-calls.hh" +#include "lix/libutil/logging.hh" #include "lix/libutil/result.hh" #include "lix/libutil/signals.hh" #include "lix/libutil/strings.hh" @@ -272,7 +273,7 @@ try { auto paths = TRY_AWAIT(queryAllValidPaths()); InodeHash inodeHash = loadInodeHash(); - act.progress(0, paths.size()); + ACTIVITY_PROGRESS(act, 0, paths.size()); uint64_t done = 0; @@ -292,7 +293,7 @@ try { ); } done++; - act.progress(done, paths.size()); + ACTIVITY_PROGRESS(act, done, paths.size()); } co_return result::success(); } catch (...) { diff --git a/lix/libstore/remote-store.cc b/lix/libstore/remote-store.cc index e9aa951f7..317c51d67 100644 --- a/lix/libstore/remote-store.cc +++ b/lix/libstore/remote-store.cc @@ -826,7 +826,7 @@ try { ); continue; } - act->result(type, fields); + ACTIVITY_RESULT(*act, type, fields); } else if (msg == STDERR_LAST) { break; } else { diff --git a/lix/libstore/store-api.cc b/lix/libstore/store-api.cc index e776fc8d2..3472dc66f 100644 --- a/lix/libstore/store-api.cc +++ b/lix/libstore/store-api.cc @@ -332,9 +332,7 @@ try { storePathsToAdd.insert(thingToAdd.first.path); } - auto showProgress = [&]() { - act.progress(nrDone, pathsToCopy.size(), nrRunning, nrFailed); - }; +#define SHOW_PROGRESS() ACTIVITY_PROGRESS(act, nrDone, pathsToCopy.size(), nrRunning, nrFailed) TRY_AWAIT(processGraphAsync( storePathsToAdd, @@ -346,12 +344,12 @@ try { if (TRY_AWAIT(isValidPath(info.path))) { nrDone++; - showProgress(); + SHOW_PROGRESS(); co_return StorePathSet(); } bytesExpected += info.narSize; - act.setExpected(actCopyPath, bytesExpected); + ACTIVITY_SET_EXPECTED(act, actCopyPath, bytesExpected); co_return info.references; } catch (...) { @@ -377,7 +375,7 @@ try { if (!TRY_AWAIT(isValidPath(info.path))) { MaintainCount mc(nrRunning); - showProgress(); + SHOW_PROGRESS(); try { TRY_AWAIT(addToStore(info, *TRY_AWAIT(source()), repair, checkSigs)); } catch (Error & e) { @@ -385,19 +383,22 @@ try { if (!settings.keepGoing) throw e; printMsg(lvlError, "could not copy %s: %s", printStorePath(path), e.what()); - showProgress(); + SHOW_PROGRESS(); co_return result::success(); } } nrDone++; - showProgress(); + SHOW_PROGRESS(); co_return result::success(); } catch (...) { co_return result::current_exception(); } - })); + } + )); co_return result::success(); + +#undef SHOW_PROGRESS } catch (...) { co_return result::current_exception(); } @@ -1007,7 +1008,7 @@ struct CopyPathStream : AsyncInputStream copied += *result; } if (doLog) { - act.progress(copied, expected); + ACTIVITY_PROGRESS(act, copied, expected); } co_return result; } catch (...) { diff --git a/lix/libutil/logging.hh b/lix/libutil/logging.hh index e2c2e496e..9aab120b6 100644 --- a/lix/libutil/logging.hh +++ b/lix/libutil/logging.hh @@ -265,6 +265,38 @@ Logger * makeJSONLogger(Logger & prevLogger); */ extern Verbosity verbosity; +#define ACTIVITY_PROGRESS(act, ...) \ + do { \ + auto && _lix_act = (act); \ + _lix_act.progress(__VA_ARGS__); \ + } while (0) +#define ACTIVITY_RESULT(act, ...) \ + do { \ + auto && _lix_act = (act); \ + _lix_act.result(__VA_ARGS__); \ + } while (0) +#define ACTIVITY_SET_EXPECTED(act, ...) \ + do { \ + auto && _lix_act = (act); \ + _lix_act.setExpected(__VA_ARGS__); \ + } while (0) + +#define ACTIVITY_PROGRESS_SYNC(aio, act, ...) \ + do { \ + auto && _lix_act = (act); \ + _lix_act.progress(__VA_ARGS__); \ + } while (0) +#define ACTIVITY_RESULT_SYNC(aio, act, ...) \ + do { \ + auto && _lix_act = (act); \ + _lix_act.result(__VA_ARGS__); \ + } while (0) +#define ACTIVITY_SET_EXPECTED_SYNC(aio, act, ...) \ + do { \ + auto && _lix_act = (act); \ + _lix_act.setExpected(__VA_ARGS__); \ + } while (0) + /** * Print a message with the standard ErrorInfo format. * In general, use these 'log' macros for reporting problems that may require user diff --git a/lix/nix/verify.cc b/lix/nix/verify.cc index 5334be7f8..7a5b6c051 100644 --- a/lix/nix/verify.cc +++ b/lix/nix/verify.cc @@ -2,6 +2,7 @@ #include "lix/libmain/shared.hh" #include "lix/libstore/store-api.hh" #include "lix/libutil/async.hh" +#include "lix/libutil/logging.hh" #include "lix/libutil/thread-pool.hh" #include "lix/libutil/signals.hh" #include "lix/libutil/exit.hh" @@ -79,7 +80,7 @@ struct CmdVerify : StorePathsCommand std::atomic active{0}; auto update = [&]() { - act.progress(done, storePaths.size(), active, failed); + ACTIVITY_PROGRESS_SYNC(aio(), act, done, storePaths.size(), active, failed); }; ThreadPool pool{"Verify pool"}; @@ -110,7 +111,9 @@ struct CmdVerify : StorePathsCommand if (hash.first != info->narHash) { corrupted++; - act2.result(resCorruptedPath, store->printStorePath(info->path)); + ACTIVITY_RESULT_SYNC( + aio, act2, resCorruptedPath, store->printStorePath(info->path) + ); printError("path '%s' was modified! expected hash '%s', got '%s'", store->printStorePath(info->path), info->narHash.to_string(Base::SRI, true), @@ -163,7 +166,9 @@ struct CmdVerify : StorePathsCommand if (!good) { untrusted++; - act2.result(resUntrustedPath, store->printStorePath(info->path)); + ACTIVITY_RESULT_SYNC( + aio, act2, resUntrustedPath, store->printStorePath(info->path) + ); printError("path '%s' is untrusted", store->printStorePath(info->path)); }