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.
40 public:
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/// ## 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 {
95 public:
96 /// @brief The primary constructor for when `Dumper` is stored in a component
97 /// @note `dumpable` must outlive this `Dumper`
98 Dumper(const components::ComponentConfig& config,
99 const components::ComponentContext& context, DumpableEntity& dumpable);
100
101 /// For internal use only
102 Dumper(const Config& initial_config,
103 std::unique_ptr<OperationsFactory> rw_factory,
104 engine::TaskProcessor& fs_task_processor,
105 dynamic_config::Source config_source,
106 utils::statistics::Storage& statistics_storage,
107 testsuite::DumpControl& dump_control, DumpableEntity& dumpable);
108
109 Dumper(Dumper&&) = delete;
110 Dumper& operator=(Dumper&&) = delete;
111 ~Dumper();
112
113 const std::string& Name() const;
114
115 /// @brief Read data from a dump, if any
116 /// @note Catches and logs any exceptions related to read operation failure
117 /// @returns `update_time` of the loaded dump on success, `null` otherwise
118 std::optional<TimePoint> ReadDump();
119
120 /// @brief Forces the `Dumper` to write a dump synchronously
121 /// @throws std::exception if the `Dumper` failed to write a dump
123
124 /// @brief Forces the `Dumper` to read from a dump synchronously
125 /// @throws std::exception if the `Dumper` failed to read a dump
127
128 /// @brief Notifies the `Dumper` of an update in the `DumpableEntity`
129 ///
130 /// A dump will be written asynchronously as soon as:
131 ///
132 /// 1. data update has been reported via `OnUpdateCompleted` since the last
133 /// written dump,
134 /// 2. dumps are `enabled` in the dynamic config, and
135 /// 3. `min-interval` time has passed
136 ///
137 /// @note This overload is more performant. The time written on the dump will
138 /// be taken from the dump writing time.
140
141 /// @overload void OnUpdateCompleted()
142 /// @param update_time The time at which the data has been guaranteed to be
143 /// up-to-date
144 /// @param update_type Whether the update modified the data or confirmed its
145 /// actuality, UpdateType::kModified by default
146 /// @note This overload locks mutexes and should not be used in tight loops.
147 /// On the other hand, it allows to exactly control the dump expiration.
148 void OnUpdateCompleted(TimePoint update_time, UpdateType update_type);
149
150 /// @brief Cancel and wait for the task running background writes. Also
151 /// disables operations via testsuite dump control.
152 ///
153 /// CancelWriteTaskAndWait is automatically called in the destructor. This
154 /// method must be called explicitly if the `DumpableEntity` may start its
155 /// destruction before the `Dumper` is destroyed.
156 ///
157 /// After calling this method, OnUpdateCompleted calls have no effect.
159
160 /// @brief Returns the static config schema for a
161 /// components::LoggableComponentBase with an added `dump` sub-section.
163
164 private:
165 Dumper(const Config& initial_config,
166 const components::ComponentContext& context, DumpableEntity& dumpable);
167
168 class Impl;
169 utils::FastPimpl<Impl, 1056, 16> impl_;
170};
171
172} // namespace dump
173
174USERVER_NAMESPACE_END