#pragma once ///@file #include "lock.hh" #include "notifying-counter.hh" #include "store-api.hh" #include "goal.hh" namespace nix { class Worker; struct PathSubstitutionGoal : public Goal { /** * The store path that should be realised through a substitute. */ StorePath storePath; /** * The path the substituter refers to the path as. This will be * different when the stores have different names. */ std::optional subPath; /** * The remaining substituters. */ std::list> subs; /** * The current substituter. */ std::shared_ptr sub; /** * Whether a substituter failed. */ bool substituterFailed = false; /** * Path info returned by the substituter's query info operation. */ std::shared_ptr info; /** * Pipe for the substituter's standard output. */ Pipe outPipe; /** * The substituter thread. */ std::future thr; /** * Whether to try to repair a valid path. */ RepairFlag repair; /** * Location where we're downloading the substitute. Differs from * storePath when doing a repair. */ Path destPath; NotifyingCounter::Bump maintainExpectedSubstitutions, maintainRunningSubstitutions, maintainExpectedNar, maintainExpectedDownload; typedef kj::Promise> (PathSubstitutionGoal::*GoalState)(bool inBuildSlot) noexcept; GoalState state; /** * Content address for recomputing store path */ std::optional ca; Finished done( ExitCode result, BuildResult::Status status, std::optional errorMsg = {}); public: PathSubstitutionGoal( const StorePath & storePath, Worker & worker, bool isDependency, RepairFlag repair = NoRepair, std::optional ca = std::nullopt ); ~PathSubstitutionGoal(); Finished timedOut(Error && ex) override { abort(); }; /** * We prepend "a$" to the key name to ensure substitution goals * happen before derivation goals. */ std::string key() override { return "a$" + std::string(storePath.name()) + "$" + worker.store.printStorePath(storePath); } kj::Promise> work(bool inBuildSlot) noexcept override; /** * The states. */ kj::Promise> init(bool inBuildSlot) noexcept; kj::Promise> tryNext(bool inBuildSlot) noexcept; kj::Promise> referencesValid(bool inBuildSlot) noexcept; kj::Promise> tryToRun(bool inBuildSlot) noexcept; kj::Promise> finished(bool inBuildSlot) noexcept; /** * Callback used by the worker to write to the log. */ WorkResult handleChildOutput(int fd, std::string_view data) override; /* Called by destructor, can't be overridden */ void cleanup() override final; JobCategory jobCategory() const override { return JobCategory::Substitution; }; }; }