diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/serve_api/serve_service/TARGETS | 3 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/source_tree.cpp | 158 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/source_tree.hpp | 32 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/target.cpp | 26 | ||||
-rw-r--r-- | src/buildtool/serve_api/serve_service/target.hpp | 8 |
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 |