diff options
Diffstat (limited to 'src/libstore/build/worker.hh')
-rw-r--r-- | src/libstore/build/worker.hh | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/src/libstore/build/worker.hh b/src/libstore/build/worker.hh index 1a913ca16..369e58b41 100644 --- a/src/libstore/build/worker.hh +++ b/src/libstore/build/worker.hh @@ -85,8 +85,40 @@ protected: class Worker : public WorkerBase { public: - using Targets = std::map<GoalPtr, kj::Promise<Result<Goal::WorkResult>>>; - using Results = std::map<GoalPtr, Goal::WorkResult>; + using Targets = std::vector<std::pair<GoalPtr, kj::Promise<Result<Goal::WorkResult>>>>; + struct Results { + /** Results of individual goals, if available. Goal results will be + * added to this map with the index they had in the `Targets` list + * returned by the goal factory function passed to `work`. If some + * goals did not complete processing, e.g. due to an early exit on + * goal failures, not all indices will be set. This may be used to + * detect which of the goals were cancelled before they completed. + */ + std::map<size_t, Goal::WorkResult> goals; + + /** + * The exit status in case of failure. + * + * In the case of a build failure, returned value follows this + * bitmask: + * + * ``` + * 0b1100100 + * ^^^^ + * |||`- timeout + * ||`-- output hash mismatch + * |`--- build failure + * `---- not deterministic + * ``` + * + * In other words, the failure code is at least 100 (0b1100100), but + * might also be greater. + * + * Otherwise (no build failure, but some other sort of failure by + * assumption), this returned value is 1. + */ + unsigned int failingExitStatus; + }; private: @@ -192,6 +224,7 @@ public: NotifyingCounter<uint64_t> expectedNarSize{[this] { updateStatisticsLater(); }}; NotifyingCounter<uint64_t> doneNarSize{[this] { updateStatisticsLater(); }}; +private: Worker(Store & store, Store & evalStore, kj::AsyncIoContext & aio); ~Worker(); @@ -202,7 +235,6 @@ public: /** * @ref DerivationGoal "derivation goal" */ -private: template<typename ID, std::derived_from<Goal> G> std::pair<std::shared_ptr<G>, kj::Promise<Result<Goal::WorkResult>>> makeGoalCommon( std::map<ID, CachedGoal<G>> & map, @@ -246,30 +278,7 @@ public: /** * Loop until the specified top-level goals have finished. */ - Results run(std::function<Targets (GoalFactory &)> req); - - /*** - * The exit status in case of failure. - * - * In the case of a build failure, returned value follows this - * bitmask: - * - * ``` - * 0b1100100 - * ^^^^ - * |||`- timeout - * ||`-- output hash mismatch - * |`--- build failure - * `---- not deterministic - * ``` - * - * In other words, the failure code is at least 100 (0b1100100), but - * might also be greater. - * - * Otherwise (no build failure, but some other sort of failure by - * assumption), this returned value is 1. - */ - unsigned int failingExitStatus(); + kj::Promise<Result<Results>> run(std::function<Targets (GoalFactory &)> req); /** * Check whether the given valid path exists and has the right @@ -278,6 +287,20 @@ public: bool pathContentsGood(const StorePath & path); void markContentsGood(const StorePath & path); + + template<typename MkGoals> + friend kj::Promise<Result<Results>> processGoals( + Store & store, Store & evalStore, kj::AsyncIoContext & aio, MkGoals && mkGoals + ) noexcept; }; +template<typename MkGoals> +kj::Promise<Result<Worker::Results>> processGoals( + Store & store, Store & evalStore, kj::AsyncIoContext & aio, MkGoals && mkGoals +) noexcept +try { + co_return co_await Worker(store, evalStore, aio).run(std::forward<MkGoals>(mkGoals)); +} catch (...) { + co_return result::failure(std::current_exception()); +} } |