Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nix
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c507a0393cf1
Choose a base ref
...
head repository: NixOS/nix
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 27ff2665898d
Choose a head ref
  • 3 commits
  • 2 files changed
  • 1 contributor

Commits on Nov 13, 2020

  1. Verified

    This commit was signed with the committer’s verified signature.
    sikmir Nikolay Korotkiy
    Copy the full SHA
    33d1063 View commit details
  2. Show downloads

    edolstra committed Nov 13, 2020
    Copy the full SHA
    1e647f1 View commit details
  3. Fix crash, tweaks

    edolstra committed Nov 13, 2020
    Copy the full SHA
    27ff266 View commit details
Showing with 84 additions and 27 deletions.
  1. +84 −26 src/libmain/progress-bar.cc
  2. +0 −1 src/libstore/build/worker.hh
110 changes: 84 additions & 26 deletions src/libmain/progress-bar.cc
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
#include <map>
#include <thread>
#include <iostream>
#include <chrono>

#include <termios.h>
#include <poll.h>
@@ -60,8 +61,10 @@ class ProgressBar : public Logger
uint64_t failed = 0;
std::map<ActivityType, uint64_t> expectedByType;
bool visible = true;
bool ignored = false;
ActivityId parent;
std::optional<std::string> name;
std::optional<std::chrono::time_point<std::chrono::steady_clock>> startTime;
};

struct ActivitiesByType
@@ -91,11 +94,12 @@ class ProgressBar : public Logger
};

for (auto & j : act.its) {
if (j.second->ignored) continue;
stats.done += j.second->done;
stats.expected += j.second->expected;
stats.running += j.second->running;
stats.failed += j.second->failed;
stats.left += j.second->expected - j.second->done;
stats.left += j.second->expected > j.second->done ? j.second->expected - j.second->done : 0;
}

stats.expected = std::max(stats.expected, act.expected);
@@ -106,9 +110,11 @@ class ProgressBar : public Logger
enum StatusLineGroup {
idHelp,
idEvaluate,
idDownload,
idCopyPaths,
idBuilds,
idStatus
idStatus,
idQuit
};

typedef std::pair<StatusLineGroup, uint16_t> LineId;
@@ -216,8 +222,10 @@ class ProgressBar : public Logger
c = std::tolower(c);

if (c == 3 || c == 'q') {
auto state(state_.lock());
state->statusLines.insert_or_assign({idQuit, 0}, ANSI_RED "Exiting...");
draw(*state);
triggerInterrupt();
break;
}
if (c == 'l') {
auto state(state_.lock());
@@ -389,13 +397,22 @@ class ProgressBar : public Logger
i->s = fmt("querying " ANSI_BOLD "%s" ANSI_NORMAL " on %s", name, getS(fields, 1));
}

if ((type == actFileTransfer && hasAncestor(*state, actCopyPath, parent))
|| (type == actFileTransfer && hasAncestor(*state, actQueryPathInfo, parent))
|| (type == actCopyPath && hasAncestor(*state, actSubstitute, parent))
if (type == actFileTransfer) {
i->s = getS(fields, 0);
if (hasAncestor(*state, actCopyPath, parent)
|| hasAncestor(*state, actQueryPathInfo, parent))
i->ignored = true;
}

if (type == actFileTransfer
|| (type == actCopyPath && hasAncestor(*state, actSubstitute, parent)) // FIXME?
|| type == actBuild
|| type == actSubstitute)
i->visible = false;

if (type == actBuild)
i->startTime = std::chrono::steady_clock::now();

update(*state);
}

@@ -420,11 +437,14 @@ class ProgressBar : public Logger
if (i != state->its.end()) {

auto & actByType = state->activitiesByType[i->second->type];
actByType.done += i->second->done;
actByType.failed += i->second->failed;

for (auto & j : i->second->expectedByType)
state->activitiesByType[j.first].expected -= j.second;
if (!i->second->ignored) {
actByType.done += i->second->done;
actByType.failed += i->second->failed;

for (auto & j : i->second->expectedByType)
state->activitiesByType[j.first].expected -= j.second;
}

actByType.its.erase(act);
state->activities.erase(i->second);
@@ -482,23 +502,27 @@ class ProgressBar : public Logger
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
actInfo.done = getI(fields, 0);
actInfo.expected = getI(fields, 1);
actInfo.running = getI(fields, 2);
actInfo.failed = getI(fields, 3);
update(*state);
if (!actInfo.ignored) {
actInfo.done = getI(fields, 0);
actInfo.expected = getI(fields, 1);
actInfo.running = getI(fields, 2);
actInfo.failed = getI(fields, 3);
update(*state);
}
}

else if (type == resSetExpected) {
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
auto type = (ActivityType) getI(fields, 0);
auto & j = actInfo.expectedByType[type];
state->activitiesByType[type].expected -= j;
j = getI(fields, 1);
state->activitiesByType[type].expected += j;
update(*state);
if (!actInfo.ignored) {
auto type = (ActivityType) getI(fields, 0);
auto & j = actInfo.expectedByType[type];
state->activitiesByType[type].expected -= j;
j = getI(fields, 1);
state->activitiesByType[type].expected += j;
update(*state);
}
}
}

