summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/serve_api/serve_service/TARGETS3
-rw-r--r--src/buildtool/serve_api/serve_service/source_tree.cpp158
-rw-r--r--src/buildtool/serve_api/serve_service/source_tree.hpp32
-rw-r--r--src/buildtool/serve_api/serve_service/target.cpp26
-rw-r--r--src/buildtool/serve_api/serve_service/target.hpp8
5 files changed, 108 insertions, 119 deletions
diff --git a/src/buildtool/serve_api/serve_service/TARGETS b/src/buildtool/serve_api/serve_service/TARGETS
index 3f51feba..9349c53d 100644
--- a/src/buildtool/serve_api/serve_service/TARGETS
+++ b/src/buildtool/serve_api/serve_service/TARGETS
@@ -19,9 +19,11 @@
, ["src/buildtool/execution_api/common", "common"]
, ["src/buildtool/execution_api/remote", "config"]
, ["src/buildtool/execution_api/common", "api_bundle"]
+ , ["src/buildtool/file_system", "git_types"]
, ["src/buildtool/file_system/symlinks_map", "pragma_special"]
, ["src/buildtool/file_system/symlinks_map", "resolve_symlinks_map"]
, ["src/buildtool/serve_api/remote", "config"]
+ , ["src/utils/cpp", "expected"]
]
, "stage": ["src", "buildtool", "serve_api", "serve_service"]
, "private-deps":
@@ -84,6 +86,7 @@
, ["src/buildtool/execution_api/common", "api_bundle"]
, ["src/buildtool/execution_api/common", "common"]
, ["src/buildtool/serve_api/remote", "config"]
+ , ["src/utils/cpp", "expected"]
]
, "stage": ["src", "buildtool", "serve_api", "serve_service"]
, "private-deps":
diff --git a/src/buildtool/serve_api/serve_service/source_tree.cpp b/src/buildtool/serve_api/serve_service/source_tree.cpp
index f79a6492..8e105eee 100644
--- a/src/buildtool/serve_api/serve_service/source_tree.cpp
+++ b/src/buildtool/serve_api/serve_service/source_tree.cpp
@@ -100,7 +100,8 @@ auto SourceTreeService::GetSubtreeFromCommit(
std::filesystem::path const& repo_path,
std::string const& commit,
std::string const& subdir,
- std::shared_ptr<Logger> const& logger) -> std::variant<bool, std::string> {
+ std::shared_ptr<Logger> const& logger)
+ -> expected<std::string, GitLookupError> {
if (auto git_cas = GitCAS::Open(repo_path)) {
if (auto repo = GitRepo::Open(git_cas)) {
// wrap logger for GitRepo call
@@ -117,22 +118,18 @@ auto SourceTreeService::GetSubtreeFromCommit(
msg);
}
});
- auto res =
- repo->GetSubtreeFromCommit(commit, subdir, wrapped_logger);
- if (not res) {
- return res.error() == GitLookupError::Fatal;
- }
- return *std::move(res);
+ return repo->GetSubtreeFromCommit(commit, subdir, wrapped_logger);
}
}
- return true; // fatal failure
+ return unexpected{GitLookupError::Fatal};
}
auto SourceTreeService::GetSubtreeFromTree(
std::filesystem::path const& repo_path,
std::string const& tree_id,
std::string const& subdir,
- std::shared_ptr<Logger> const& logger) -> std::variant<bool, std::string> {
+ std::shared_ptr<Logger> const& logger)
+ -> expected<std::string, GitLookupError> {
if (auto git_cas = GitCAS::Open(repo_path)) {
if (auto repo = GitRepo::Open(git_cas)) {
// wrap logger for GitRepo call
@@ -153,16 +150,16 @@ auto SourceTreeService::GetSubtreeFromTree(
repo->GetSubtreeFromTree(tree_id, subdir, wrapped_logger)) {
return *subtree_id;
}
- return false; // non-fatal failure
+ return unexpected{GitLookupError::NotFound}; // non-fatal failure
}
}
- return true; // fatal failure
+ return unexpected{GitLookupError::Fatal};
}
auto SourceTreeService::GetBlobFromRepo(std::filesystem::path const& repo_path,
std::string const& blob_id,
std::shared_ptr<Logger> const& logger)
- -> std::variant<bool, std::string> {
+ -> expected<std::string, GitLookupError> {
if (auto git_cas = GitCAS::Open(repo_path)) {
if (auto repo = GitRepo::Open(git_cas)) {
// wrap logger for GitRepo call
@@ -179,14 +176,15 @@ auto SourceTreeService::GetBlobFromRepo(std::filesystem::path const& repo_path,
});
auto res = repo->TryReadBlob(blob_id, wrapped_logger);
if (not res.first) {
- return true; // fatal failure
+ return unexpected{GitLookupError::Fatal};
}
if (not res.second) {
logger->Emit(LogLevel::Debug,
"Blob {} not found in repository {}",
blob_id,
repo_path.string());
- return false; // non-fatal failure
+ return unexpected{
+ GitLookupError::NotFound}; // non-fatal failure
}
return res.second.value();
}
@@ -194,7 +192,7 @@ auto SourceTreeService::GetBlobFromRepo(std::filesystem::path const& repo_path,
// failed to open repository
logger->Emit(
LogLevel::Debug, "Failed to open repository {}", repo_path.string());
- return true; // fatal failure
+ return unexpected{GitLookupError::Fatal};
}
auto SourceTreeService::ServeCommitTree(
@@ -206,8 +204,8 @@ auto SourceTreeService::ServeCommitTree(
// try in local build root Git cache
auto res =
GetSubtreeFromCommit(StorageConfig::GitRoot(), commit, subdir, logger_);
- if (std::holds_alternative<std::string>(res)) {
- auto tree_id = std::get<std::string>(res);
+ if (res) {
+ auto tree_id = *std::move(res);
if (request->sync_tree()) {
// sync tree with remote CAS; only possible in native mode
if (Compatibility::IsCompatible()) {
@@ -247,7 +245,7 @@ auto SourceTreeService::ServeCommitTree(
return ::grpc::Status::OK;
}
// report fatal failure
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed while retrieving subtree {} of commit {} from "
"repository {}",
@@ -260,8 +258,8 @@ auto SourceTreeService::ServeCommitTree(
// try given extra repositories, in order
for (auto const& path : serve_config_.known_repositories) {
auto res = GetSubtreeFromCommit(path, commit, subdir, logger_);
- if (std::holds_alternative<std::string>(res)) {
- auto tree_id = std::get<std::string>(res);
+ if (res) {
+ auto tree_id = *std::move(res);
if (request->sync_tree()) {
// sync tree with remote CAS; only possible in native mode
if (Compatibility::IsCompatible()) {
@@ -305,7 +303,7 @@ auto SourceTreeService::ServeCommitTree(
return ::grpc::Status::OK;
}
// report fatal failure
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed while retrieving subtree {} of commit {} "
"from repository {}",
@@ -498,16 +496,13 @@ auto SourceTreeService::ResolveContentTree(
auto SourceTreeService::CommonImportToGit(
std::filesystem::path const& root_path,
- std::string const& commit_message)
- -> std::variant<std::string, std::string> {
- using result_t = std::variant<std::string, std::string>;
+ std::string const& commit_message) -> expected<std::string, std::string> {
// do the initial commit; no need to guard, as the tmp location is unique
auto git_repo = GitRepo::InitAndOpen(root_path,
/*is_bare=*/false);
if (not git_repo) {
- auto str = fmt::format("Could not initialize repository {}",
- root_path.string());
- return result_t(std::in_place_index<0>, str);
+ return unexpected{fmt::format("Could not initialize repository {}",
+ root_path.string())};
}
// wrap logger for GitRepo call
std::string err;
@@ -524,20 +519,18 @@ auto SourceTreeService::CommonImportToGit(
auto commit_hash =
git_repo->StageAndCommitAllAnonymous(commit_message, wrapped_logger);
if (not commit_hash) {
- return result_t(std::in_place_index<0>, err);
+ return unexpected{err};
}
// open the Git CAS repo
auto just_git_cas = GitCAS::Open(StorageConfig::GitRoot());
if (not just_git_cas) {
- auto str = fmt::format("Failed to open Git ODB at {}",
- StorageConfig::GitRoot().string());
- return result_t(std::in_place_index<0>, str);
+ return unexpected{fmt::format("Failed to open Git ODB at {}",
+ StorageConfig::GitRoot().string())};
}
auto just_git_repo = GitRepo::Open(just_git_cas);
if (not just_git_repo) {
- auto str = fmt::format("Failed to open Git repository {}",
- StorageConfig::GitRoot().string());
- return result_t(std::in_place_index<0>, str);
+ return unexpected{fmt::format("Failed to open Git repository {}",
+ StorageConfig::GitRoot().string())};
}
// wrap logger for GitRepo call
err.clear();
@@ -554,7 +547,7 @@ auto SourceTreeService::CommonImportToGit(
if (not just_git_repo->LocalFetchViaTmpRepo(root_path.string(),
/*branch=*/std::nullopt,
wrapped_logger)) {
- return result_t(std::in_place_index<0>, err);
+ return unexpected{err};
}
// wrap logger for GitRepo call
err.clear();
@@ -575,15 +568,15 @@ auto SourceTreeService::CommonImportToGit(
// open real repository at Git CAS location
auto git_repo = GitRepo::Open(StorageConfig::GitRoot());
if (not git_repo) {
- auto str = fmt::format("Failed to open Git CAS repository {}",
- StorageConfig::GitRoot().string());
- return result_t(std::in_place_index<0>, str);
+ return unexpected{
+ fmt::format("Failed to open Git CAS repository {}",
+ StorageConfig::GitRoot().string())};
}
// Important: message must be consistent with just-mr!
if (not git_repo->KeepTag(*commit_hash,
"Keep referenced tree alive", // message
wrapped_logger)) {
- return result_t(std::in_place_index<0>, err);
+ return unexpected{err};
}
}
// wrap logger for GitRepo call
@@ -600,10 +593,10 @@ auto SourceTreeService::CommonImportToGit(
auto res =
just_git_repo->GetSubtreeFromCommit(*commit_hash, ".", wrapped_logger);
if (not res) {
- return result_t(std::in_place_index<0>, err);
+ return unexpected{err};
}
// return the root tree id
- return result_t(std::in_place_index<1>, *std::move(res));
+ return *std::move(res);
}
auto SourceTreeService::ArchiveImportToGit(
@@ -619,13 +612,13 @@ auto SourceTreeService::ArchiveImportToGit(
auto commit_message =
fmt::format("Content of {} {}", archive_type, content);
auto res = CommonImportToGit(unpack_path, commit_message);
- if (res.index() == 0) {
+ if (not res) {
// report the error
- logger_->Emit(LogLevel::Error, "{}", std::get<0>(res));
+ logger_->Emit(LogLevel::Error, "{}", res.error());
response->set_status(ServeArchiveTreeResponse::INTERNAL_ERROR);
return ::grpc::Status::OK;
}
- auto const& tree_id = std::get<1>(res);
+ auto const& tree_id = *res;
// write to tree id file
if (not StorageUtils::WriteTreeIDFile(archive_tree_id_file, tree_id)) {
logger_->Emit(LogLevel::Error,
@@ -732,8 +725,8 @@ auto SourceTreeService::ServeArchiveTree(
// check local build root Git cache
auto res = GetSubtreeFromTree(
StorageConfig::GitRoot(), *archive_tree_id, subdir, logger_);
- if (std::holds_alternative<std::string>(res)) {
- return ResolveContentTree(std::get<std::string>(res), // tree_id
+ if (res) {
+ return ResolveContentTree(*res, // tree_id
StorageConfig::GitRoot(),
/*repo_is_git_cache=*/true,
resolve_special,
@@ -741,7 +734,7 @@ auto SourceTreeService::ServeArchiveTree(
response);
}
// check for fatal error
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed to open repository {}",
StorageConfig::GitRoot().string());
@@ -752,17 +745,16 @@ auto SourceTreeService::ServeArchiveTree(
for (auto const& path : serve_config_.known_repositories) {
auto res =
GetSubtreeFromTree(path, *archive_tree_id, subdir, logger_);
- if (std::holds_alternative<std::string>(res)) {
- return ResolveContentTree(
- std::get<std::string>(res), // tree_id
- path,
- /*repo_is_git_cache=*/false,
- resolve_special,
- request->sync_tree(),
- response);
+ if (res) {
+ return ResolveContentTree(*res, // tree_id
+ path,
+ /*repo_is_git_cache=*/false,
+ resolve_special,
+ request->sync_tree(),
+ response);
}
// check for fatal error
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed to open repository {}",
path.string());
@@ -793,12 +785,11 @@ auto SourceTreeService::ServeArchiveTree(
not content_cas_path) {
// check if content blob is in Git cache
auto res = GetBlobFromRepo(StorageConfig::GitRoot(), content, logger_);
- if (std::holds_alternative<std::string>(res)) {
+ if (res) {
// add to CAS
- content_cas_path =
- StorageUtils::AddToCAS(std::get<std::string>(res));
+ content_cas_path = StorageUtils::AddToCAS(*res);
}
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(
LogLevel::Error,
"Failed while trying to retrieve content {} from repository {}",
@@ -812,15 +803,14 @@ auto SourceTreeService::ServeArchiveTree(
// check if content blob is in a known repository
for (auto const& path : serve_config_.known_repositories) {
auto res = GetBlobFromRepo(path, content, logger_);
- if (std::holds_alternative<std::string>(res)) {
+ if (res) {
// add to CAS
- content_cas_path =
- StorageUtils::AddToCAS(std::get<std::string>(res));
+ content_cas_path = StorageUtils::AddToCAS(*res);
if (content_cas_path) {
break;
}
}
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed while trying to retrieve content {} from "
"repository {}",
@@ -926,13 +916,13 @@ auto SourceTreeService::DistdirImportToGit(
// Important: commit message must match that in just-mr!
auto commit_message = fmt::format("Content of distdir {}", content_id);
auto res = CommonImportToGit(tmp_path, commit_message);
- if (res.index() == 0) {
+ if (not res) {
// report the error
- logger_->Emit(LogLevel::Error, "{}", std::get<0>(res));
+ logger_->Emit(LogLevel::Error, "{}", res.error());
response->set_status(ServeDistdirTreeResponse::INTERNAL_ERROR);
return ::grpc::Status::OK;
}
- auto tree_id = std::get<1>(res);
+ auto tree_id = *std::move(res);
// check the committed tree matches what we expect
if (tree_id != distdir_tree_id) {
// something is very wrong...
@@ -1027,10 +1017,9 @@ auto SourceTreeService::ServeDistdirTree(
// check local Git cache
auto res =
GetBlobFromRepo(StorageConfig::GitRoot(), content, logger_);
- if (std::holds_alternative<std::string>(res)) {
+ if (res) {
// add content to local CAS
- auto stored_blob =
- cas.StoreBlob(std::get<std::string>(res), kv.executable());
+ auto stored_blob = cas.StoreBlob(*res, kv.executable());
if (not stored_blob) {
logger_->Emit(LogLevel::Error,
"Failed to store content {} from local Git "
@@ -1044,7 +1033,7 @@ auto SourceTreeService::ServeDistdirTree(
blob_digest = NativeSupport::Unprefix(stored_blob->hash());
}
else {
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed while trying to retrieve content {} "
"from repository {}",
@@ -1057,10 +1046,9 @@ auto SourceTreeService::ServeDistdirTree(
// check known repositories
for (auto const& path : serve_config_.known_repositories) {
auto res = GetBlobFromRepo(path, content, logger_);
- if (std::holds_alternative<std::string>(res)) {
+ if (res) {
// add content to local CAS
- auto stored_blob = cas.StoreBlob(
- std::get<std::string>(res), kv.executable());
+ auto stored_blob = cas.StoreBlob(*res, kv.executable());
if (not stored_blob) {
logger_->Emit(LogLevel::Error,
"Failed to store content {} from "
@@ -1076,7 +1064,7 @@ auto SourceTreeService::ServeDistdirTree(
NativeSupport::Unprefix(stored_blob->hash());
break;
}
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(
LogLevel::Error,
"Failed while trying to retrieve content {} from "
@@ -1290,7 +1278,7 @@ auto SourceTreeService::ServeContent(
auto const digest = ArtifactDigest{content, 0, /*is_tree=*/false};
// check if content blob is in Git cache
auto res = GetBlobFromRepo(StorageConfig::GitRoot(), content, logger_);
- if (std::holds_alternative<std::string>(res)) {
+ if (res) {
// upload blob to remote CAS
auto repo = RepositoryConfig{};
if (not repo.SetGitCAS(StorageConfig::GitRoot())) {
@@ -1315,7 +1303,7 @@ auto SourceTreeService::ServeContent(
response->set_status(ServeContentResponse::OK);
return ::grpc::Status::OK;
}
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
logger_->Emit(LogLevel::Error,
"Failed while checking for content {} in repository {}",
content,
@@ -1326,7 +1314,7 @@ auto SourceTreeService::ServeContent(
// check if content blob is in a known repository
for (auto const& path : serve_config_.known_repositories) {
auto res = GetBlobFromRepo(path, content, logger_);
- if (std::holds_alternative<std::string>(res)) {
+ if (res) {
// upload blob to remote CAS
auto repo = RepositoryConfig{};
if (not repo.SetGitCAS(path)) {
@@ -1353,7 +1341,7 @@ auto SourceTreeService::ServeContent(
response->set_status(ServeContentResponse::OK);
return ::grpc::Status::OK;
}
- if (std::get<bool>(res)) {
+ if (res.error() == GitLookupError::Fatal) {
auto str = fmt::format(
"Failed while checking for content {} in repository {}",
content,
@@ -1592,13 +1580,13 @@ auto SourceTreeService::CheckRootTree(
tmp_dir->GetPath(),
fmt::format("Content of tree {}", tree_id) // message
);
- if (res.index() == 0) {
+ if (not res) {
// report the error
- logger_->Emit(LogLevel::Error, "{}", std::get<0>(res));
+ logger_->Emit(LogLevel::Error, "{}", res.error());
response->set_status(CheckRootTreeResponse::INTERNAL_ERROR);
return ::grpc::Status::OK;
}
- auto const& imported_tree_id = std::get<1>(res);
+ auto const& imported_tree_id = *res;
// sanity check
if (imported_tree_id != tree_id) {
logger_->Emit(
@@ -1664,13 +1652,13 @@ auto SourceTreeService::GetRemoteTree(
CommonImportToGit(tmp_dir->GetPath(),
fmt::format("Content of tree {}", tree_id) // message
);
- if (res.index() == 0) {
+ if (not res) {
// report the error
- logger_->Emit(LogLevel::Error, "{}", std::get<0>(res));
+ logger_->Emit(LogLevel::Error, "{}", res.error());
response->set_status(GetRemoteTreeResponse::INTERNAL_ERROR);
return ::grpc::Status::OK;
}
- auto const& imported_tree_id = std::get<1>(res);
+ auto const& imported_tree_id = *res;
// sanity check
if (imported_tree_id != tree_id) {
logger_->Emit(
diff --git a/src/buildtool/serve_api/serve_service/source_tree.hpp b/src/buildtool/serve_api/serve_service/source_tree.hpp
index 809ed889..a21eb23e 100644
--- a/src/buildtool/serve_api/serve_service/source_tree.hpp
+++ b/src/buildtool/serve_api/serve_service/source_tree.hpp
@@ -22,7 +22,6 @@
#include <string>
#include <unordered_map>
#include <utility>
-#include <variant>
#include <vector>
#include "gsl/gsl"
@@ -31,10 +30,12 @@
#include "src/buildtool/execution_api/common/api_bundle.hpp"
#include "src/buildtool/execution_api/common/execution_api.hpp"
#include "src/buildtool/execution_api/remote/config.hpp"
+#include "src/buildtool/file_system/git_types.hpp"
#include "src/buildtool/file_system/symlinks_map/pragma_special.hpp"
#include "src/buildtool/file_system/symlinks_map/resolve_symlinks_map.hpp"
#include "src/buildtool/logging/logger.hpp"
#include "src/buildtool/serve_api/remote/config.hpp"
+#include "src/utils/cpp/expected.hpp"
// Service for improved interaction with the target-level cache.
class SourceTreeService final
@@ -133,37 +134,33 @@ class SourceTreeService final
ResolveSymlinksMap resolve_symlinks_map_{CreateResolveSymlinksMap()};
/// \brief Check if commit exists and tries to get the subtree if found.
- /// \returns An error + data union, where at index 0 is a failure type flag
- /// and at index 1 is the subtree hash on success. The failure flag is false
- /// if commit was not found and true if failed otherwise.
+ /// \returns The subtree hash on success or an unexpected error (fatal or
+ /// commit was not found).
[[nodiscard]] static auto GetSubtreeFromCommit(
std::filesystem::path const& repo_path,
std::string const& commit,
std::string const& subdir,
std::shared_ptr<Logger> const& logger)
- -> std::variant<bool, std::string>;
+ -> expected<std::string, GitLookupError>;
/// \brief Check if tree exists and tries to get the subtree if found.
- /// \returns An error + data union, where at index 0 is a failure type flag
- /// and at index 1 is the subtree hash on success. The failure flag is true
- /// if repository could not be opened (i.e., fatal failure), false if the
- /// check for the subtree itself failed.
+ /// \returns The subtree hash on success or an unexpected error (fatal or
+ /// subtree not found).
[[nodiscard]] static auto GetSubtreeFromTree(
std::filesystem::path const& repo_path,
std::string const& tree_id,
std::string const& subdir,
std::shared_ptr<Logger> const& logger)
- -> std::variant<bool, std::string>;
+ -> expected<std::string, GitLookupError>;
/// \brief Tries to retrieve the blob from a repository.
- /// \returns An error + data union, where at index 0 is a failure type flag
- /// and at index 1 is the subtree hash on success. The failure flag is false
- /// if blob was not found and true if failed otherwise.
+ /// \returns The subtree hash on success or an unexpected error (fatal or
+ /// blob not found).
[[nodiscard]] static auto GetBlobFromRepo(
std::filesystem::path const& repo_path,
std::string const& blob_id,
std::shared_ptr<Logger> const& logger)
- -> std::variant<bool, std::string>;
+ -> expected<std::string, GitLookupError>;
[[nodiscard]] auto SyncArchive(std::string const& tree_id,
std::filesystem::path const& repo_path,
@@ -182,12 +179,11 @@ class SourceTreeService final
ServeArchiveTreeResponse* response) -> ::grpc::Status;
/// \brief Common import-to-git utility, used by both archives and distdirs.
- /// \returns An error + data union, where at index 0 is the error message on
- /// failure and at index 1 is the root tree id of the committed directory on
- /// success.
+ /// \returns The root tree id on of the committed directory on success or an
+ /// unexpected error as string.
[[nodiscard]] auto CommonImportToGit(std::filesystem::path const& root_path,
std::string const& commit_message)
- -> std::variant<std::string, std::string>;
+ -> expected<std::string, std::string>;
[[nodiscard]] auto ArchiveImportToGit(
std::filesystem::path const& unpack_path,
diff --git a/src/buildtool/serve_api/serve_service/target.cpp b/src/buildtool/serve_api/serve_service/target.cpp
index 341b326e..0f980f86 100644
--- a/src/buildtool/serve_api/serve_service/target.cpp
+++ b/src/buildtool/serve_api/serve_service/target.cpp
@@ -46,32 +46,34 @@
auto TargetService::GetDispatchList(
ArtifactDigest const& dispatch_digest) noexcept
- -> std::variant<::grpc::Status, dispatch_t> {
+ -> expected<dispatch_t, ::grpc::Status> {
// get blob from remote cas
auto const& dispatch_info = Artifact::ObjectInfo{.digest = dispatch_digest,
.type = ObjectType::File};
if (not apis_.local->IsAvailable(dispatch_digest) and
not apis_.remote->RetrieveToCas({dispatch_info}, *apis_.local)) {
- return ::grpc::Status{::grpc::StatusCode::FAILED_PRECONDITION,
- fmt::format("Could not retrieve blob {} from "
- "remote-execution endpoint",
- dispatch_info.ToString())};
+ return unexpected{
+ ::grpc::Status{::grpc::StatusCode::FAILED_PRECONDITION,
+ fmt::format("Could not retrieve blob {} from "
+ "remote-execution endpoint",
+ dispatch_info.ToString())}};
}
// get blob content
auto const& dispatch_str = apis_.local->RetrieveToMemory(dispatch_info);
if (not dispatch_str) {
// this should not fail unless something really broke...
- return ::grpc::Status{
+ return unexpected{::grpc::Status{
::grpc::StatusCode::INTERNAL,
fmt::format("Unexpected failure in reading blob {} from CAS",
- dispatch_info.ToString())};
+ dispatch_info.ToString())}};
}
// parse content
auto parsed = ParseDispatch(*dispatch_str);
if (not parsed) {
// pass the parsing error forward
- return ::grpc::Status{::grpc::StatusCode::FAILED_PRECONDITION,
- std::move(parsed).error()};
+ return unexpected{
+ ::grpc::Status{::grpc::StatusCode::FAILED_PRECONDITION,
+ std::move(parsed).error()}};
}
return *std::move(parsed);
}
@@ -155,14 +157,14 @@ auto TargetService::ServeTarget(
}
auto const& dispatch_info_digest = ArtifactDigest{request->dispatch_info()};
auto res = GetDispatchList(dispatch_info_digest);
- if (res.index() == 0) {
- auto err = std::get<0>(res);
+ if (not res) {
+ auto err = move(res).error();
logger_->Emit(LogLevel::Error, "{}", err.error_message());
return err;
}
// keep dispatch list, as it needs to be passed to the executor (via the
// graph_traverser)
- auto dispatch_list = std::get<1>(res);
+ auto dispatch_list = *res;
// parse dispatch list to json and add to description
auto dispatch_json = nlohmann::json::array();
try {
diff --git a/src/buildtool/serve_api/serve_service/target.hpp b/src/buildtool/serve_api/serve_service/target.hpp
index 7b1d0ec9..5301b82c 100644
--- a/src/buildtool/serve_api/serve_service/target.hpp
+++ b/src/buildtool/serve_api/serve_service/target.hpp
@@ -21,7 +21,6 @@
#include <optional>
#include <string>
#include <utility>
-#include <variant>
#include <vector>
#include "gsl/gsl"
@@ -35,6 +34,7 @@
#include "src/buildtool/logging/logger.hpp"
#include "src/buildtool/serve_api/remote/config.hpp"
#include "src/buildtool/serve_api/remote/serve_api.hpp"
+#include "src/utils/cpp/expected.hpp"
// The target-level cache service.
class TargetService final : public justbuild::just_serve::Target::Service {
@@ -132,11 +132,11 @@ class TargetService final : public justbuild::just_serve::Target::Service {
/// \brief Get from remote and parse the endpoint configuration. The method
/// also ensures the content has the expected format.
- /// \returns An error + data union, with a pair of grpc status at index 0
- /// and the dispatch list stored as a JSON object at index 1.
+ /// \returns The dispatch list stored as JSON object on success or an
+ /// unexpected error as grpc::Status.
[[nodiscard]] auto GetDispatchList(
ArtifactDigest const& dispatch_digest) noexcept
- -> std::variant<::grpc::Status, dispatch_t>;
+ -> expected<dispatch_t, ::grpc::Status>;
/// \brief Handles the processing of the log after a failed analysis or
/// build. Will populate the response as needed and set the status to be