#pragma once ///@file #include "lock.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::thread thr; std::promise promise; /** * 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; std::unique_ptr> maintainExpectedSubstitutions, maintainRunningSubstitutions, maintainExpectedNar, maintainExpectedDownload; typedef void (PathSubstitutionGoal::*GoalState)(); GoalState state; /** * Content address for recomputing store path */ std::optional ca; void done( ExitCode result, BuildResult::Status status, std::optional errorMsg = {}); public: PathSubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair, std::optional ca = std::nullopt); ~PathSubstitutionGoal(); void 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); } void work() override; /** * The states. */ void init(); void tryNext(); void gotInfo(); void referencesValid(); void tryToRun(); void finished(); /** * Callback used by the worker to write to the log. */ void handleChildOutput(int fd, std::string_view data) override; void handleEOF(int fd) override; void cleanup() override; }; }