summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/serve_api/remote/serve_api.hpp6
-rw-r--r--src/buildtool/serve_api/remote/source_tree_client.cpp31
-rw-r--r--src/buildtool/serve_api/remote/source_tree_client.hpp35
-rw-r--r--src/other_tools/root_maps/commit_git_map.cpp96
-rw-r--r--src/other_tools/root_maps/content_git_map.cpp113
-rw-r--r--src/other_tools/root_maps/distdir_git_map.cpp88
6 files changed, 255 insertions, 114 deletions
diff --git a/src/buildtool/serve_api/remote/serve_api.hpp b/src/buildtool/serve_api/remote/serve_api.hpp
index 44169223..23b8904b 100644
--- a/src/buildtool/serve_api/remote/serve_api.hpp
+++ b/src/buildtool/serve_api/remote/serve_api.hpp
@@ -44,7 +44,7 @@ class ServeApi final {
[[nodiscard]] static auto RetrieveTreeFromCommit(
std::string const& commit,
std::string const& subdir = ".",
- bool sync_tree = false) -> std::optional<std::string> {
+ bool sync_tree = false) -> std::variant<bool, std::string> {
return Instance().stc_->ServeCommitTree(commit, subdir, sync_tree);
}
@@ -53,7 +53,7 @@ class ServeApi final {
std::string const& archive_type = "archive",
std::string const& subdir = ".",
std::optional<PragmaSpecial> const& resolve_symlinks = std::nullopt,
- bool sync_tree = false) -> std::optional<std::string> {
+ bool sync_tree = false) -> std::variant<bool, std::string> {
return Instance().stc_->ServeArchiveTree(
content, archive_type, subdir, resolve_symlinks, sync_tree);
}
@@ -61,7 +61,7 @@ class ServeApi final {
[[nodiscard]] static auto RetrieveTreeFromDistdir(
std::shared_ptr<std::unordered_map<std::string, std::string>> const&
distfiles,
- bool sync_tree = false) -> std::optional<std::string> {
+ bool sync_tree = false) -> std::variant<bool, std::string> {
return Instance().stc_->ServeDistdirTree(distfiles, sync_tree);
}
diff --git a/src/buildtool/serve_api/remote/source_tree_client.cpp b/src/buildtool/serve_api/remote/source_tree_client.cpp
index 073181a0..8267df7f 100644
--- a/src/buildtool/serve_api/remote/source_tree_client.cpp
+++ b/src/buildtool/serve_api/remote/source_tree_client.cpp
@@ -64,8 +64,7 @@ SourceTreeClient::SourceTreeClient(std::string const& server,
auto SourceTreeClient::ServeCommitTree(std::string const& commit_id,
std::string const& subdir,
- bool sync_tree)
- -> std::optional<std::string> {
+ bool sync_tree) -> result_t {
justbuild::just_serve::ServeCommitTreeRequest request{};
request.set_commit(commit_id);
request.set_subdir(subdir);
@@ -77,16 +76,18 @@ auto SourceTreeClient::ServeCommitTree(std::string const& commit_id,
if (not status.ok()) {
LogStatus(&logger_, LogLevel::Debug, status);
- return std::nullopt;
+ return true; // fatal failure
}
if (response.status() !=
::justbuild::just_serve::ServeCommitTreeResponse::OK) {
logger_.Emit(LogLevel::Debug,
"ServeCommitTree response returned with {}",
static_cast<int>(response.status()));
- return std::nullopt;
+ return /*fatal = */ (
+ response.status() !=
+ ::justbuild::just_serve::ServeCommitTreeResponse::NOT_FOUND);
}
- return response.tree();
+ return response.tree(); // success
}
auto SourceTreeClient::ServeArchiveTree(
@@ -94,7 +95,7 @@ auto SourceTreeClient::ServeArchiveTree(
std::string const& archive_type,
std::string const& subdir,
std::optional<PragmaSpecial> const& resolve_symlinks,
- bool sync_tree) -> std::optional<std::string> {
+ bool sync_tree) -> result_t {
justbuild::just_serve::ServeArchiveTreeRequest request{};
request.set_content(content);
request.set_archive_type(StringToArchiveType(archive_type));
@@ -109,22 +110,24 @@ auto SourceTreeClient::ServeArchiveTree(
if (not status.ok()) {
LogStatus(&logger_, LogLevel::Debug, status);
- return std::nullopt;
+ return true; // fatal failure
}
if (response.status() !=
::justbuild::just_serve::ServeArchiveTreeResponse::OK) {
logger_.Emit(LogLevel::Debug,
"ServeArchiveTree response returned with {}",
static_cast<int>(response.status()));
- return std::nullopt;
+ return /*fatal = */ (
+ response.status() !=
+ ::justbuild::just_serve::ServeArchiveTreeResponse::NOT_FOUND);
}
- return response.tree();
+ return response.tree(); // success
}
auto SourceTreeClient::ServeDistdirTree(
std::shared_ptr<std::unordered_map<std::string, std::string>> const&
distfiles,
- bool sync_tree) -> std::optional<std::string> {
+ bool sync_tree) -> result_t {
justbuild::just_serve::ServeDistdirTreeRequest request{};
for (auto const& [k, v] : *distfiles) {
auto* distfile = request.add_distfiles();
@@ -139,16 +142,18 @@ auto SourceTreeClient::ServeDistdirTree(
if (not status.ok()) {
LogStatus(&logger_, LogLevel::Debug, status);
- return std::nullopt;
+ return true; // fatal failure
}
if (response.status() !=
::justbuild::just_serve::ServeDistdirTreeResponse::OK) {
logger_.Emit(LogLevel::Debug,
"ServeDistdirTree response returned with {}",
static_cast<int>(response.status()));
- return std::nullopt;
+ return /*fatal = */ (
+ response.status() !=
+ ::justbuild::just_serve::ServeDistdirTreeResponse::NOT_FOUND);
}
- return response.tree();
+ return response.tree(); // success
}
auto SourceTreeClient::ServeContent(std::string const& content) -> bool {
diff --git a/src/buildtool/serve_api/remote/source_tree_client.hpp b/src/buildtool/serve_api/remote/source_tree_client.hpp
index 3ea1058b..24b2654a 100644
--- a/src/buildtool/serve_api/remote/source_tree_client.hpp
+++ b/src/buildtool/serve_api/remote/source_tree_client.hpp
@@ -17,6 +17,7 @@
#include <memory>
#include <string>
+#include <variant>
#include "justbuild/just_serve/just_serve.grpc.pb.h"
#include "src/buildtool/common/remote/port.hpp"
@@ -29,42 +30,54 @@ class SourceTreeClient {
public:
SourceTreeClient(std::string const& server, Port port) noexcept;
- /// \brief Retrieve the Git tree of a given commit, if known by the remote.
+ // An error + data union type
+ using result_t = std::variant<bool, std::string>;
+
+ /// \brief Retrieve the Git tree of a given commit, if known by the
+ /// endpoint. It is a fatal error if the commit is known to the endpoint but
+ /// no tree is able to be returned.
/// \param[in] commit_id Hash of the Git commit to look up.
/// \param[in] subdir Relative path of the tree inside commit.
/// \param[in] sync_tree Sync tree to the remote-execution endpoint.
- /// \returns The hash of the tree if commit found, nullopt otherwise.
+ /// \returns An error + data union, where at index 0 we return a fatal flag,
+ /// with false meaning non-fatal failure (commit or subtree not found), and
+ /// at index 1 the tree identifier on success.
[[nodiscard]] auto ServeCommitTree(std::string const& commit_id,
std::string const& subdir,
- bool sync_tree)
- -> std::optional<std::string>;
+ bool sync_tree) -> result_t;
- /// \brief Retrieve the Git tree of an archive content, if known by remote.
+ /// \brief Retrieve the Git tree of an archive content, if known by the
+ /// endpoint. It is a fatal error if the content blob is known to the
+ /// endpoint but no tree is able to be returned.
/// \param[in] content Hash of the archive content to look up.
/// \param[in] archive_type Type of archive ("archive"|"zip").
/// \param[in] subdir Relative path of the tree inside archive.
/// \param[in] resolve_symlinks Optional enum to state how symlinks in the
/// archive should be handled if the tree has to be actually computed.
/// \param[in] sync_tree Sync tree to the remote-execution endpoint.
- /// \returns The hash of the tree if content blob found, nullopt otherwise.
+ /// \returns An error + data union, where at index 0 we return a fatal flag,
+ /// with false meaning non-fatal failure (content blob not found), and at
+ /// index 1 the tree identifier on success.
[[nodiscard]] auto ServeArchiveTree(
std::string const& content,
std::string const& archive_type,
std::string const& subdir,
std::optional<PragmaSpecial> const& resolve_symlinks,
- bool sync_tree) -> std::optional<std::string>;
+ bool sync_tree) -> result_t;
/// \brief Retrieve the Git tree of a directory of distfiles, if all the
- /// content blobs are known by serve remote.
+ /// content blobs are known by the endpoint. It is a fatal error if all
+ /// content blobs are known but no tree is able to be returned.
/// \param[in] distfiles Mapping from distfile names to content blob ids.
/// \param[in] sync_tree Sync tree and all ditfile blobs to the
/// remote-execution endpoint.
- /// \returns The hash of the resulting tree if all distfile blobs found,
- /// nullopt otherwise.
+ /// \returns An error + data union, where at index 0 we return a fatal flag,
+ /// with false meaning non-fatal failure (at least one distfile blob
+ /// missing), and at index 1 the tree identifier on success.
[[nodiscard]] auto ServeDistdirTree(
std::shared_ptr<std::unordered_map<std::string, std::string>> const&
distfiles,
- bool sync_tree) -> std::optional<std::string>;
+ bool sync_tree) -> result_t;
/// \brief Make a given content blob available in remote CAS, if known by
/// serve remote.
diff --git a/src/other_tools/root_maps/commit_git_map.cpp b/src/other_tools/root_maps/commit_git_map.cpp
index 63cfa02a..7dc332ea 100644
--- a/src/other_tools/root_maps/commit_git_map.cpp
+++ b/src/other_tools/root_maps/commit_git_map.cpp
@@ -62,21 +62,34 @@ void EnsureRootAsAbsent(
if (not *has_tree) {
// try to see if serve endpoint has the information to prepare the
// root itself
- if (auto served_tree_id =
- ServeApi::RetrieveTreeFromCommit(repo_info.hash,
- repo_info.subdir,
- /*sync_tree = */ false)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromCommit(repo_info.hash,
+ repo_info.subdir,
+ /*sync_tree = */ false);
+ if (std::holds_alternative<std::string>(serve_result)) {
// if serve has set up the tree, it must match what we expect
- if (tree_id != *served_tree_id) {
+ auto const& served_tree_id =
+ std::get<std::string>(serve_result);
+ if (tree_id != served_tree_id) {
(*logger)(fmt::format("Mismatch in served root tree "
"id:\nexpected {}, but got {}",
tree_id,
- *served_tree_id),
+ served_tree_id),
/*fatal=*/true);
return;
}
}
else {
+ // check if serve failure was due to commit not being found or
+ // it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(fmt::format("Serve endpoint failed to set up "
+ "root from known commit {}",
+ repo_info.hash),
+ /*fatal=*/true);
+ return;
+ }
if (not remote_api) {
(*logger)(fmt::format("Missing remote-execution endpoint "
"needed to sync workspace root {} "
@@ -263,10 +276,11 @@ void EnsureCommit(
if (serve_api_exists) {
// if root purely absent, request only the subdir tree
if (repo_info.absent and not fetch_absent) {
- if (auto tree_id = ServeApi::RetrieveTreeFromCommit(
- repo_info.hash,
- repo_info.subdir,
- /*sync_tree = */ false)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromCommit(repo_info.hash,
+ repo_info.subdir,
+ /*sync_tree = */ false);
+ if (std::holds_alternative<std::string>(serve_result)) {
// set the workspace root as absent
JustMRProgress::Instance().TaskTracker().Stop(
repo_info.origin);
@@ -275,23 +289,36 @@ void EnsureCommit(
{repo_info.ignore_special
? FileRoot::kGitTreeIgnoreSpecialMarker
: FileRoot::kGitTreeMarker,
- *tree_id}),
+ std::get<std::string>(serve_result)}),
/*is_cache_hit=*/false));
return;
}
+ // check if serve failure was due to commit not being found or
+ // it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(fmt::format("Serve endpoint failed to set up "
+ "root from known commit {}",
+ repo_info.hash),
+ /*fatal=*/true);
+ return;
+ }
}
// otherwise, request (and sync) the whole commit tree, to ensure
// we maintain the id file association
else {
- if (auto root_tree_id = ServeApi::RetrieveTreeFromCommit(
- repo_info.hash,
- /*subdir = */ ".",
- /*sync_tree = */ true)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromCommit(repo_info.hash,
+ /*subdir = */ ".",
+ /*sync_tree = */ true);
+ if (std::holds_alternative<std::string>(serve_result)) {
+ auto const& root_tree_id =
+ std::get<std::string>(serve_result);
// verify if we know the tree already locally
auto wrapped_logger =
std::make_shared<AsyncMapConsumerLogger>(
- [logger, tree = *root_tree_id](auto const& msg,
- bool fatal) {
+ [logger, tree = root_tree_id](auto const& msg,
+ bool fatal) {
(*logger)(
fmt::format("While verifying presence of "
"tree {}:\n{}",
@@ -299,8 +326,8 @@ void EnsureCommit(
msg),
fatal);
});
- auto tree_present = git_repo->CheckTreeExists(
- *root_tree_id, wrapped_logger);
+ auto tree_present =
+ git_repo->CheckTreeExists(root_tree_id, wrapped_logger);
if (not tree_present) {
return;
}
@@ -309,7 +336,7 @@ void EnsureCommit(
repo_info.origin);
// write association to id file, get subdir tree,
// and set the workspace root as present
- WriteIdFileAndSetWSRoot(*root_tree_id,
+ WriteIdFileAndSetWSRoot(root_tree_id,
repo_info.subdir,
repo_info.ignore_special,
git_cas,
@@ -321,7 +348,7 @@ void EnsureCommit(
}
// try to get root tree from remote execution endpoint
auto root_digest =
- ArtifactDigest{*root_tree_id, 0, /*is_tree=*/true};
+ ArtifactDigest{root_tree_id, 0, /*is_tree=*/true};
if (remote_api and
remote_api.value()->RetrieveToCas(
{Artifact::ObjectInfo{.digest = root_digest,
@@ -337,7 +364,7 @@ void EnsureCommit(
fmt::format("Failed to create tmp "
"directory after fetching root "
"tree {} for absent commit {}",
- *root_tree_id,
+ root_tree_id,
repo_info.hash),
/*fatal=*/true);
return;
@@ -349,18 +376,18 @@ void EnsureCommit(
{tmp_dir->GetPath()})) {
(*logger)(fmt::format("Failed to copy fetched root "
"tree {} to {}",
- *root_tree_id,
+ root_tree_id,
tmp_dir->GetPath().string()),
/*fatal=*/true);
return;
}
CommitInfo c_info{
- tmp_dir->GetPath(), "tree", *root_tree_id};
+ tmp_dir->GetPath(), "tree", root_tree_id};
import_to_git_map->ConsumeAfterKeysReady(
ts,
{std::move(c_info)},
[tmp_dir, // keep tmp_dir alive
- root_tree_id = *root_tree_id,
+ root_tree_id,
subdir = repo_info.subdir,
ignore_special = repo_info.ignore_special,
git_cas,
@@ -411,7 +438,7 @@ void EnsureCommit(
(*logger)(
fmt::format("While moving root tree {} "
"from {} to local git:\n{}",
- *root_tree_id,
+ root_tree_id,
tmp_dir->GetPath().string(),
msg),
fatal);
@@ -423,15 +450,20 @@ void EnsureCommit(
// remote CAS, so log this attempt and revert to network
(*logger)(fmt::format("Tree {} marked as served, but not "
"found on remote",
- *root_tree_id),
+ root_tree_id),
/*fatal=*/false);
}
else {
- // give warning
- (*logger)(fmt::format(
- "Root tree for commit {} could not be served",
- repo_info.hash),
- /*fatal=*/false);
+ // check if serve failure was due to commit not being found
+ // or it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(fmt::format("Serve endpoint failed to set up "
+ "root from known commit {}",
+ repo_info.hash),
+ /*fatal=*/true);
+ return;
+ }
}
}
}
diff --git a/src/other_tools/root_maps/content_git_map.cpp b/src/other_tools/root_maps/content_git_map.cpp
index 5dafef06..5d910015 100644
--- a/src/other_tools/root_maps/content_git_map.cpp
+++ b/src/other_tools/root_maps/content_git_map.cpp
@@ -71,23 +71,36 @@ void EnsureRootAsAbsent(
if (not *has_tree) {
// try to see if serve endpoint has the information to prepare the
// root itself
- if (auto served_tree_id =
- ServeApi::RetrieveTreeFromArchive(key.archive.content,
- key.repo_type,
- key.subdir,
- key.pragma_special,
- /*sync_tree=*/false)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromArchive(key.archive.content,
+ key.repo_type,
+ key.subdir,
+ key.pragma_special,
+ /*sync_tree=*/false);
+ if (std::holds_alternative<std::string>(serve_result)) {
// if serve has set up the tree, it must match what we expect
- if (tree_id != *served_tree_id) {
+ auto const& served_tree_id =
+ std::get<std::string>(serve_result);
+ if (tree_id != served_tree_id) {
(*logger)(fmt::format("Mismatch in served root tree "
"id:\nexpected {}, but got {}",
tree_id,
- *served_tree_id),
+ served_tree_id),
/*fatal=*/true);
return;
}
}
else {
+ // check if serve failure was due to archive content not being
+ // found or it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(fmt::format("Serve endpoint failed to set up "
+ "root from known archive content {}",
+ key.archive.content),
+ /*fatal=*/true);
+ return;
+ }
if (not is_on_remote and not remote_api) {
(*logger)(fmt::format("Missing remote-execution endpoint "
"needed to sync workspace root {} "
@@ -700,39 +713,58 @@ auto CreateContentGitMap(
// if purely absent, request the resolved subdir tree
// directly
if (key.absent and not fetch_absent) {
- if (auto tree_id =
- ServeApi::RetrieveTreeFromArchive(
- key.archive.content,
- key.repo_type,
- key.subdir,
- key.pragma_special,
- /*sync_tree = */ false)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromArchive(
+ key.archive.content,
+ key.repo_type,
+ key.subdir,
+ key.pragma_special,
+ /*sync_tree = */ false);
+ if (std::holds_alternative<std::string>(
+ serve_result)) {
// set the workspace root as absent
JustMRProgress::Instance().TaskTracker().Stop(
key.archive.origin);
(*setter)(std::pair(
nlohmann::json::array(
- {FileRoot::kGitTreeMarker, *tree_id}),
+ {FileRoot::kGitTreeMarker,
+ std::get<std::string>(serve_result)}),
/*is_cache_hit = */ false));
return;
}
+ // check if serve failure was due to archive content
+ // not being found or it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(
+ fmt::format(
+ "Serve endpoint failed to set up "
+ "root from known archive content {}",
+ key.archive.content),
+ /*fatal=*/true);
+ return;
+ }
}
// otherwise, request (and sync) the whole archive tree,
// UNRESOLVED, to ensure we maintain the id file
// association
else {
- if (auto root_tree_id =
- ServeApi::RetrieveTreeFromArchive(
- key.archive.content,
- key.repo_type,
- /*subdir = */ ".",
- /* resolve_symlinks = */ std::nullopt,
- /*sync_tree = */ true)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromArchive(
+ key.archive.content,
+ key.repo_type,
+ /*subdir = */ ".",
+ /* resolve_symlinks = */ std::nullopt,
+ /*sync_tree = */ true);
+ if (std::holds_alternative<std::string>(
+ serve_result)) {
+ auto const& root_tree_id =
+ std::get<std::string>(serve_result);
// verify if we already know the tree locally;
// setup wrapped logger
auto wrapped_logger =
std::make_shared<AsyncMapConsumerLogger>(
- [&logger, tree = *root_tree_id](
+ [&logger, tree = root_tree_id](
auto const& msg, bool fatal) {
(*logger)(
fmt::format(
@@ -744,7 +776,7 @@ auto CreateContentGitMap(
});
auto tree_present =
just_git_repo->CheckTreeExists(
- *root_tree_id, wrapped_logger);
+ root_tree_id, wrapped_logger);
if (not tree_present) {
return;
}
@@ -756,7 +788,7 @@ auto CreateContentGitMap(
// this results in a present root
WriteIdFileAndSetWSRoot(
key,
- *root_tree_id,
+ root_tree_id,
just_git_cas,
archive_tree_id_file,
/*is_absent=*/false,
@@ -773,7 +805,7 @@ auto CreateContentGitMap(
// try to get root tree from remote execution
// endpoint
auto root_digest = ArtifactDigest{
- *root_tree_id, 0, /*is_tree=*/true};
+ root_tree_id, 0, /*is_tree=*/true};
if (remote_api and
remote_api.value()->RetrieveToCas(
{Artifact::ObjectInfo{
@@ -793,7 +825,7 @@ auto CreateContentGitMap(
"Failed to create tmp "
"directory after fetching root "
"tree {} for absent archive {}",
- *root_tree_id,
+ root_tree_id,
key.archive.content),
true);
return;
@@ -807,14 +839,14 @@ auto CreateContentGitMap(
fmt::format(
"Failed to copy fetched root "
"tree {} to {}",
- *root_tree_id,
+ root_tree_id,
tmp_dir->GetPath().string()),
true);
return;
}
CommitInfo c_info{tmp_dir->GetPath(),
"tree",
- *root_tree_id};
+ root_tree_id};
import_to_git_map->ConsumeAfterKeysReady(
ts,
{std::move(c_info)},
@@ -838,7 +870,7 @@ auto CreateContentGitMap(
// present root
WriteIdFileAndSetWSRoot(
key,
- *root_tree_id,
+ root_tree_id,
just_git_cas,
archive_tree_id_file,
/*is_absent=*/false,
@@ -856,7 +888,7 @@ auto CreateContentGitMap(
fmt::format(
"While moving root tree {} "
"from {} to local git:\n{}",
- *root_tree_id,
+ root_tree_id,
tmp_dir->GetPath().string(),
msg),
fatal);
@@ -919,11 +951,18 @@ auto CreateContentGitMap(
// done
return;
}
- // give warning
- (*logger)(fmt::format("Root tree for content {} "
- "could not be served",
- key.archive.content),
- /*fatal=*/false);
+ // check if serve failure was due to archive content
+ // not being found or it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(
+ fmt::format(
+ "Serve endpoint failed to set up root "
+ "from known archive content {}",
+ key.archive.content),
+ /*fatal=*/true);
+ return;
+ }
}
}
diff --git a/src/other_tools/root_maps/distdir_git_map.cpp b/src/other_tools/root_maps/distdir_git_map.cpp
index 7646882b..2ee0265f 100644
--- a/src/other_tools/root_maps/distdir_git_map.cpp
+++ b/src/other_tools/root_maps/distdir_git_map.cpp
@@ -191,6 +191,7 @@ auto CreateDistdirGitMap(
ts,
{std::move(op_key)},
[distdir_tree_id = *distdir_tree_id,
+ content_id = key.content_id,
key,
serve_api_exists,
remote_api,
@@ -216,24 +217,45 @@ auto CreateDistdirGitMap(
if (not *has_tree) {
// try to see if serve endpoint has the
// information to prepare the root itself
- if (auto served_tree_id =
- ServeApi::RetrieveTreeFromDistdir(
- key.content_list,
- /*sync_tree=*/false)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromDistdir(
+ key.content_list,
+ /*sync_tree=*/false);
+ if (std::holds_alternative<std::string>(
+ serve_result)) {
// if serve has set up the tree, it must
// match what we expect
- if (distdir_tree_id != *served_tree_id) {
+ auto const& served_tree_id =
+ std::get<std::string>(serve_result);
+ if (distdir_tree_id != served_tree_id) {
(*logger)(
fmt::format(
"Mismatch in served root tree "
"id:\nexpected {}, but got {}",
distdir_tree_id,
- *served_tree_id),
+ served_tree_id),
/*fatal=*/true);
return;
}
}
else {
+ // check if serve failure was due to distdir
+ // content not being found or it is
+ // otherwise fatal
+ auto const& is_fatal =
+ std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(
+ fmt::format(
+ "Serve endpoint failed to set "
+ "up root from known distdir "
+ "content {}",
+ content_id),
+ /*fatal=*/true);
+ return;
+ }
+ // at this point we cannot continue without
+ // the remote api
if (not remote_api) {
(*logger)(
fmt::format(
@@ -344,17 +366,20 @@ auto CreateDistdirGitMap(
}
// try to see if serve endpoint has the information to
// prepare the root itself
- if (auto served_tree_id = ServeApi::RetrieveTreeFromDistdir(
- key.content_list,
- /*sync_tree=*/false)) {
- // if serve has set up the tree, it must match what we
- // expect
- if (tree_id != *served_tree_id) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromDistdir(key.content_list,
+ /*sync_tree=*/false);
+ if (std::holds_alternative<std::string>(serve_result)) {
+ // if serve has set up the tree, it must
+ // match what we expect
+ auto const& served_tree_id =
+ std::get<std::string>(serve_result);
+ if (tree_id != served_tree_id) {
(*logger)(
fmt::format("Mismatch in served root tree "
"id:\nexpected {}, but got {}",
tree_id,
- *served_tree_id),
+ served_tree_id),
/*fatal=*/true);
return;
}
@@ -365,6 +390,17 @@ auto CreateDistdirGitMap(
/*is_cache_hit=*/false));
return;
}
+ // check if serve failure was due to distdir content not
+ // being found or it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(
+ fmt::format("Serve endpoint failed to set up root "
+ "from known distdir content {}",
+ key.content_id),
+ /*fatal=*/true);
+ return;
+ }
// at this point we cannot continue without the remote api
if (not remote_api) {
(*logger)(
@@ -467,16 +503,19 @@ auto CreateDistdirGitMap(
}
// now ask serve endpoint if it can set up the root
if (serve_api_exists and remote_api) {
- if (auto served_tree_id =
- ServeApi::RetrieveTreeFromDistdir(key.content_list,
- /*sync_tree=*/true)) {
+ auto serve_result =
+ ServeApi::RetrieveTreeFromDistdir(key.content_list,
+ /*sync_tree=*/true);
+ if (std::holds_alternative<std::string>(serve_result)) {
// if serve has set up the tree, it must match what we
// expect
- if (tree_id != *served_tree_id) {
+ auto const& served_tree_id =
+ std::get<std::string>(serve_result);
+ if (tree_id != served_tree_id) {
(*logger)(fmt::format("Mismatch in served root tree "
"id:\nexpected {}, but got {}",
tree_id,
- *served_tree_id),
+ served_tree_id),
/*fatal=*/true);
return;
}
@@ -484,6 +523,19 @@ auto CreateDistdirGitMap(
// root, as we will check the remote CAS for the
// resulting tree anyway
}
+ else {
+ // check if serve failure was due to distdir content not
+ // being found or it is otherwise fatal
+ auto const& is_fatal = std::get<bool>(serve_result);
+ if (is_fatal) {
+ (*logger)(
+ fmt::format("Serve endpoint failed to set up root "
+ "from known distdir content {}",
+ key.content_id),
+ /*fatal=*/true);
+ return;
+ }
+ }
}
// check the remote CAS for the tree
if (remote_api and