repl: respect --print-build-logs

243c0f18d[1] allowed the logger's progress bar to display during repl
builds, but startProgressBar() re-creates the entire logger from
scratch, discarding the value of printBuildLogs. In this commit, we
instead allow the ProgressBar::resume() to re-initialize the state that
ProgressBar::stop() destroys.

Internally, this also allows the progress bar to be entirely stopped and
entirely re-started at any time, without discarding the current logger.

[1]: 243c0f18da

Change-Id: If749a8b41975cb1431be12cad00f2a49da30e7e1
This commit is contained in:
Qyriad 2024-06-14 11:38:30 -06:00
parent 6aead00a01
commit 9cfc88efc0
2 changed files with 33 additions and 15 deletions

View file

@ -622,7 +622,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
// TODO: this only shows a progress bar for explicitly initiated builds,
// not eval-time fetching or builds performed for IFD.
// But we can't just show it everywhere, since that would erase partial output from evaluation.
startProgressBar();
logger->resume();
Finally stopLogger([&]() {
stopProgressBar();
});

View file

@ -82,6 +82,22 @@ private:
bool haveUpdate = true;
};
void createUpdateThread()
{
this->updateThread = std::thread([&]() {
auto state(state_.lock());
auto nextWakeup = A_LONG_TIME;
while (state->active) {
if (!state->haveUpdate) {
state.wait_for(updateCV, nextWakeup);
}
nextWakeup = draw(*state);
state.wait_for(quitCV, std::chrono::milliseconds(50));
}
});
}
Sync<State> state_;
std::thread updateThread;
@ -97,16 +113,7 @@ public:
: isTTY(isTTY)
{
state_.lock()->active = isTTY;
updateThread = std::thread([&]() {
auto state(state_.lock());
auto nextWakeup = A_LONG_TIME;
while (state->active) {
if (!state->haveUpdate)
state.wait_for(updateCV, nextWakeup);
nextWakeup = draw(*state);
state.wait_for(quitCV, std::chrono::milliseconds(50));
}
});
this->createUpdateThread();
}
~ProgressBar()
@ -133,10 +140,21 @@ public:
writeToStderr("\r\e[K");
}
void resume() override {
state_.lock()->paused = false;
writeToStderr("\r\e[K");
state_.lock()->haveUpdate = true;
void resume() override
{
{
auto lockedState(this->state_.lock());
lockedState->paused = false;
writeToStderr("\r\e[K");
lockedState->haveUpdate = true;
}
// We must lock individually here, as createUpdateThread() also locks.
if (!state_.lock()->active) {
state_.lock()->active = true;
this->createUpdateThread();
}
updateCV.notify_one();
}