#pragma once ///@file #include "notifying-counter.hh" #include "store-api.hh" #include "goal.hh" #include "realisation.hh" #include namespace nix { class Worker; /** * Substitution of a derivation output. * This is done in three steps: * 1. Fetch the output info from a substituter * 2. Substitute the corresponding output path * 3. Register the output info */ class DrvOutputSubstitutionGoal : public Goal { /** * The drv output we're trying to substitute */ DrvOutput id; /** * The realisation corresponding to the given output id. * Will be filled once we can get it. */ std::shared_ptr outputInfo; /** * The remaining substituters. */ std::list> subs; /** * The current substituter. */ std::shared_ptr sub; NotifyingCounter::Bump maintainRunningSubstitutions; struct DownloadState { Pipe outPipe; std::future> result; }; std::shared_ptr downloadState; /** * Whether a substituter failed. */ bool substituterFailed = false; public: DrvOutputSubstitutionGoal( const DrvOutput & id, Worker & worker, bool isDependency, RepairFlag repair = NoRepair, std::optional ca = std::nullopt ); typedef kj::Promise> (DrvOutputSubstitutionGoal::*GoalState)(bool inBuildSlot) noexcept; GoalState state; kj::Promise> init(bool inBuildSlot) noexcept; kj::Promise> tryNext(bool inBuildSlot) noexcept; kj::Promise> realisationFetched(bool inBuildSlot) noexcept; kj::Promise> outPathValid(bool inBuildSlot) noexcept; kj::Promise> finished() noexcept; Finished timedOut(Error && ex) override { abort(); }; std::string key() override; kj::Promise> work(bool inBuildSlot) noexcept override; JobCategory jobCategory() const override { return JobCategory::Substitution; }; }; }