aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/worker.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build/worker.hh')
-rw-r--r--src/libstore/build/worker.hh77
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());
+}
}