mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 08:16:15 +02:00
nix copy: Revive progress bar
This commit is contained in:
parent
dffc3fe43b
commit
c5e4404580
6 changed files with 99 additions and 2 deletions
|
@ -135,7 +135,6 @@ struct LegacySSHStore : public Store
|
|||
|
||||
if (readInt(conn->from) != 1)
|
||||
throw Error("failed to add path '%s' to remote host '%s', info.path, host");
|
||||
|
||||
}
|
||||
|
||||
void narFromPath(const Path & path, Sink & sink) override
|
||||
|
|
|
@ -565,8 +565,12 @@ void Store::buildPaths(const PathSet & paths, BuildMode buildMode)
|
|||
void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
|
||||
const Path & storePath, RepairFlag repair, CheckSigsFlag checkSigs)
|
||||
{
|
||||
Activity act(actCopyPath, fmt("copying path '%s'", storePath));
|
||||
|
||||
auto info = srcStore->queryPathInfo(storePath);
|
||||
|
||||
//act->progress(0, info->size());
|
||||
|
||||
StringSink sink;
|
||||
srcStore->narFromPath({storePath}, sink);
|
||||
|
||||
|
@ -600,13 +604,28 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePa
|
|||
for (auto & path : storePaths)
|
||||
if (!valid.count(path)) missing.insert(path);
|
||||
|
||||
Activity act;
|
||||
|
||||
logger->event(evCopyStarted, act);
|
||||
|
||||
std::atomic<size_t> nrCopied{0};
|
||||
std::atomic<size_t> nrDone{storePaths.size() - missing.size()};
|
||||
|
||||
auto showProgress = [&]() {
|
||||
logger->event(evCopyProgress, act, storePaths.size(), nrCopied, nrDone);
|
||||
};
|
||||
|
||||
ThreadPool pool;
|
||||
|
||||
processGraph<Path>(pool,
|
||||
PathSet(missing.begin(), missing.end()),
|
||||
|
||||
[&](const Path & storePath) {
|
||||
if (dstStore->isValidPath(storePath)) return PathSet();
|
||||
if (dstStore->isValidPath(storePath)) {
|
||||
nrDone++;
|
||||
showProgress();
|
||||
return PathSet();
|
||||
}
|
||||
return srcStore->queryPathInfo(storePath)->references;
|
||||
},
|
||||
|
||||
|
@ -616,7 +635,12 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePa
|
|||
if (!dstStore->isValidPath(storePath)) {
|
||||
printInfo("copying '%s'...", storePath);
|
||||
copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
|
||||
nrCopied++;
|
||||
}
|
||||
|
||||
nrDone++;
|
||||
|
||||
showProgress();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ static void dumpContents(const Path & path, size_t size,
|
|||
|
||||
static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path '%1%'") % path);
|
||||
|
|
|
@ -80,4 +80,15 @@ std::atomic<uint64_t> nextId{(uint64_t) getpid() << 32};
|
|||
|
||||
Activity::Activity() : id(nextId++) { };
|
||||
|
||||
Activity::Activity(ActivityType type, std::string msg)
|
||||
: Activity()
|
||||
{
|
||||
logger->event(evStartActivity, id, msg);
|
||||
}
|
||||
|
||||
Activity::~Activity()
|
||||
{
|
||||
logger->event(evStopActivity, id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ typedef enum {
|
|||
lvlVomit
|
||||
} Verbosity;
|
||||
|
||||
typedef enum {
|
||||
actCopyPath = 100,
|
||||
} ActivityType;
|
||||
|
||||
class Activity
|
||||
{
|
||||
public:
|
||||
|
@ -21,6 +25,10 @@ public:
|
|||
Activity();
|
||||
Activity(const Activity & act) : id(act.id) { };
|
||||
Activity(uint64_t id) : id(id) { };
|
||||
Activity(ActivityType type, std::string msg = "");
|
||||
~Activity();
|
||||
|
||||
//void progress(...);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -35,6 +43,13 @@ typedef enum {
|
|||
evSubstitutionCreated = 8,
|
||||
evSubstitutionStarted = 9,
|
||||
evSubstitutionFinished = 10,
|
||||
|
||||
evCopyStarted = 100,
|
||||
evCopyProgress = 101,
|
||||
|
||||
evStartActivity = 1000,
|
||||
evStopActivity = 1001,
|
||||
|
||||
} EventType;
|
||||
|
||||
struct Event
|
||||
|
|
|
@ -27,17 +27,29 @@ private:
|
|||
DownloadInfo(const std::string & uri) : uri(uri) { }
|
||||
};
|
||||
|
||||
struct CopyInfo
|
||||
{
|
||||
uint64_t expected = 0;
|
||||
uint64_t copied = 0;
|
||||
uint64_t done = 0;
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
std::map<Activity::t, Path> builds;
|
||||
std::set<Activity::t> runningBuilds;
|
||||
uint64_t succeededBuilds = 0;
|
||||
uint64_t failedBuilds = 0;
|
||||
|
||||
std::map<Activity::t, Path> substitutions;
|
||||
std::set<Activity::t> runningSubstitutions;
|
||||
uint64_t succeededSubstitutions = 0;
|
||||
|
||||
uint64_t downloadedBytes = 0; // finished downloads
|
||||
std::map<Activity::t, DownloadInfo> downloads;
|
||||
|
||||
std::map<Activity::t, CopyInfo> runningCopies;
|
||||
|
||||
std::list<ActInfo> activities;
|
||||
std::map<Activity::t, std::list<ActInfo>::iterator> its;
|
||||
};
|
||||
|
@ -167,11 +179,35 @@ public:
|
|||
res += fmt("%1$.0f/%2$.0f KiB", current / 1024.0, expected / 1024.0);
|
||||
}
|
||||
|
||||
if (!state.runningCopies.empty()) {
|
||||
if (!res.empty()) res += ", ";
|
||||
uint64_t copied = 0, expected = 0;
|
||||
for (auto & i : state.runningCopies) {
|
||||
copied += i.second.copied;
|
||||
expected += i.second.expected - (i.second.done - i.second.copied);
|
||||
}
|
||||
res += fmt("%d/%d copied", copied, expected);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void event(const Event & ev) override
|
||||
{
|
||||
if (ev.type == evStartActivity) {
|
||||
auto state(state_.lock());
|
||||
Activity::t act = ev.getI(0);
|
||||
createActivity(*state, act, ev.getS(1));
|
||||
update(*state);
|
||||
}
|
||||
|
||||
if (ev.type == evStopActivity) {
|
||||
auto state(state_.lock());
|
||||
Activity::t act = ev.getI(0);
|
||||
deleteActivity(*state, act);
|
||||
update(*state);
|
||||
}
|
||||
|
||||
if (ev.type == evBuildCreated) {
|
||||
auto state(state_.lock());
|
||||
state->builds[ev.getI(0)] = ev.getS(1);
|
||||
|
@ -280,6 +316,16 @@ public:
|
|||
update(*state);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.type == evCopyProgress) {
|
||||
auto state(state_.lock());
|
||||
Activity::t act = ev.getI(0);
|
||||
auto & i = state->runningCopies[act];
|
||||
i.expected = ev.getI(1);
|
||||
i.copied = ev.getI(2);
|
||||
i.done = ev.getI(3);
|
||||
update(*state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue