diff options
author | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2024-04-08 10:44:53 +0200 |
---|---|---|
committer | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2024-04-10 15:25:45 +0200 |
commit | 327b74ed6a94f3eb69a6b49bac3395b7203ce580 (patch) | |
tree | b830cabaa364de77ff0aebedbc513f7839ecd49f /src/buildtool/serve_api/serve_service/source_tree.cpp | |
parent | c60eb6dfb22f28f638caff578b8815d3c4753bdc (diff) | |
download | justbuild-327b74ed6a94f3eb69a6b49bac3395b7203ce580.tar.gz |
just-mr: Ensure resolved trees are kept alive in Git cache
The association map file for a resolved tree was supposed to
guarantee that the respective tree is kept alive in a Git
repository as part of a tagged commit.
This commit fixes this issue by tagging the tree (found in the Git
cache after resolution) before writing its association file.
Diffstat (limited to 'src/buildtool/serve_api/serve_service/source_tree.cpp')
-rw-r--r-- | src/buildtool/serve_api/serve_service/source_tree.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/buildtool/serve_api/serve_service/source_tree.cpp b/src/buildtool/serve_api/serve_service/source_tree.cpp index 4eeadf3f..e1e8ae57 100644 --- a/src/buildtool/serve_api/serve_service/source_tree.cpp +++ b/src/buildtool/serve_api/serve_service/source_tree.cpp @@ -456,7 +456,39 @@ auto SourceTreeService::ResolveContentTree( response->set_status(ServeArchiveTreeResponse::RESOLVE_ERROR); return ::grpc::Status::OK; } - // cache the resolved tree + // keep tree alive in the Git cache via a tagged commit + auto wrapped_logger = std::make_shared<GitRepo::anon_logger_t>( + [logger = logger_, resolved_tree](auto const& msg, bool fatal) { + if (fatal) { + logger->Emit(LogLevel::Error, + fmt::format("While keeping tree {} in " + "repository {}:\n{}", + resolved_tree.id, + StorageConfig::GitRoot().string(), + msg)); + } + }); + { + // this is a non-thread-safe Git operation, so it must be guarded! + std::shared_lock slock{mutex_}; + // 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()); + logger_->Emit(LogLevel::Error, str); + response->set_status(ServeArchiveTreeResponse::RESOLVE_ERROR); + return ::grpc::Status::OK; + } + // Important: message must be consistent with just-mr! + if (not git_repo->KeepTree(resolved_tree.id, + "Keep referenced tree alive", // message + wrapped_logger)) { + response->set_status(ServeArchiveTreeResponse::RESOLVE_ERROR); + return ::grpc::Status::OK; + } + } + // cache the resolved tree association if (not StorageUtils::WriteTreeIDFile(tree_id_file, resolved_tree.id)) { auto str = fmt::format("Failed to write resolved tree id to file {}", |