Improve "waiting for locks" messages

These are now shown in the progress bar.

Closes #3577.
This commit is contained in:
Eelco Dolstra 2020-06-15 16:03:29 +02:00
parent e14e62fddd
commit 5ed5d7acbd
3 changed files with 21 additions and 4 deletions

View file

@ -156,7 +156,7 @@ public:
{ {
auto state(state_.lock()); auto state(state_.lock());
if (lvl <= verbosity && !s.empty()) 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());

View file

@ -869,6 +869,9 @@ private:
std::unique_ptr<Activity> act; std::unique_ptr<Activity> act;
/* Activity that denotes waiting for a lock. */
std::unique_ptr<Activity> actLock;
std::map<ActivityId, Activity> builderActivities; std::map<ActivityId, Activity> builderActivities;
/* The remote machine on which we're building. */ /* The remote machine on which we're building. */
@ -1439,10 +1442,15 @@ void DerivationGoal::tryToBuild()
lockFiles.insert(worker.store.Store::toRealPath(outPath)); lockFiles.insert(worker.store.Store::toRealPath(outPath));
if (!outputLocks.lockPaths(lockFiles, "", false)) { if (!outputLocks.lockPaths(lockFiles, "", false)) {
if (!actLock)
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
fmt("waiting for lock on %s", yellowtxt(showPaths(lockFiles))));
worker.waitForAWhile(shared_from_this()); worker.waitForAWhile(shared_from_this());
return; return;
} }
actLock.reset();
/* Now check again whether the outputs are valid. This is because /* Now check again whether the outputs are valid. This is because
another process may have started building in parallel. After another process may have started building in parallel. After
it has finished and released the locks, we can (and should) it has finished and released the locks, we can (and should)
@ -1481,6 +1489,7 @@ void DerivationGoal::tryToBuild()
case rpAccept: case rpAccept:
/* Yes, it has started doing so. Wait until we get /* Yes, it has started doing so. Wait until we get
EOF from the hook. */ EOF from the hook. */
actLock.reset();
result.startTime = time(0); // inexact result.startTime = time(0); // inexact
state = &DerivationGoal::buildDone; state = &DerivationGoal::buildDone;
started(); started();
@ -1488,6 +1497,9 @@ void DerivationGoal::tryToBuild()
case rpPostpone: case rpPostpone:
/* Not now; wait until at least one child finishes or /* Not now; wait until at least one child finishes or
the wake-up timeout expires. */ the wake-up timeout expires. */
if (!actLock)
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
fmt("waiting for a machine to build '%s'", yellowtxt(worker.store.printStorePath(drvPath))));
worker.waitForAWhile(shared_from_this()); worker.waitForAWhile(shared_from_this());
outputLocks.unlock(); outputLocks.unlock();
return; return;
@ -1497,6 +1509,8 @@ void DerivationGoal::tryToBuild()
} }
} }
actLock.reset();
/* Make sure that we are allowed to start a build. If this /* Make sure that we are allowed to start a build. If this
derivation prefers to be done locally, do it even if derivation prefers to be done locally, do it even if
maxBuildJobs is 0. */ maxBuildJobs is 0. */
@ -1524,7 +1538,9 @@ void DerivationGoal::tryLocalBuild() {
uid. */ uid. */
buildUser->kill(); buildUser->kill();
} else { } else {
debug("waiting for build users"); if (!actLock)
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
fmt("waiting for UID to build '%s'", yellowtxt(worker.store.printStorePath(drvPath))));
worker.waitForAWhile(shared_from_this()); worker.waitForAWhile(shared_from_this());
return; return;
} }
@ -1535,6 +1551,8 @@ void DerivationGoal::tryLocalBuild() {
#endif #endif
} }
actLock.reset();
try { try {
/* Okay, we have to build. */ /* Okay, we have to build. */
@ -4863,8 +4881,6 @@ void Worker::waitForInput()
up after a few seconds at most. */ up after a few seconds at most. */
if (!waitingForAWhile.empty()) { if (!waitingForAWhile.empty()) {
useTimeout = true; useTimeout = true;
if (lastWokenUp == steady_time_point::min())
printInfo("waiting for locks, build slots or build users...");
if (lastWokenUp == steady_time_point::min() || lastWokenUp > before) lastWokenUp = before; if (lastWokenUp == steady_time_point::min() || lastWokenUp > before) lastWokenUp = before;
timeout = std::max(1L, timeout = std::max(1L,
(long) std::chrono::duration_cast<std::chrono::seconds>( (long) std::chrono::duration_cast<std::chrono::seconds>(

View file

@ -18,6 +18,7 @@ typedef enum {
actSubstitute = 108, actSubstitute = 108,
actQueryPathInfo = 109, actQueryPathInfo = 109,
actPostBuildHook = 110, actPostBuildHook = 110,
actBuildWaiting = 111,
} ActivityType; } ActivityType;
typedef enum { typedef enum {