From 492659714db1961daae65020e421d68db60ca3d2 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Tue, 25 Feb 2025 22:13:19 +0100 Subject: [PATCH] libstore: account path copy progress with new source type generators are nice, but they can't be made async. narFromPath will eventually have to be made async. we just can't win with this stuff Change-Id: Ia24727893be0001491e232ea27a09cc921b1c935 --- lix/libstore/store-api.cc | 102 +++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/lix/libstore/store-api.cc b/lix/libstore/store-api.cc index 7a51d3611..728caee16 100644 --- a/lix/libstore/store-api.cc +++ b/lix/libstore/store-api.cc @@ -1082,9 +1082,29 @@ static std::string makeCopyPathMessage( } -// buffer size for path copy progress reporting. should be large enough to not cause excessive -// overhead during copies, but small enough to provide reasonably quick copy progress updates. -static constexpr unsigned PATH_COPY_BUFSIZE = 65536; +namespace { +struct CopyPathSource : Source +{ + Activity & act; + size_t copied = 0, expected; + box_ptr inner; + + CopyPathSource(Activity & act, size_t expected, box_ptr inner) + : act(act) + , expected(expected) + , inner(std::move(inner)) + { + } + + size_t read(char * data, size_t len) override + { + auto result = inner->read(data, len); + copied += result; + act.progress(copied, expected); + return result; + } +}; +} kj::Promise> copyStorePath( Store & srcStore, @@ -1125,24 +1145,7 @@ try { info = info2; } - GeneratorSource source{ - [](auto & act, auto & info, auto & srcStore, auto & storePath) -> WireFormatGenerator { - auto nar = srcStore.narFromPath(storePath); - auto buf = std::make_unique(PATH_COPY_BUFSIZE); - uint64_t total = 0; - while (true) { - try { - auto got = nar->read(buf.get(), PATH_COPY_BUFSIZE); - total += got; - act.progress(total, info->narSize); - co_yield std::span{buf.get(), got}; - } catch (EndOfFile &) { - break; - } - } - }(act, info, srcStore, storePath) - }; - + CopyPathSource source{act, info->narSize, srcStore.narFromPath(storePath)}; TRY_AWAIT(dstStore.addToStore(*info, source, repair, checkSigs)); co_return result::success(); } catch (...) { @@ -1260,38 +1263,33 @@ try { ValidPathInfo infoForDst = *info; infoForDst.path = storePathForDst; - auto source = [&srcStore, &dstStore, missingPath, info] { - auto content = [](auto & srcStore, auto & dstStore, auto missingPath, auto info - ) -> WireFormatGenerator { - // We can reasonably assume that the copy will happen whenever we - // read the path, so log something about that at that point - auto srcUri = srcStore.getUri(); - auto dstUri = dstStore.getUri(); - auto storePathS = srcStore.printStorePath(missingPath); - Activity act( - *logger, - lvlInfo, - actCopyPath, - makeCopyPathMessage(srcUri, dstUri, storePathS), - {storePathS, srcUri, dstUri} - ); - PushActivity pact(act.id); + struct SinglePathSource : CopyPathSource + { + Activity act; + PushActivity pact{act.id}; - auto nar = srcStore.narFromPath(missingPath); - auto buf = std::make_unique(PATH_COPY_BUFSIZE); - uint64_t total = 0; - while (true) { - try { - auto got = nar->read(buf.get(), PATH_COPY_BUFSIZE); - total += got; - act.progress(total, info->narSize); - co_yield std::span{buf.get(), got}; - } catch (EndOfFile &) { - break; - } - } - }; - return make_box_ptr(content(srcStore, dstStore, missingPath, info)); + SinglePathSource( + std::string message, Logger::Fields fields, size_t expected, box_ptr inner + ) + : CopyPathSource(act, expected, std::move(inner)) + , act(*logger, lvlInfo, actCopyPath, message, fields) + { + } + }; + + auto source = [&srcStore, &dstStore, missingPath, info] { + // We can reasonably assume that the copy will happen whenever we + // read the path, so log something about that at that point + auto srcUri = srcStore.getUri(); + auto dstUri = dstStore.getUri(); + auto storePathS = srcStore.printStorePath(missingPath); + + return make_box_ptr( + makeCopyPathMessage(srcUri, dstUri, storePathS), + Logger::Fields{storePathS, srcUri, dstUri}, + info->narSize, + srcStore.narFromPath(missingPath) + ); }; pathsToCopy.push_back(std::pair{infoForDst, std::move(source)}); }