summaryrefslogtreecommitdiff
path: root/src/buildtool/execution_api/local/local_ac.hpp
blob: 7800d16fd0f6a3e5351f847601a265333cb1b452 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_AC_HPP
#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_AC_HPP

#include "gsl-lite/gsl-lite.hpp"
#include "src/buildtool/common/bazel_types.hpp"
#include "src/buildtool/execution_api/common/execution_common.hpp"
#include "src/buildtool/execution_api/local/config.hpp"
#include "src/buildtool/execution_api/local/local_cas.hpp"
#include "src/buildtool/file_system/file_storage.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
#include "src/buildtool/logging/logger.hpp"

class LocalAC {
  public:
    explicit LocalAC(gsl::not_null<LocalCAS<ObjectType::File>*> cas) noexcept
        : cas_{std::move(cas)} {};

    LocalAC(LocalAC const&) = delete;
    LocalAC(LocalAC&&) = delete;
    auto operator=(LocalAC const&) -> LocalAC& = delete;
    auto operator=(LocalAC&&) -> LocalAC& = delete;
    ~LocalAC() noexcept = default;

    [[nodiscard]] auto StoreResult(
        bazel_re::Digest const& action_id,
        bazel_re::ActionResult const& result) const noexcept -> bool {
        auto bytes = result.SerializeAsString();
        auto digest = cas_->StoreBlobFromBytes(bytes);
        return (digest and file_store_.AddFromBytes(
                               NativeSupport::Unprefix(action_id.hash()),
                               digest->SerializeAsString()));
    }

    [[nodiscard]] auto CachedResult(bazel_re::Digest const& action_id)
        const noexcept -> std::optional<bazel_re::ActionResult> {
        auto entry_path =
            file_store_.GetPath(NativeSupport::Unprefix(action_id.hash()));
        bazel_re::Digest digest{};
        auto const entry =
            FileSystemManager::ReadFile(entry_path, ObjectType::File);
        if (not entry.has_value()) {
            logger_.Emit(LogLevel::Debug,
                         "Cache miss, entry not found {}",
                         entry_path.string());
            return std::nullopt;
        }
        if (not digest.ParseFromString(*entry)) {
            logger_.Emit(LogLevel::Warning,
                         "Parsing cache entry failed for action {}",
                         NativeSupport::Unprefix(action_id.hash()));
            return std::nullopt;
        }
        auto src_path = cas_->BlobPath(digest);
        bazel_re::ActionResult result{};
        if (src_path) {
            auto const bytes = FileSystemManager::ReadFile(*src_path);
            if (bytes.has_value() and result.ParseFromString(*bytes)) {
                return result;
            }
        }
        logger_.Emit(LogLevel::Warning,
                     "Parsing action result failed for action {}",
                     NativeSupport::Unprefix(action_id.hash()));
        return std::nullopt;
    }

  private:
    // The action cache stores the results of failed actions. For those to be
    // overwritable by subsequent runs we need to choose the store mode "last
    // wins" for the underlying file storage.
    static constexpr auto kStoreMode = StoreMode::LastWins;

    Logger logger_{"LocalAC"};
    gsl::not_null<LocalCAS<ObjectType::File>*> cas_;
    FileStorage<ObjectType::File, kStoreMode, /*kSetEpochTime=*/false>
        file_store_{LocalExecutionConfig::ActionCacheDir()};
};

#endif  // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_AC_HPP