diff options
author | eldritch horrors <pennae@lix.systems> | 2024-09-30 01:31:30 +0200 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-10-01 11:36:45 +0000 |
commit | d5db0b1abc1809ad97fa28b82056b19c4a45710a (patch) | |
tree | 4cad72d306db586912b40726414916b730e04826 /src/libstore/build/worker.cc | |
parent | b0c7c1ec664415d451dcd56d2982b369c0c33892 (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
Diffstat (limited to 'src/libstore/build/worker.cc')
-rw-r--r-- | src/libstore/build/worker.cc | 36 |
1 files changed, 20 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()); |