userver: userver/dump/dumper.hpp Source File
Loading...
Searching...
No Matches
dumper.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/dump/dumper.hpp
4/// @brief @copybrief dump::Dumper
5
6#include <chrono>
7#include <memory>
8#include <optional>
9#include <string>
10
11#include <userver/components/component_fwd.hpp>
12#include <userver/dump/helpers.hpp>
13#include <userver/dump/operations.hpp>
14#include <userver/dynamic_config/fwd.hpp>
15#include <userver/engine/task/task_processor_fwd.hpp>
16#include <userver/utils/fast_pimpl.hpp>
17#include <userver/yaml_config/fwd.hpp>
18
19USERVER_NAMESPACE_BEGIN
20
21namespace utils::statistics {
22class Storage;
23} // namespace utils::statistics
24
25namespace testsuite {
26class DumpControl;
27} // namespace testsuite
28
29/// Dumping of cache-like components
30namespace dump {
31
32struct Config;
34extern const std::string_view kDump;
35
36/// A dynamically dispatched equivalent of `kDumpable` "concept". Unlike
37/// with ADL-found `Write`/`Read`, the methods are guaranteed not to be called
38/// in parallel.
40public:
41 virtual ~DumpableEntity();
42
43 virtual void GetAndWrite(dump::Writer& writer) const = 0;
44
45 virtual void ReadAndSet(dump::Reader& reader) = 0;
46};
47
48enum class UpdateType {
49 /// Some new data has appeared since the last update. `Dumper` will write it
50 /// on the next `WriteDumpAsync` call, or as specified by the config.
52
53 /// There is no new data, but we have verified that the old data is
54 /// up-to-date. `Dumper` will bump the dump modification time to `now`.
56};
57
58// clang-format off
59/// @brief Manages dumps of a cache-like component
60///
61/// The class is thread-safe.
62///
63/// Used in `components::CachingComponentBase`.
64///
65/// Automatically subscribes to:
66/// - dynamic config updates from `USERVER_DUMPS` under `dumper_name`
67/// - statistics under `cache.{dumper_name}.dump`
68///
69/// Dumps will be stored in `{dump-root}/{dumper_name}`, where `dump-root` is
70/// taken from `components::DumpConfigurator`.
71///
72/// Here, `dumper_name` is the name of the parent component.
73///
74/// ## Dumper Dynamic config
75/// * @ref USERVER_DUMPS
76///
77/// ## Static config
78/// Name | Type | Description | Default value
79/// ---- | ---- | ----------- | -------------
80/// `enable` | `boolean` | Whether this `Dumper` should actually read and write dumps | (required)
81/// `world-readable` | `boolean` | If `true`, dumps are created with access `0444`, otherwise with access `0400` | (required)
82/// `format-version` | `integer` | Allows to ignore dumps written with an obsolete `format-version` | (required)
83/// `max-age` | optional `string` (duration) | Overdue dumps are ignored | null
84/// `max-count` | optional `integer` | Old dumps over the limit are removed from disk | `1`
85/// `min-interval` | `string` (duration) | `WriteDumpAsync` calls performed in a fast succession are ignored | `0s`
86/// `fs-task-processor` | `string` | `TaskProcessor` for blocking disk IO | `fs-task-processor`
87/// `encrypted` | `boolean` | Whether to encrypt the dump | `false`
88///
89/// ## Sample usage
90/// @snippet core/src/dump/dumper_test.cpp Sample Dumper usage
91///
92/// @see components::DumpConfigurator
93// clang-format on
94class Dumper final {
95public:
96 /// @brief The primary constructor for when `Dumper` is stored in a component
97 /// @note `dumpable` must outlive this `Dumper`
99 const components::ComponentConfig& config,
100 const components::ComponentContext& context,
101 DumpableEntity& dumpable
102 );
103
104 /// For internal use only
105 Dumper(
106 const Config& initial_config,
107 std::unique_ptr<OperationsFactory> rw_factory,
108 engine::TaskProcessor& fs_task_processor,
109 dynamic_config::Source config_source,
110 utils::statistics::Storage& statistics_storage,
111 testsuite::DumpControl& dump_control,
112 DumpableEntity& dumpable
113 );
114
115 Dumper(Dumper&&) = delete;
116 Dumper& operator=(Dumper&&) = delete;
117 ~Dumper();
118
119 const std::string& Name() const;
120
121 /// @brief Read data from a dump, if any
122 /// @note Catches and logs any exceptions related to read operation failure
123 /// @returns `update_time` of the loaded dump on success, `null` otherwise
124 std::optional<TimePoint> ReadDump();
125
126 /// @brief Forces the `Dumper` to write a dump synchronously
127 /// @throws std::exception if the `Dumper` failed to write a dump
129
130 /// @brief Forces the `Dumper` to read from a dump synchronously
131 /// @throws std::exception if the `Dumper` failed to read a dump
133
134 /// @brief Notifies the `Dumper` of an update in the `DumpableEntity`
135 ///
136 /// A dump will be written asynchronously as soon as:
137 ///
138 /// 1. data update has been reported via `OnUpdateCompleted` since the last
139 /// written dump,
140 /// 2. dumps are `enabled` in the dynamic config, and
141 /// 3. `min-interval` time has passed
142 ///
143 /// @note This overload is more performant. The time written on the dump will
144 /// be taken from the dump writing time.
146
147 /// @overload void OnUpdateCompleted()
148 /// @param update_time The time at which the data has been guaranteed to be
149 /// up-to-date
150 /// @param update_type Whether the update modified the data or confirmed its
151 /// actuality, UpdateType::kModified by default
152 /// @note This overload locks mutexes and should not be used in tight loops.
153 /// On the other hand, it allows to exactly control the dump expiration.
154 void OnUpdateCompleted(TimePoint update_time, UpdateType update_type);
155
156 /// @brief Cancel and wait for the task running background writes. Also
157 /// disables operations via testsuite dump control.
158 ///
159 /// CancelWriteTaskAndWait is automatically called in the destructor. This
160 /// method must be called explicitly if the `DumpableEntity` may start its
161 /// destruction before the `Dumper` is destroyed.
162 ///
163 /// After calling this method, OnUpdateCompleted calls have no effect.
165
166 /// @brief Returns the static config schema for a
167 /// components::ComponentBase with an added `dump` sub-section.
169
170private:
171 Dumper(const Config& initial_config, const components::ComponentContext& context, DumpableEntity& dumpable);
172
173 class Impl;
174 utils::FastPimpl<Impl, 1088, 16> impl_;
175};
176
177} // namespace dump
178
179USERVER_NAMESPACE_END