userver: userver/dynamic_config/updater/component.hpp Source File
Loading...
Searching...
No Matches
component.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/dynamic_config/updater/component.hpp
4/// @brief @copybrief components::DynamicConfigClientUpdater
5
6#include <chrono>
7#include <functional>
8#include <optional>
9#include <string>
10#include <unordered_set>
11
12#include <userver/cache/cache_statistics.hpp>
13#include <userver/cache/caching_component_base.hpp>
14#include <userver/cache/update_type.hpp>
15#include <userver/components/component_fwd.hpp>
16#include <userver/concurrent/variable.hpp>
17#include <userver/dynamic_config/client/client.hpp>
18#include <userver/dynamic_config/storage/component.hpp>
19#include <userver/dynamic_config/updater/additional_keys_token.hpp>
20#include <userver/dynamic_config/updates_sink/component.hpp>
21#include <userver/engine/mutex.hpp>
22#include <userver/utils/impl/transparent_hash.hpp>
23
24USERVER_NAMESPACE_BEGIN
25
26namespace components {
27
28/// @ingroup userver_components
29///
30/// @brief Component that does a periodic update of runtime configs.
31///
32/// Note that the service with dynamic config update component and without
33/// configs cache requires successful update to start. See @ref dynamic_config_fallback for details and explanation.
34///
35/// ## Optional update event deduplication
36///
37/// Config update types to deduplicate. If enabled, JSON of the whole config is
38/// compared to the previous one; if same, no config update event is sent to the
39/// subscribers of dynamic_config::Source (`OnConfigUpdate` functions).
40///
41/// `deduplicate-update-types` static config option specifies the update types
42/// of the config cache, for which event deduplication should be performed.
43/// Possible values:
44/// - `none` (the default)
45/// - `only-full`
46/// - `only-incremental`
47/// - `full-and-incremental`
48///
49/// Full updates will always send an event unless deduplicated. Incremental
50/// updates may send an extra event for some config service implementations.
51///
52/// Note: This is not a silver bullet against extra events, because the events
53/// will be sent to every dynamic config subscriber if *any* part of the config
54/// has updated, not if the interesting part has updated.
55///
56/// ## Static options @ref components::DynamicConfigClientUpdater :
57/// @include{doc} scripts/docs/en/components_schema/core/src/dynamic_config/updater/component.md
58///
59/// Options inherited from @ref components::CachingComponentBase :
60/// @include{doc} scripts/docs/en/components_schema/core/src/cache/caching_component_base.md
61///
62/// Options inherited from @ref components::ComponentBase :
63/// @include{doc} scripts/docs/en/components_schema/core/src/components/impl/component_base.md
64///
65/// See also the options for components::CachingComponentBase.
66///
67/// ## Static configuration example:
68///
69/// @snippet components/common_component_list_test.cpp Sample dynamic config client updater component config
70class DynamicConfigClientUpdater final : public CachingComponentBase<dynamic_config::DocsMap> {
71public:
72 /// @ingroup userver_component_names
73 /// @brief The default name of @ref components::DynamicConfigClientUpdater
74 static constexpr std::string_view kName = "dynamic-config-client-updater";
75
76 DynamicConfigClientUpdater(const ComponentConfig&, const ComponentContext&);
77
78 ~DynamicConfigClientUpdater() override;
79
80 // After calling this method, `Get()` will return a dynamic_config containing
81 // the specified keys while the token that this method returned is alive.
82 dynamic_config::AdditionalKeysToken SetAdditionalKeys(std::vector<std::string> keys);
83
84 static yaml_config::Schema GetStaticConfigSchema();
85
86private:
87 void
88 Update(cache::UpdateType update_type, const std::chrono::system_clock::time_point& last_update, const std::chrono::system_clock::time_point& now, cache::UpdateStatisticsScope&)
89 override;
90
91 void UpdateFull(const std::vector<std::string>& docs_map_keys, cache::UpdateStatisticsScope&);
92
93 void UpdateIncremental(const std::vector<std::string>& docs_map_keys, cache::UpdateStatisticsScope&);
94
95 void SetDisabledKillSwitchesToDefault(
96 dynamic_config::DocsMap& docs_map,
97 const std::vector<std::string>& kill_switches_disabled
98 );
99
100 dynamic_config::DocsMap MergeDocsMap(
101 const dynamic_config::DocsMap& current,
102 dynamic_config::DocsMap&& update,
103 const std::vector<std::string>& removed
104 );
105 void StoreIfEnabled(const dynamic_config::DocsMap& value);
106
107 using DocsMapKeys = utils::impl::TransparentSet<std::string>;
108 using AdditionalDocsMapKeys = std::unordered_set<std::shared_ptr<std::vector<std::string>>>;
109
110 std::vector<std::string> GetDocsMapKeysToFetch(AdditionalDocsMapKeys& additional_docs_map_keys);
111
112 void UpdateAdditionalKeys(const std::vector<std::string>& keys);
113
114 bool IsDuplicate(cache::UpdateType update_type, const dynamic_config::DocsMap& new_value) const;
115
116 DynamicConfigUpdatesSinkBase& updates_sink_;
117 const bool load_only_my_values_;
118 const bool store_enabled_;
119 const std::optional<cache::AllowedUpdateTypes> deduplicate_update_types_;
120 dynamic_config::Client& config_client_;
121
122 dynamic_config::Client::Timestamp server_timestamp_;
123 // for atomic updates of cached data
124 engine::Mutex update_config_mutex_;
125 dynamic_config::DocsMap docs_map_defaults_;
126 DocsMapKeys docs_map_keys_;
127 concurrent::Variable<AdditionalDocsMapKeys> additional_docs_map_keys_;
128};
129
130template <>
131inline constexpr bool kHasValidate<DynamicConfigClientUpdater> = true;
132
133} // namespace components
134
135USERVER_NAMESPACE_END