summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/computed_roots/evaluate.cpp62
1 files changed, 55 insertions, 7 deletions
diff --git a/src/buildtool/computed_roots/evaluate.cpp b/src/buildtool/computed_roots/evaluate.cpp
index c046297f..5df902fd 100644
--- a/src/buildtool/computed_roots/evaluate.cpp
+++ b/src/buildtool/computed_roots/evaluate.cpp
@@ -342,6 +342,11 @@ void ComputeAndFill(
/// 2.3 If fails, downloads the tree from serve via the remote end point
/// (with a possible rehashing), and runs LOCAL-LOCAL on this tree_structure
/// to make the tree structure available for roots.
+/// 3. (ABSENT-ABSENT) Absent tree of an absent root:
+/// Compute absent tree structure on serve.
+/// 4. (ABSENT-LOCAL): Absent tree structure of a local root:
+/// Perform logic of LOCAL-LOCAL (compute tree structure locally) and
+/// upload the result of computation to serve.
[[nodiscard]] auto ResolveTreeStructureRoot(
TreeStructureRoot const& key,
gsl::not_null<RepositoryConfig*> const& repository_config,
@@ -410,16 +415,19 @@ void ComputeAndFill(
known_repositories.push_back(*path_to_git_cas);
}
+ bool const compute_locally = not key.absent or not ref_root.IsAbsent();
+
std::optional<ArtifactDigest> local_tree_structure;
// Try to compute the tree structure locally:
- if (auto from_local = TreeStructureUtils::ComputeStructureLocally(
- *digest, known_repositories, native_storage_config, git_lock)) {
+ if (compute_locally) {
+ auto from_local = TreeStructureUtils::ComputeStructureLocally(
+ *digest, known_repositories, native_storage_config, git_lock);
+ if (not from_local.has_value()) {
+ // A critical error occurred:
+ return unexpected{std::move(from_local).error()};
+ }
local_tree_structure = *from_local;
}
- else {
- // A critical error occurred:
- return unexpected{std::move(from_local).error()};
- }
// For absent roots ask serve to process the tree:
std::optional<ArtifactDigest> absent_tree_structure;
@@ -440,7 +448,7 @@ void ComputeAndFill(
// Try to process an absent tree structure locally. It might be found in
// CAS or git cache, so there'll be no need to download it from the
// remote end point:
- if (not local_tree_structure.has_value() and
+ if (compute_locally and not local_tree_structure.has_value() and
absent_tree_structure.has_value()) {
if (auto from_local = TreeStructureUtils::ComputeStructureLocally(
*absent_tree_structure,
@@ -490,6 +498,46 @@ void ComputeAndFill(
}
}
+ if (key.absent and absent_tree_structure.has_value()) {
+ Logger::Log(LogLevel::Performance,
+ "Root {} was computed on serve",
+ key.ToString());
+ return FileRoot(absent_tree_structure->hash());
+ }
+
+ if (key.absent and local_tree_structure.has_value()) {
+ if (serve == nullptr) {
+ return unexpected{fmt::format(
+ "No serve end point is given to compute {}", key.ToString())};
+ }
+
+ // Make sure the tree structure is available on serve:
+ auto known = serve->CheckRootTree(local_tree_structure->hash());
+ if (known.has_value() and not *known) {
+ auto uploaded_to_serve =
+ UploadToServe(*serve,
+ *execution_context->apis,
+ *storage_config,
+ *local_tree_structure,
+ native_storage_config.GitRoot());
+ if (not uploaded_to_serve.has_value()) {
+ return unexpected{std::move(uploaded_to_serve).error()};
+ }
+ known = true;
+ }
+
+ if (not known.has_value() or not *known) {
+ return unexpected{
+ fmt::format("Failed to ensure that tree {} is "
+ "available on serve",
+ local_tree_structure->hash())};
+ }
+ Logger::Log(LogLevel::Performance,
+ "Root {} was computed locally and uploaded to serve",
+ key.ToString());
+ return FileRoot(local_tree_structure->hash());
+ }
+
if (local_tree_structure.has_value()) {
auto resolved_root = FileRoot::FromGit(native_storage_config.GitRoot(),
local_tree_structure->hash());