LCOV - code coverage report
Current view: top level - source/extensions/http/cache/file_system_http_cache - config.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 4 48 8.3 %
Date: 2024-01-05 06:35:25 Functions: 2 7 28.6 %

          Line data    Source code
       1             : #include <memory>
       2             : #include <string>
       3             : 
       4             : #include "envoy/extensions/http/cache/file_system_http_cache/v3/file_system_http_cache.pb.h"
       5             : #include "envoy/extensions/http/cache/file_system_http_cache/v3/file_system_http_cache.pb.validate.h"
       6             : #include "envoy/registry/registry.h"
       7             : 
       8             : #include "source/extensions/common/async_files/async_file_manager_factory.h"
       9             : #include "source/extensions/filters/http/cache/http_cache.h"
      10             : #include "source/extensions/http/cache/file_system_http_cache/cache_eviction_thread.h"
      11             : #include "source/extensions/http/cache/file_system_http_cache/file_system_http_cache.h"
      12             : 
      13             : namespace Envoy {
      14             : namespace Extensions {
      15             : namespace HttpFilters {
      16             : namespace Cache {
      17             : namespace FileSystemHttpCache {
      18             : namespace {
      19             : 
      20             : /**
      21             :  * Returns a copy of the original ConfigProto with a slash appended to cache_path
      22             :  * if one was not present.
      23             :  * @param original the original ConfigProto.
      24             :  * @return the normalized ConfigProto.
      25             :  */
      26           0 : ConfigProto normalizeConfig(const ConfigProto& original) {
      27           0 :   ConfigProto config = original;
      28           0 :   if (!absl::EndsWith(config.cache_path(), "/") && !absl::EndsWith(config.cache_path(), "\\")) {
      29           0 :     config.set_cache_path(absl::StrCat(config.cache_path(), "/"));
      30           0 :   }
      31           0 :   return config;
      32           0 : }
      33             : 
      34             : /**
      35             :  * A singleton that acts as a factory for generating and looking up FileSystemHttpCaches.
      36             :  * When given equivalent configs, the singleton returns pointers to the same cache.
      37             :  * When given different configs, the singleton returns different cache instances.
      38             :  * If given configs with the same cache_path but different configuration,
      39             :  * an exception is thrown, as it doesn't make sense two operate two caches in the
      40             :  * same path with different configurations.
      41             :  */
      42             : class CacheSingleton : public Envoy::Singleton::Instance {
      43             : public:
      44             :   CacheSingleton(
      45             :       std::shared_ptr<Common::AsyncFiles::AsyncFileManagerFactory>&& async_file_manager_factory,
      46             :       Thread::ThreadFactory& thread_factory)
      47             :       : async_file_manager_factory_(async_file_manager_factory),
      48           0 :         cache_eviction_thread_(thread_factory) {}
      49             : 
      50             :   std::shared_ptr<FileSystemHttpCache> get(std::shared_ptr<CacheSingleton> singleton,
      51             :                                            const ConfigProto& non_normalized_config,
      52           0 :                                            Stats::Scope& stats_scope) {
      53           0 :     std::shared_ptr<FileSystemHttpCache> cache;
      54           0 :     ConfigProto config = normalizeConfig(non_normalized_config);
      55           0 :     auto key = config.cache_path();
      56           0 :     absl::MutexLock lock(&mu_);
      57           0 :     auto it = caches_.find(key);
      58           0 :     if (it != caches_.end()) {
      59           0 :       cache = it->second.lock();
      60           0 :     }
      61           0 :     if (!cache) {
      62           0 :       std::shared_ptr<Common::AsyncFiles::AsyncFileManager> async_file_manager =
      63           0 :           async_file_manager_factory_->getAsyncFileManager(config.manager_config());
      64           0 :       cache = std::make_shared<FileSystemHttpCache>(singleton, cache_eviction_thread_,
      65           0 :                                                     std::move(config),
      66           0 :                                                     std::move(async_file_manager), stats_scope);
      67           0 :       caches_[key] = cache;
      68           0 :     } else if (!Protobuf::util::MessageDifferencer::Equals(cache->config(), config)) {
      69           0 :       throw EnvoyException(
      70           0 :           fmt::format("mismatched FileSystemHttpCacheConfig with same path\n{}\nvs.\n{}",
      71           0 :                       cache->config().DebugString(), config.DebugString()));
      72           0 :     }
      73           0 :     return cache;
      74           0 :   }
      75             : 
      76             : private:
      77             :   std::shared_ptr<Common::AsyncFiles::AsyncFileManagerFactory> async_file_manager_factory_;
      78             :   CacheEvictionThread cache_eviction_thread_;
      79             :   absl::Mutex mu_;
      80             :   // We keep weak_ptr here so the caches can be destroyed if the config is updated to stop using
      81             :   // that config of cache. The caches each keep shared_ptrs to this singleton, which keeps the
      82             :   // singleton from being destroyed unless it's no longer keeping track of any caches.
      83             :   // (The singleton shared_ptr is *only* held by cache instances.)
      84             :   absl::flat_hash_map<std::string, std::weak_ptr<FileSystemHttpCache>> caches_ ABSL_GUARDED_BY(mu_);
      85             : };
      86             : 
      87             : SINGLETON_MANAGER_REGISTRATION(file_system_http_cache_singleton);
      88             : 
      89             : class FileSystemHttpCacheFactory : public HttpCacheFactory {
      90             : public:
      91             :   // From UntypedFactory
      92          38 :   std::string name() const override { return std::string{FileSystemHttpCache::name()}; }
      93             :   // From TypedFactory
      94           1 :   ProtobufTypes::MessagePtr createEmptyConfigProto() override {
      95           1 :     return std::make_unique<ConfigProto>();
      96           1 :   }
      97             :   // From HttpCacheFactory
      98             :   std::shared_ptr<HttpCache>
      99             :   getCache(const envoy::extensions::filters::http::cache::v3::CacheConfig& filter_config,
     100           0 :            Server::Configuration::FactoryContext& context) override {
     101           0 :     ConfigProto config;
     102           0 :     MessageUtil::unpackTo(filter_config.typed_config(), config);
     103           0 :     std::shared_ptr<CacheSingleton> caches =
     104           0 :         context.serverFactoryContext().singletonManager().getTyped<CacheSingleton>(
     105           0 :             SINGLETON_MANAGER_REGISTERED_NAME(file_system_http_cache_singleton), [&context] {
     106           0 :               return std::make_shared<CacheSingleton>(
     107           0 :                   Common::AsyncFiles::AsyncFileManagerFactory::singleton(
     108           0 :                       &context.serverFactoryContext().singletonManager()),
     109           0 :                   context.serverFactoryContext().api().threadFactory());
     110           0 :             });
     111           0 :     return caches->get(caches, config, context.scope());
     112           0 :   }
     113             : };
     114             : 
     115             : static Registry::RegisterFactory<FileSystemHttpCacheFactory, HttpCacheFactory> register_;
     116             : 
     117             : } // namespace
     118             : } // namespace FileSystemHttpCache
     119             : } // namespace Cache
     120             : } // namespace HttpFilters
     121             : } // namespace Extensions
     122             : } // namespace Envoy

Generated by: LCOV version 1.15