10#include <unordered_set> 
   12#include <userver/cache/update_type.hpp> 
   13#include <userver/components/component_fwd.hpp> 
   14#include <userver/components/state.hpp> 
   15#include <userver/utils/assert.hpp> 
   17USERVER_NAMESPACE_BEGIN
 
   31enum class PeriodicUpdatesMode { kDefault, kEnabled, kDisabled };
 
   34class CacheResetRegistration;
 
   54class CacheControl 
final {
 
   62      const std::unordered_set<std::string>& force_incremental_names,
 
   63      const std::unordered_set<std::string>& exclude_names);
 
   71      std::unordered_set<std::string> reset_only_names,
 
   72      const std::unordered_set<std::string>& force_incremental_names);
 
   74  CacheControl(CacheControl&&) = 
delete;
 
   75  CacheControl& operator=(CacheControl&&) = 
delete;
 
   80    explicit UnitTests() = 
default;
 
   83  enum class ExecPolicy {
 
   88  CacheControl(impl::PeriodicUpdatesMode, UnitTests);
 
   89  CacheControl(impl::PeriodicUpdatesMode, ExecPolicy, 
components::State);
 
   93  bool IsPeriodicUpdateEnabled(
const cache::Config& cache_config,
 
   94                               const std::string& cache_name) 
const;
 
   97  CacheResetRegistration RegisterPeriodicCache(cache::
CacheUpdateTrait& cache);
 
  100  template <
typename Component>
 
  101  CacheResetRegistration RegisterCache(Component* self, std::string_view name,
 
  102                                       void (Component::*reset_method)());
 
  105  friend class CacheResetRegistration;
 
  107  struct CacheInfo 
final {
 
  110    bool needs_span{
true};
 
  113  struct CacheInfoNode;
 
  114  using CacheInfoIterator = CacheInfoNode*;
 
  119      std::unordered_set<std::string>* reset_only_names,
 
  120      const std::unordered_set<std::string>& force_incremental_names,
 
  121      const std::unordered_set<std::string>* exclude_names);
 
  123  void DoResetCachesConcurrently(
 
  125      std::unordered_set<std::string>* reset_only_names,
 
  126      const std::unordered_set<std::string>& force_incremental_names,
 
  127      const std::unordered_set<std::string>* exclude_names);
 
  129  CacheInfoIterator DoRegisterCache(CacheInfo&& info);
 
  131  void UnregisterCache(CacheInfoIterator) 
noexcept;
 
  133  static void DoResetSingleCache(
 
  134      const CacheInfo& info, cache::
UpdateType update_type,
 
  135      const std::unordered_set<std::string>& force_incremental_names);
 
  138  std::unique_ptr<Impl> impl_;
 
  146class [[nodiscard]] CacheResetRegistration 
final {
 
  148  CacheResetRegistration() 
noexcept;
 
  150  CacheResetRegistration(CacheResetRegistration&&) 
noexcept;
 
  151  CacheResetRegistration& operator=(CacheResetRegistration&&) 
noexcept;
 
  152  ~CacheResetRegistration();
 
  160  CacheResetRegistration(CacheControl&, CacheControl::CacheInfoIterator);
 
  164  CacheControl* cache_control_{
nullptr};
 
  165  CacheControl::CacheInfoIterator cache_info_iterator_{};
 
  179template <
typename Component>
 
  182    const components::ComponentContext& context, Component* self,
 
  183    void (Component::*reset_method)()) {
 
  189template <
typename Component>
 
  190CacheResetRegistration CacheControl::RegisterCache(
 
  191    Component* self, std::string_view name, 
void (Component::*reset_method)()) {
 
  192  static_assert(std::is_base_of_v<
components::impl::ComponentBase, Component>,
 
  193                "CacheControl can only be used with components");
 
  198  info.name = std::string{name};
 
  199  info.reset = [self, reset_method]([[maybe_unused]] cache::
UpdateType) {
 
  200    (self->*reset_method)();
 
  202  info.needs_span = 
true;
 
  204  auto iter = DoRegisterCache(std::move(info));
 
  205  return CacheResetRegistration(*
this, std::move(iter));