forked from lix-project/lix
Merge pull request #6913 from edolstra/lazy-trees-cherrypicks
lazy-trees cherrypicks
This commit is contained in:
commit
84cc7ad77c
|
@ -616,6 +616,8 @@ InstallableFlake::InstallableFlake(
|
||||||
|
|
||||||
std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableFlake::toDerivation()
|
std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableFlake::toDerivation()
|
||||||
{
|
{
|
||||||
|
Activity act(*logger, lvlTalkative, actUnknown, fmt("evaluating derivation '%s'", what()));
|
||||||
|
|
||||||
auto attr = getCursor(*state);
|
auto attr = getCursor(*state);
|
||||||
|
|
||||||
auto attrPath = attr->getAttrPathStr();
|
auto attrPath = attr->getAttrPathStr();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ private:
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
ActivityId parent;
|
ActivityId parent;
|
||||||
std::optional<std::string> name;
|
std::optional<std::string> name;
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> startTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ActivitiesByType
|
struct ActivitiesByType
|
||||||
|
@ -91,10 +93,11 @@ public:
|
||||||
state_.lock()->active = isTTY;
|
state_.lock()->active = isTTY;
|
||||||
updateThread = std::thread([&]() {
|
updateThread = std::thread([&]() {
|
||||||
auto state(state_.lock());
|
auto state(state_.lock());
|
||||||
|
auto nextWakeup = std::chrono::milliseconds::max();
|
||||||
while (state->active) {
|
while (state->active) {
|
||||||
if (!state->haveUpdate)
|
if (!state->haveUpdate)
|
||||||
state.wait(updateCV);
|
state.wait_for(updateCV, nextWakeup);
|
||||||
draw(*state);
|
nextWakeup = draw(*state);
|
||||||
state.wait_for(quitCV, std::chrono::milliseconds(50));
|
state.wait_for(quitCV, std::chrono::milliseconds(50));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -118,7 +121,8 @@ public:
|
||||||
updateThread.join();
|
updateThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVerbose() override {
|
bool isVerbose() override
|
||||||
|
{
|
||||||
return printBuildLogs;
|
return printBuildLogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,11 +163,13 @@ public:
|
||||||
if (lvl <= verbosity && !s.empty() && type != actBuildWaiting)
|
if (lvl <= verbosity && !s.empty() && type != actBuildWaiting)
|
||||||
log(*state, lvl, s + "...");
|
log(*state, lvl, s + "...");
|
||||||
|
|
||||||
state->activities.emplace_back(ActInfo());
|
state->activities.emplace_back(ActInfo {
|
||||||
|
.s = s,
|
||||||
|
.type = type,
|
||||||
|
.parent = parent,
|
||||||
|
.startTime = std::chrono::steady_clock::now()
|
||||||
|
});
|
||||||
auto i = std::prev(state->activities.end());
|
auto i = std::prev(state->activities.end());
|
||||||
i->s = s;
|
|
||||||
i->type = type;
|
|
||||||
i->parent = parent;
|
|
||||||
state->its.emplace(act, i);
|
state->its.emplace(act, i);
|
||||||
state->activitiesByType[type].its.emplace(act, i);
|
state->activitiesByType[type].its.emplace(act, i);
|
||||||
|
|
||||||
|
@ -327,10 +333,12 @@ public:
|
||||||
updateCV.notify_one();
|
updateCV.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(State & state)
|
std::chrono::milliseconds draw(State & state)
|
||||||
{
|
{
|
||||||
|
auto nextWakeup = std::chrono::milliseconds::max();
|
||||||
|
|
||||||
state.haveUpdate = false;
|
state.haveUpdate = false;
|
||||||
if (!state.active) return;
|
if (!state.active) return nextWakeup;
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
|
@ -341,12 +349,25 @@ public:
|
||||||
line += "]";
|
line += "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
if (!state.activities.empty()) {
|
if (!state.activities.empty()) {
|
||||||
if (!status.empty()) line += " ";
|
if (!status.empty()) line += " ";
|
||||||
auto i = state.activities.rbegin();
|
auto i = state.activities.rbegin();
|
||||||
|
|
||||||
while (i != state.activities.rend() && (!i->visible || (i->s.empty() && i->lastLine.empty())))
|
while (i != state.activities.rend()) {
|
||||||
|
if (i->visible && (!i->s.empty() || !i->lastLine.empty())) {
|
||||||
|
/* Don't show activities until some time has
|
||||||
|
passed, to avoid displaying very short
|
||||||
|
activities. */
|
||||||
|
auto delay = std::chrono::milliseconds(10);
|
||||||
|
if (i->startTime + delay < now)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
nextWakeup = std::min(nextWakeup, std::chrono::duration_cast<std::chrono::milliseconds>(delay - (now - i->startTime)));
|
||||||
|
}
|
||||||
++i;
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
if (i != state.activities.rend()) {
|
if (i != state.activities.rend()) {
|
||||||
line += i->s;
|
line += i->s;
|
||||||
|
@ -366,6 +387,8 @@ public:
|
||||||
if (width <= 0) width = std::numeric_limits<decltype(width)>::max();
|
if (width <= 0) width = std::numeric_limits<decltype(width)>::max();
|
||||||
|
|
||||||
writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K");
|
writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K");
|
||||||
|
|
||||||
|
return nextWakeup;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getStatus(State & state)
|
std::string getStatus(State & state)
|
||||||
|
|
|
@ -580,7 +580,6 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
conn->to.written = 0;
|
conn->to.written = 0;
|
||||||
conn->to.warn = true;
|
|
||||||
connections->incCapacity();
|
connections->incCapacity();
|
||||||
{
|
{
|
||||||
Finally cleanup([&]() { connections->decCapacity(); });
|
Finally cleanup([&]() { connections->decCapacity(); });
|
||||||
|
@ -591,7 +590,6 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
|
||||||
dumpString(contents, conn->to);
|
dumpString(contents, conn->to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn->to.warn = false;
|
|
||||||
conn.processStderr();
|
conn.processStderr();
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
/* Daemon closed while we were sending the path. Probably OOM
|
/* Daemon closed while we were sending the path. Probably OOM
|
||||||
|
|
|
@ -48,24 +48,9 @@ FdSink::~FdSink()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t threshold = 256 * 1024 * 1024;
|
|
||||||
|
|
||||||
static void warnLargeDump()
|
|
||||||
{
|
|
||||||
warn("dumping very large path (> 256 MiB); this may run out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FdSink::write(std::string_view data)
|
void FdSink::write(std::string_view data)
|
||||||
{
|
{
|
||||||
written += data.size();
|
written += data.size();
|
||||||
static bool warned = false;
|
|
||||||
if (warn && !warned) {
|
|
||||||
if (written > threshold) {
|
|
||||||
warnLargeDump();
|
|
||||||
warned = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
writeFull(fd, data);
|
writeFull(fd, data);
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
|
@ -448,11 +433,6 @@ Error readError(Source & source)
|
||||||
|
|
||||||
void StringSink::operator () (std::string_view data)
|
void StringSink::operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
static bool warned = false;
|
|
||||||
if (!warned && s.size() > threshold) {
|
|
||||||
warnLargeDump();
|
|
||||||
warned = true;
|
|
||||||
}
|
|
||||||
s.append(data);
|
s.append(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,19 +97,17 @@ protected:
|
||||||
struct FdSink : BufferedSink
|
struct FdSink : BufferedSink
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
bool warn = false;
|
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
FdSink() : fd(-1) { }
|
FdSink() : fd(-1) { }
|
||||||
FdSink(int fd) : fd(fd) { }
|
FdSink(int fd) : fd(fd) { }
|
||||||
FdSink(FdSink&&) = default;
|
FdSink(FdSink&&) = default;
|
||||||
|
|
||||||
FdSink& operator=(FdSink && s)
|
FdSink & operator=(FdSink && s)
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
fd = s.fd;
|
fd = s.fd;
|
||||||
s.fd = -1;
|
s.fd = -1;
|
||||||
warn = s.warn;
|
|
||||||
written = s.written;
|
written = s.written;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,8 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
|
||||||
ANSI_BOLD "Last modified:" ANSI_NORMAL " %s",
|
ANSI_BOLD "Last modified:" ANSI_NORMAL " %s",
|
||||||
std::put_time(std::localtime(&*lastModified), "%F %T"));
|
std::put_time(std::localtime(&*lastModified), "%F %T"));
|
||||||
|
|
||||||
logger->cout(ANSI_BOLD "Inputs:" ANSI_NORMAL);
|
if (!lockedFlake.lockFile.root->inputs.empty())
|
||||||
|
logger->cout(ANSI_BOLD "Inputs:" ANSI_NORMAL);
|
||||||
|
|
||||||
std::unordered_set<std::shared_ptr<Node>> visited;
|
std::unordered_set<std::shared_ptr<Node>> visited;
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ fi
|
||||||
onError() {
|
onError() {
|
||||||
set +x
|
set +x
|
||||||
echo "$0: test failed at:" >&2
|
echo "$0: test failed at:" >&2
|
||||||
for ((i = 1; i < 16; i++)); do
|
for ((i = 1; i < ${#BASH_SOURCE[@]}; i++)); do
|
||||||
if [[ -z ${BASH_SOURCE[i]} ]]; then break; fi
|
if [[ -z ${BASH_SOURCE[i]} ]]; then break; fi
|
||||||
echo " ${FUNCNAME[i]} in ${BASH_SOURCE[i]}:${BASH_LINENO[i-1]}" >&2
|
echo " ${FUNCNAME[i]} in ${BASH_SOURCE[i]}:${BASH_LINENO[i-1]}" >&2
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in a new issue