aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-09-30 01:31:30 +0200
committereldritch horrors <pennae@lix.systems>2024-10-01 11:36:45 +0000
commitd5db0b1abc1809ad97fa28b82056b19c4a45710a (patch)
tree4cad72d306db586912b40726414916b730e04826
parentb0c7c1ec664415d451dcd56d2982b369c0c33892 (diff)
libstore: turn periodic gc attempt into a promise
notably we will check whether we want to do GC at all only once during startup, and we'll only attempt GC every ten seconds rather than every time a goal has finished a partial work call. this shouldn't cause any problems in practice since relying on auto-gc is not deterministic and stores in which builds can fill all remaining free space in merely ten seconds are severely troubled even when gargage collection runs a lot. Change-Id: I1175a56bf7f4e531f8be90157ad88750ff2ddec4
-rw-r--r--src/libstore/build/worker.cc36
-rw-r--r--src/libstore/build/worker.hh2
2 files changed, 22 insertions, 16 deletions
diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc
index 8ab7fcc86..e9904a1f5 100644
--- a/src/libstore/build/worker.cc
+++ b/src/libstore/build/worker.cc
@@ -298,6 +298,13 @@ std::vector<GoalPtr> Worker::run(std::function<Targets (GoalFactory &)> req)
}
auto promise = runImpl();
+
+ // TODO GC interface?
+ if (auto localStore = dynamic_cast<LocalStore *>(&store); localStore && settings.minFree != 0) {
+ // Periodically wake up to see if we need to run the garbage collector.
+ promise = promise.exclusiveJoin(boopGC(*localStore));
+ }
+
promise.wait(aio.waitScope).value();
std::vector<GoalPtr> results;
@@ -315,10 +322,6 @@ try {
checkInterrupt();
- // TODO GC interface?
- if (auto localStore = dynamic_cast<LocalStore *>(&store))
- localStore->autoGC(false);
-
/* Call every wake goal (in the ordering established by
CompareGoalPtrs). */
while (!awake.empty() && !topGoals.empty()) {
@@ -356,22 +359,23 @@ try {
co_return result::failure(std::current_exception());
}
+kj::Promise<Result<void>> Worker::boopGC(LocalStore & localStore)
+try {
+ while (true) {
+ co_await aio.provider->getTimer().afterDelay(10 * kj::SECONDS);
+ localStore.autoGC(false);
+ }
+} catch (...) {
+ co_return result::failure(std::current_exception());
+}
+
kj::Promise<Result<void>> Worker::waitForInput()
try {
printMsg(lvlVomit, "waiting for children");
- auto waitFor = [&]{
- auto pair = kj::newPromiseAndFulfiller<void>();
- this->childFinished = kj::mv(pair.fulfiller);
- return kj::mv(pair.promise);
- }();
-
- if (settings.minFree.get() != 0) {
- // Periodicallty wake up to see if we need to run the garbage collector.
- waitFor = waitFor.exclusiveJoin(aio.provider->getTimer().afterDelay(10 * kj::SECONDS));
- }
-
- co_await waitFor;
+ auto pair = kj::newPromiseAndFulfiller<void>();
+ this->childFinished = kj::mv(pair.fulfiller);
+ co_await pair.promise;
co_return result::success();
} catch (...) {
co_return result::failure(std::current_exception());
diff --git a/src/libstore/build/worker.hh b/src/libstore/build/worker.hh
index 6da76fe34..dc85c43e3 100644
--- a/src/libstore/build/worker.hh
+++ b/src/libstore/build/worker.hh
@@ -20,6 +20,7 @@ namespace nix {
struct DerivationGoal;
struct PathSubstitutionGoal;
class DrvOutputSubstitutionGoal;
+class LocalStore;
typedef std::chrono::time_point<std::chrono::steady_clock> steady_time_point;
@@ -189,6 +190,7 @@ private:
}
kj::Promise<Result<void>> runImpl();
+ kj::Promise<Result<void>> boopGC(LocalStore & localStore);
public: