libstore: de-callback-ify CA realisation substitution

this is the *only* real user of file transfer download completion
callbacks, and a pretty spurious user at that (seeing how nothing
here is even turned on by default and indeed a dependency of path
substitution which *isn't* async, and concurrency-limited). it'll
be a real pain to keep this around, and realistically it would be
a lot better to overhaul substitution in general to be *actually*
async. that requires a proper async framework footing though, and
we don't have anything of the sort, but it's also blocking *that*

Change-Id: I1bf671f217c654a67377087607bf608728cbfc83
This commit is contained in:
eldritch horrors 2024-04-26 18:04:19 +02:00
parent 9ae90612a7
commit 1a002d1a11
2 changed files with 9 additions and 16 deletions

View file

@ -72,25 +72,18 @@ void DrvOutputSubstitutionGoal::tryNext()
sub = subs.front(); sub = subs.front();
subs.pop_front(); subs.pop_front();
// FIXME: Make async /* The async call to a curl download below can outlive `this` (if
// outputInfo = sub->queryRealisation(id);
/* The callback of the curl download below can outlive `this` (if
some other error occurs), so it must not touch `this`. So put some other error occurs), so it must not touch `this`. So put
the shared state in a separate refcounted object. */ the shared state in a separate refcounted object. */
downloadState = std::make_shared<DownloadState>(); downloadState = std::make_shared<DownloadState>();
downloadState->outPipe.create(); downloadState->outPipe.create();
sub->queryRealisation( downloadState->result =
id, std::async(std::launch::async, [downloadState{downloadState}, id{id}, sub{sub}] {
{ [downloadState(downloadState)](std::future<std::shared_ptr<const Realisation>> res) { ReceiveInterrupts receiveInterrupts;
try { Finally updateStats([&]() { downloadState->outPipe.writeSide.close(); });
Finally updateStats([&]() { downloadState->outPipe.writeSide.close(); }); return sub->queryRealisation(id);
downloadState->promise.set_value(res.get()); });
} catch (...) {
downloadState->promise.set_exception(std::current_exception());
}
} });
worker.childStarted(shared_from_this(), {downloadState->outPipe.readSide.get()}, true, false); worker.childStarted(shared_from_this(), {downloadState->outPipe.readSide.get()}, true, false);
@ -103,7 +96,7 @@ void DrvOutputSubstitutionGoal::realisationFetched()
maintainRunningSubstitutions.reset(); maintainRunningSubstitutions.reset();
try { try {
outputInfo = downloadState->promise.get_future().get(); outputInfo = downloadState->result.get();
} catch (std::exception & e) { } catch (std::exception & e) {
printError(e.what()); printError(e.what());
substituterFailed = true; substituterFailed = true;

View file

@ -51,7 +51,7 @@ class DrvOutputSubstitutionGoal : public Goal {
struct DownloadState struct DownloadState
{ {
Pipe outPipe; Pipe outPipe;
std::promise<std::shared_ptr<const Realisation>> promise; std::future<std::shared_ptr<const Realisation>> result;
}; };
std::shared_ptr<DownloadState> downloadState; std::shared_ptr<DownloadState> downloadState;