summaryrefslogtreecommitdiff
path: root/src/buildtool/computed_roots/evaluate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildtool/computed_roots/evaluate.cpp')
-rw-r--r--src/buildtool/computed_roots/evaluate.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/buildtool/computed_roots/evaluate.cpp b/src/buildtool/computed_roots/evaluate.cpp
index 5df902fd..ebcbed8a 100644
--- a/src/buildtool/computed_roots/evaluate.cpp
+++ b/src/buildtool/computed_roots/evaluate.cpp
@@ -42,6 +42,7 @@
#include "src/buildtool/common/protocol_traits.hpp"
#include "src/buildtool/common/statistics.hpp"
#include "src/buildtool/computed_roots/analyse_and_build.hpp"
+#include "src/buildtool/computed_roots/inquire_serve.hpp"
#include "src/buildtool/computed_roots/lookup_cache.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/execution_api/common/api_bundle.hpp"
@@ -174,6 +175,7 @@ void ComputeAndFill(
std::size_t jobs,
RootMap::LoggerPtr const& logger,
RootMap::SetterPtr const& setter) {
+
auto tmpdir = storage_config->CreateTypedTmpDir("computed-root");
if (not tmpdir) {
(*logger)("Failed to create temporary directory", true);
@@ -257,6 +259,34 @@ void ComputeAndFill(
}
}
+ if (key.absent) {
+ if (storage_config->hash_function.GetType() !=
+ HashFunction::Type::GitSHA1) {
+ Logger::Log(LogLevel::Performance,
+ "Computing root {} locally as rehahing would have to "
+ "be done locally",
+ key.ToString());
+ }
+ else {
+ auto serve_result = InquireServe(
+ &analyse_context, target, context->apis, &build_logger);
+ if (serve_result) {
+ auto root_result = FileRoot(*serve_result);
+ Logger::Log(LogLevel::Performance,
+ "Absent root {} obtained from serve to be {}",
+ target.ToString(),
+ *serve_result);
+ {
+ std::unique_lock setting{*config_lock};
+ repository_config->SetPrecomputedRoot(PrecomputedRoot{key},
+ root_result);
+ }
+ (*setter)(std::move(*serve_result));
+ return;
+ }
+ }
+ }
+
GraphTraverser traverser{
root_build_args, &root_exec_context, reporter, &build_logger};
std::optional<AnalyseAndBuildResult> build_result{};
@@ -314,6 +344,50 @@ void ComputeAndFill(
/*fatal=*/true);
return;
}
+ if (key.absent) {
+ if (serve == nullptr) {
+ (*logger)(fmt::format("Requested root {} to be absent, without "
+ "providing serve endpoint",
+ key.ToString()),
+ /*fatal=*/true);
+ return;
+ }
+ auto known = serve->CheckRootTree(*result);
+ if (known.has_value() and not *known) {
+ auto tree_digest =
+ ArtifactDigestFactory::Create(HashFunction::Type::GitSHA1,
+ *result,
+ /*size_unknown=*/0,
+ /*is_tree=*/true);
+ if (not tree_digest) {
+ (*logger)(
+ fmt::format("Internal error getting digest for tree {}: {}",
+ *known,
+ tree_digest.error()),
+ /*fatal=*/true);
+ return;
+ }
+ auto uploaded_to_serve = UploadToServe(*serve,
+ *context->apis,
+ *storage_config,
+ *tree_digest,
+ storage_config->GitRoot());
+ if (not uploaded_to_serve) {
+ (*logger)(fmt::format("Failed to sync {} to serve:{}",
+ *result,
+ uploaded_to_serve.error()),
+ /*fatal=*/true);
+ return;
+ }
+ Logger::Log(LogLevel::Performance, "Uploaded {} to serve", *result);
+ known = true;
+ }
+ if (not known.has_value() or not *known) {
+ (*logger)(
+ fmt::format("Failed to ensure {} is known to serve", *result),
+ /*fatal=*/true);
+ }
+ }
{
// For setting, we need an exclusiver lock; so get one after we
// dropped the shared one