]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Fetch/update secondary storage manifest on primary miss (#1065)
authorbengtj <2410396+bengtj@users.noreply.github.com>
Tue, 7 Jun 2022 08:53:07 +0000 (10:53 +0200)
committerGitHub <noreply@github.com>
Tue, 7 Jun 2022 08:53:07 +0000 (10:53 +0200)
src/ccache.cpp
src/storage/Storage.cpp
src/storage/Storage.hpp

index bdc87290250fe78b48894f8243fe40d618bcda4f..db93bc8d786e64ed1274d6e6183fe49e79faa094 100644 (file)
@@ -1791,8 +1791,9 @@ calculate_result_and_manifest_key(Context& ctx,
 
     manifest_key = hash.digest();
 
-    const auto manifest_path =
-      ctx.storage.get(*manifest_key, core::CacheEntryType::manifest);
+    auto manifest_path = ctx.storage.get(*manifest_key,
+                                         core::CacheEntryType::manifest,
+                                         storage::Storage::Mode::primary_only);
 
     if (manifest_path) {
       LOG("Looking for result key in {}", *manifest_path);
@@ -1810,6 +1811,30 @@ calculate_result_and_manifest_key(Context& ctx,
         LOG_RAW("Did not find result key in manifest");
       }
     }
+    // Check secondary storage if not found in primary
+    if (!result_key) {
+      manifest_path = ctx.storage.get(*manifest_key,
+                                      core::CacheEntryType::manifest,
+                                      storage::Storage::Mode::secondary_only);
+      if (manifest_path) {
+        LOG("Looking for result key in fetched secondary manifest {}",
+            *manifest_path);
+        MTR_BEGIN("manifest", "secondary_manifest_get");
+        try {
+          const auto manifest = read_manifest(*manifest_path);
+          result_key = manifest.look_up_result_digest(ctx);
+        } catch (const core::Error& e) {
+          LOG(
+            "Failed to look up result key in {}: {}", *manifest_path, e.what());
+        }
+        MTR_END("manifest", "secondary_manifest_get");
+        if (result_key) {
+          LOG_RAW("Got result key from fetched secondary manifest");
+        } else {
+          LOG_RAW("Did not find result key in fetched secondary manifest");
+        }
+      }
+    }
   } else if (ctx.args_info.arch_args.empty()) {
     const auto digest = get_result_key_from_cpp(ctx, preprocessor_args, hash);
     if (!digest) {
index 957c71aaccc7ce55f142705a06f569fe3a5520ba..d1aa4fb30e7682166474025463e72516d1b49743 100644 (file)
@@ -228,34 +228,42 @@ Storage::finalize()
 }
 
 std::optional<std::string>
-Storage::get(const Digest& key, const core::CacheEntryType type)
+Storage::get(const Digest& key,
+             const core::CacheEntryType type,
+             const Mode mode)
 {
   MTR_SCOPE("storage", "get");
 
-  auto path = primary.get(key, type);
-  primary.increment_statistic(path ? core::Statistic::primary_storage_hit
-                                   : core::Statistic::primary_storage_miss);
-  if (path) {
-    if (m_config.reshare()) {
-      // Temporary optimization until primary storage API has been refactored to
-      // pass data via memory instead of files.
-      const bool should_put_in_secondary_storage =
-        std::any_of(m_secondary_storages.begin(),
-                    m_secondary_storages.end(),
-                    [](const auto& entry) { return !entry->config.read_only; });
-      if (should_put_in_secondary_storage) {
-        std::string value;
-        try {
-          value = Util::read_file(*path);
-        } catch (const core::Error& e) {
-          LOG("Failed to read {}: {}", *path, e.what());
-          return path; // Don't indicate failure since primary storage was OK.
+  if (mode != Mode::secondary_only) {
+    const auto path = primary.get(key, type);
+    primary.increment_statistic(path ? core::Statistic::primary_storage_hit
+                                     : core::Statistic::primary_storage_miss);
+    if (path) {
+      if (m_config.reshare()) {
+        // Temporary optimization until primary storage API has been refactored
+        // to pass data via memory instead of files.
+        const bool should_put_in_secondary_storage = std::any_of(
+          m_secondary_storages.begin(),
+          m_secondary_storages.end(),
+          [](const auto& entry) { return !entry->config.read_only; });
+        if (should_put_in_secondary_storage) {
+          std::string value;
+          try {
+            value = Util::read_file(*path);
+          } catch (const core::Error& e) {
+            LOG("Failed to read {}: {}", *path, e.what());
+            return path; // Don't indicate failure since primary storage was OK.
+          }
+          put_in_secondary_storage(key, value, true);
         }
-        put_in_secondary_storage(key, value, true);
       }
+
+      return path;
     }
+  }
 
-    return path;
+  if (mode == Mode::primary_only) {
+    return std::nullopt;
   }
 
   const auto value_and_share_hits = get_from_secondary_storage(key);
index 5593e03c334d1feee9c7b58812b9f4eaa9a52838..4a18aeeb295eabc3e377af179576fdbacaf7eb71 100644 (file)
@@ -51,7 +51,10 @@ public:
   primary::PrimaryStorage primary;
 
   // Returns a path to a file containing the value.
-  std::optional<std::string> get(const Digest& key, core::CacheEntryType type);
+  enum class Mode { secondary_fallback, secondary_only, primary_only };
+  std::optional<std::string> get(const Digest& key,
+                                 core::CacheEntryType type,
+                                 const Mode mode = Mode::secondary_fallback);
 
   bool put(const Digest& key,
            core::CacheEntryType type,