@@ -523,7 +547,8 @@ class ProgressBar : public Logger
}

removeStatusLines(state, idStatus);
state.statusLines.insert_or_assign({idStatus, 0}, line);
if (line != "")
state.statusLines.insert_or_assign({idStatus, 0}, line);

if (state.activitiesByType.count(actEvaluate)) {
if (!state.activitiesByType[actEvaluate].its.empty()) {
@@ -533,7 +558,7 @@ class ProgressBar : public Logger
} else {
// FIXME: evaluation could fail...
state.statusLines.insert_or_assign({idEvaluate, 0},
fmt(ANSI_GREEN "Evaluated"));
fmt(ANSI_GREEN "Evaluating"));
state.statusLines.insert_or_assign({idEvaluate, 1}, "");
}
}
@@ -544,17 +569,45 @@ class ProgressBar : public Logger
auto pct1 = std::min((double) failed / expected, 1.0);
auto pct2 = std::min((double) (failed + done) / expected, 1.0);
auto pct3 = std::min((double) (failed + done + running) / expected, 1.0);
auto barLength = 60;
auto barLength = 70;
size_t chars1 = barLength * pct1;
size_t chars2 = barLength * pct2;
size_t chars3 = barLength * pct3;
assert(chars1 <= chars2);
assert(chars2 <= chars3);
return
ANSI_RED + repeat("", chars1) +
ANSI_GREEN + repeat("", chars2 - chars1) +
ANSI_YELLOW + repeat("", chars3 - chars2) +
ANSI_NORMAL + repeat("", barLength - chars3);
};

auto fileTransfer = getActivityStats(state.activitiesByType[actFileTransfer]);

if (fileTransfer.done || fileTransfer.expected) {
removeStatusLines(state, idDownload);

size_t n = 0;
state.statusLines.insert_or_assign({idDownload, n++},
fmt("%s Downloaded %.1f / %.1f MiB",
fileTransfer.running || fileTransfer.done < fileTransfer.expected
? ANSI_BOLD ""
: ANSI_GREEN "",
//copyPaths.done, copyPaths.expected,
fileTransfer.done / MiB, fileTransfer.expected / MiB));

state.statusLines.insert_or_assign({idDownload, n++},
fmt(" %s", renderBar(fileTransfer.done, 0, fileTransfer.left, fileTransfer.expected)));

for (auto & build : state.activitiesByType[actFileTransfer].its) {
if (build.second->ignored) continue;
state.statusLines.insert_or_assign({idDownload, n++},
fmt(ANSI_BOLD " ‣ %s", build.second->s));
}

state.statusLines.insert_or_assign({idDownload, n++}, "");
}

auto copyPath = getActivityStats(state.activitiesByType[actCopyPath]);
auto copyPaths = getActivityStats(state.activitiesByType[actCopyPaths]);

@@ -565,12 +618,13 @@ class ProgressBar : public Logger

size_t n = 0;
state.statusLines.insert_or_assign({idCopyPaths, n++},
fmt("%s Fetched %d / %d paths, %.1f / %.1f MiB",
fmt("%s Fetched %d / %d store paths, %.1f / %.1f MiB",
copyPaths.running || copyPaths.done < copyPaths.expected
? ANSI_BOLD ""
: ANSI_GREEN "",
copyPaths.done, copyPaths.expected,
copyPath.done / MiB, copyPath.expected / MiB));

state.statusLines.insert_or_assign({idCopyPaths, n++},
fmt(" %s", renderBar(copyPath.done, 0, copyPath.left, copyPath.expected)));

@@ -599,14 +653,18 @@ class ProgressBar : public Logger
builds.done, builds.expected)
+ (builds.running ? fmt(", %d running", builds.running) : "")
+ (builds.failed ? fmt(", %d failed", builds.failed) : ""));

state.statusLines.insert_or_assign({idBuilds, n++},
fmt(" %s",
renderBar(builds.done, builds.failed, builds.running, builds.expected)));

auto now = std::chrono::steady_clock::now();

for (auto & build : state.activitiesByType[actBuild].its) {
state.statusLines.insert_or_assign({idBuilds, n++},
fmt(ANSI_BOLD " ‣ %s%s: %s",
fmt(ANSI_BOLD " ‣ %s (%d s)%s: %s",
build.second->s,
std::chrono::duration_cast<std::chrono::seconds>(now - *build.second->startTime).count(),
build.second->phase ? fmt(" (%s)", *build.second->phase) : "",
build.second->lastLine));
}
1 change: 0 additions & 1 deletion src/libstore/build/worker.hh
Original file line number Diff line number Diff line change
@@ -199,7 +199,6 @@ public:
{
actDerivations.progress(doneBuilds, expectedBuilds + doneBuilds, runningBuilds, failedBuilds);
actSubstitutions.progress(doneSubstitutions, expectedSubstitutions + doneSubstitutions, runningSubstitutions, failedSubstitutions);
act.setExpected(actFileTransfer, expectedDownloadSize + doneDownloadSize);
act.setExpected(actCopyPath, expectedNarSize + doneNarSize);
}
};