could_not_use_modules = 32,
direct_cache_miss = 33,
preprocessed_cache_miss = 34,
+ primary_storage_hit = 35,
+ primary_storage_miss = 36,
+ secondary_storage_hit = 37,
+ secondary_storage_miss = 38,
+ secondary_storage_error = 39,
+ secondary_storage_timeout = 40,
END
};
STATISTICS_FIELD(cache_miss, "cache miss", FLAG_ALWAYS),
STATISTICS_FIELD(direct_cache_miss, "cache miss (direct)"),
STATISTICS_FIELD(preprocessed_cache_miss, "cache miss (preprocessed)"),
+ STATISTICS_FIELD(primary_storage_hit, "primary storage hit"),
+ STATISTICS_FIELD(primary_storage_miss, "primary storage miss"),
+ STATISTICS_FIELD(secondary_storage_hit, "secondary storage hit"),
+ STATISTICS_FIELD(secondary_storage_miss, "secondary storage miss"),
+ STATISTICS_FIELD(secondary_storage_error, "secondary storage error"),
+ STATISTICS_FIELD(secondary_storage_timeout, "secondary storage timeout"),
STATISTICS_FIELD(called_for_link, "called for link"),
STATISTICS_FIELD(called_for_preprocessing, "called for preprocessing"),
STATISTICS_FIELD(multiple_source_files, "multiple source files"),
#include <TemporaryFile.hpp>
#include <Util.hpp>
#include <assertions.hpp>
+#include <core/Statistic.hpp>
#include <core/exceptions.hpp>
#include <fmtmacros.hpp>
#include <storage/secondary/FileStorage.hpp>
#ifdef HAVE_REDIS_STORAGE_BACKEND
# include <storage/secondary/RedisStorage.hpp>
#endif
-#include <storage/secondary/SecondaryStorage.hpp>
#include <util/Timer.hpp>
#include <util/Tokenizer.hpp>
#include <util/expected.hpp>
{
const auto path = primary.get(key, type);
if (path) {
+ primary.increment_statistic(core::Statistic::primary_storage_hit);
return path;
}
+ primary.increment_statistic(core::Statistic::primary_storage_miss);
+
const auto value = get_from_secondary_storage(key);
if (!value) {
return nonstd::nullopt;
}
}
-static void
-mark_backend_as_failed(
+void
+Storage::mark_backend_as_failed(
SecondaryStorageBackendEntry& backend_entry,
const secondary::SecondaryStorage::Backend::Failure failure)
{
// The backend is expected to log details about the error.
backend_entry.failed = true;
- (void)failure; // TODO: Update statistics.
+ primary.increment_statistic(
+ failure == secondary::SecondaryStorage::Backend::Failure::timeout
+ ? core::Statistic::secondary_storage_timeout
+ : core::Statistic::secondary_storage_error);
}
static double
return util::replace_first(url, "*", best_shard);
}
-static SecondaryStorageBackendEntry*
-get_backend(SecondaryStorageEntry& entry,
- const Digest& key,
- nonstd::string_view operation_description,
- const bool for_writing)
+SecondaryStorageBackendEntry*
+Storage::get_backend(SecondaryStorageEntry& entry,
+ const Digest& key,
+ const nonstd::string_view operation_description,
+ const bool for_writing)
{
if (for_writing && entry.config.read_only) {
LOG("Not {} {} since it is read-only",
key.to_string(),
backend->url_for_logging,
ms);
+ primary.increment_statistic(core::Statistic::secondary_storage_hit);
return *value;
} else {
LOG("No {} in {} ({:.2f} ms)",
key.to_string(),
backend->url_for_logging,
ms);
+ primary.increment_statistic(core::Statistic::secondary_storage_miss);
}
}
#include <core/types.hpp>
#include <storage/primary/PrimaryStorage.hpp>
+#include <storage/secondary/SecondaryStorage.hpp>
#include <storage/types.hpp>
#include <third_party/nonstd/optional.hpp>
std::string get_features();
+struct SecondaryStorageBackendEntry;
struct SecondaryStorageEntry;
class Storage
std::vector<std::string> m_tmp_files;
void add_secondary_storages();
+
+ void
+ mark_backend_as_failed(SecondaryStorageBackendEntry& backend_entry,
+ secondary::SecondaryStorage::Backend::Failure failure);
+
+ SecondaryStorageBackendEntry*
+ get_backend(SecondaryStorageEntry& entry,
+ const Digest& key,
+ nonstd::string_view operation_description,
+ const bool for_writing);
nonstd::optional<std::string> get_from_secondary_storage(const Digest& key);
+
void put_in_secondary_storage(const Digest& key, const std::string& value);
+
void remove_from_secondary_storage(const Digest& key);
};
expect_stat cache_miss 1
expect_stat direct_cache_miss 0
expect_stat preprocessed_cache_miss 1
+ expect_stat primary_storage_hit 0
+ expect_stat primary_storage_miss 1
+ expect_stat secondary_storage_hit 0
+ expect_stat secondary_storage_miss 0
expect_stat files_in_cache 1
expect_equal_object_files reference_test1.o test1.o
expect_stat cache_miss 1
expect_stat direct_cache_miss 0
expect_stat preprocessed_cache_miss 1
+ expect_stat primary_storage_hit 1
+ expect_stat primary_storage_miss 1
+ expect_stat secondary_storage_hit 0
+ expect_stat secondary_storage_miss 0
expect_stat files_in_cache 1
expect_equal_object_files reference_test1.o test1.o
expect_stat cache_miss 1
expect_stat direct_cache_miss 1
expect_stat preprocessed_cache_miss 1
+ expect_stat primary_storage_hit 0
+ expect_stat primary_storage_miss 2 # result + manifest
+ expect_stat secondary_storage_hit 0
+ expect_stat secondary_storage_miss 0
expect_stat files_in_cache 2 # result + manifest
expect_equal_object_files reference_test.o test.o
expect_stat cache_miss 1
expect_stat direct_cache_miss 1
expect_stat preprocessed_cache_miss 1
+ expect_stat primary_storage_hit 2 # result + manifest
+ expect_stat primary_storage_miss 2 # result + manifest
+ expect_stat secondary_storage_hit 0
+ expect_stat secondary_storage_miss 0
expect_stat files_in_cache 2
expect_equal_object_files reference_test.o test.o
expect_newer_than $manifest_file test.c
SUITE_secondary_file() {
# -------------------------------------------------------------------------
- TEST "Subdirs layout"
+ TEST "Base case"
$CCACHE_COMPILE -c test.c
expect_stat direct_cache_hit 0
expect_stat cache_miss 1
expect_stat files_in_cache 2
+ expect_stat primary_storage_hit 0
+ expect_stat primary_storage_miss 2 # result + manifest
+ expect_stat secondary_storage_hit 0
+ expect_stat secondary_storage_miss 2 # result + manifest
expect_exists secondary/CACHEDIR.TAG
subdirs=$(find secondary -type d | wc -l)
if [ "${subdirs}" -lt 2 ]; then # "secondary" itself counts as one
$CCACHE_COMPILE -c test.c
expect_stat direct_cache_hit 1
expect_stat cache_miss 1
+ expect_stat primary_storage_hit 2 # result + manifest
+ expect_stat primary_storage_miss 2 # result + manifest
+ expect_stat secondary_storage_hit 0
+ expect_stat secondary_storage_miss 2 # result + manifest
expect_stat files_in_cache 2
expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
$CCACHE_COMPILE -c test.c
expect_stat direct_cache_hit 2
expect_stat cache_miss 1
+ expect_stat primary_storage_hit 2
+ expect_stat primary_storage_miss 4 # 2 * (result + manifest)
+ expect_stat secondary_storage_hit 2 # result + manifest
+ expect_stat secondary_storage_miss 2 # result + manifest
expect_stat files_in_cache 2 # fetched from secondary
expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
cache_miss
direct_cache_miss
preprocessed_cache_miss
+primary_storage_miss
# test.c
-direct_cache_hit"
+direct_cache_hit
+primary_storage_hit"
}