userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
cache_update_trait.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/cache/cache_update_trait.hpp
4
/// @brief @copybrief cache::CacheUpdateTrait
5
6
#
include
<
memory
>
7
#
include
<
string
>
8
9
#
include
<
userver
/
cache
/
cache_statistics
.
hpp
>
10
#
include
<
userver
/
cache
/
update_type
.
hpp
>
11
#
include
<
userver
/
components
/
component_fwd
.
hpp
>
12
#
include
<
userver
/
dump
/
fwd
.
hpp
>
13
#
include
<
userver
/
engine
/
task
/
task_processor_fwd
.
hpp
>
14
#
include
<
userver
/
rcu
/
fwd
.
hpp
>
15
#
include
<
userver
/
utils
/
flags
.
hpp
>
16
17
USERVER_NAMESPACE_BEGIN
18
19
namespace
cache
{
20
21
struct
CacheDependencies;
22
struct
Config;
23
24
/// @ingroup userver_base_classes
25
///
26
/// @brief Base class for periodically updated caches.
27
///
28
/// @note Don't use directly, inherit from components::CachingComponentBase
29
/// instead
30
class
CacheUpdateTrait
{
31
public
:
32
CacheUpdateTrait(
CacheUpdateTrait
&&) =
delete
;
33
CacheUpdateTrait
& operator=(
CacheUpdateTrait
&&) =
delete
;
34
35
/// @brief Non-blocking forced cache update of specified type
36
/// @see PeriodicTask::ForceStepAsync for behavior details
37
void
InvalidateAsync
(
UpdateType
update_type);
38
39
/// @brief Forces a synchronous cache update of specified type
40
///
41
/// @warning This method is intended for tests and debugging only. In
42
/// production code use `InvalidateAsync` instead. The reasons are:
43
///
44
/// 1. `InvalidateAsync` shifts the time of the next update as if a periodic
45
/// update has just happened. `UpdateSyncDebug` does not do that: it locks
46
/// the mutex and performs an additional update on the side, which puts
47
/// extra load on the CPU and on the data source.
48
/// 2. The cache we subscribe to sends events *as part of its own update*. If
49
/// the callback does something lengthy, e.g. updating another cache, this
50
/// affects the cache we subscribe to: it may disrupt its updates and
51
/// cause a traffic jam in the whole chain of caches. `InvalidateAsync` is
52
/// not subject to this. On top of that, `UpdateSyncDebug` will block the
53
/// cache we subscribe to for the time we wait for the previous update of
54
/// the dependent cache to finish (if one was in progress).
55
/// 3. `InvalidateAsync` robustly handles situations with repeated update
56
/// requests, see the docs of `PeriodicTask::ForceStepAsync`, on top of
57
/// which it is implemented. `UpdateSyncDebug` tries to lock the mutex over
58
/// and over and performs as many updates as were requested, even if they
59
/// were requested many times in a row.
60
/// 4. If `UpdateSyncDebug` is called before the periodic updates of the
61
/// current cache have started (they start after the constructor of the
62
/// derived cache finishes), the behavior is undefined, because the state
63
/// of the periodic updates is not set up yet, while an update was already
64
/// requested. `InvalidateAsync` handles this case: in that situation
65
/// nothing happens.
66
///
67
/// @see InvalidateAsync
68
/// @throws If `Update` throws
69
void
UpdateSyncDebug
(
UpdateType
update_type);
70
71
/// @return name of the component
72
const
std::string&
Name
()
const
noexcept
;
73
74
protected
:
75
/// @cond
76
// For internal use only
77
CacheUpdateTrait(
const
components
::ComponentConfig& config,
const
components
::ComponentContext& context);
78
79
// For internal use only
80
explicit
CacheUpdateTrait(CacheDependencies&& dependencies);
81
82
virtual
~CacheUpdateTrait();
83
/// @endcond
84
85
/// Update types configured for the cache
86
AllowedUpdateTypes
GetAllowedUpdateTypes
()
const
;
87
88
/// Periodic update flags
89
enum
class
Flag
{
90
kNone = 0,
91
92
/// @brief Disable initial update on start
93
/// @deprecated Use `first-update-fail-ok: true` instead
94
kNoFirstUpdate
= 1 << 0,
95
};
96
97
/// Called in `CachingComponentBase::Set` during update to indicate
98
/// that the cached data has been modified
99
void
OnCacheModified
()
noexcept
;
100
101
/// @cond
102
// For internal use only
103
rcu
::
ReadablePtr
<Config> GetConfig()
const
;
104
105
// Checks for the presence of the flag for pre-assign check.
106
// For internal use only.
107
bool
HasPreAssignCheck()
const
noexcept
;
108
109
// Returns value of the flag safe-data-lifetime.
110
// For internal use only.
111
bool
IsSafeDataLifetime()
const
noexcept
;
112
113
// For internal use only.
114
void
SetDataSizeStatistic(std::size_t size)
noexcept
;
115
116
// For internal use only
117
// TODO remove after TAXICOMMON-3959
118
engine::TaskProcessor& GetCacheTaskProcessor()
const
noexcept
;
119
/// @endcond
120
121
/// @brief Should be overridden in a derived class to align the stored data
122
/// with some data source.
123
///
124
/// `Update` implementation should do one of the following:
125
///
126
/// A. If the update succeeded and has changes...
127
/// 1. call CachingComponentBase::Set to update the stored value and send a
128
/// notification to subscribers
129
/// 2. call UpdateStatisticsScope::Finish
130
/// 3. return normally (an exception is allowed in edge cases)
131
///
132
/// B. If the update succeeded and verified that there are no changes...
133
/// 1. DON'T call CachingComponentBase::Set
134
/// 2. call UpdateStatisticsScope::FinishNoChanges
135
/// 3. return normally (an exception is allowed in edge cases)
136
///
137
/// C. If the update failed...
138
/// 1. DON'T call CachingComponentBase::Set
139
/// 2. call UpdateStatisticsScope::FinishWithError, or...
140
/// 3. throw an exception, which will be logged nicely
141
/// (if there already is an exception, prefer rethrowing it instead
142
/// of calling UpdateStatisticsScope::FinishWithError)
143
///
144
/// @param type type of the update
145
/// @param last_update time of the last update (value of `now` from previous
146
/// invocation of Update or default constructed value if this is the first
147
/// Update).
148
/// @param now current time point
149
/// @param stats_scope the scope that expects
150
/// one of `Finish`, `FinishNoChanges`, `FinishWithError` or an exception.
151
///
152
/// @throws std::exception on update failure
153
///
154
/// @warning If `Update` returns without throwing an exception and without
155
/// calling one of the `Finish*` methods, the behavior is undefined.
156
///
157
/// @see @ref scripts/docs/en/userver/caches.md
158
virtual
void
Update
(
159
UpdateType
type,
160
const
std::chrono::system_clock::time_point& last_update,
161
const
std::chrono::system_clock::time_point& now,
162
UpdateStatisticsScope& stats_scope
163
) = 0;
164
165
/// @brief Returns flags for cache start.
166
virtual
utils
::Flags<
Flag
>
GetStartFlags
()
const
;
167
168
/// @brief Call this to start periodic updates just now,
169
/// not after the constructor.
170
void
EarlyStartPeriodicUpdates
(
utils
::Flags<
Flag
> flags);
171
172
/// @cond
173
// For internal use only
174
void
EarlyStopPeriodicUpdates();
175
/// @endcond
176
177
private
:
178
void
StartPeriodicUpdates();
179
180
void
StopPeriodicUpdates();
181
182
virtual
void
Cleanup() = 0;
183
184
virtual
void
MarkAsExpired();
185
186
virtual
void
GetAndWrite(
dump
::
Writer
& writer)
const
;
187
188
virtual
void
ReadAndSet(
dump
::
Reader
& reader);
189
190
class
Impl;
191
std::unique_ptr<Impl> impl_;
192
};
193
194
}
// namespace cache
195
196
USERVER_NAMESPACE_END
userver
cache
cache_update_trait.hpp
Generated on
for userver by
Doxygen
1.17.0