userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
snapshot.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/dynamic_config/snapshot.hpp
4
/// @brief @copybrief dynamic_config::Snapshot
5
6
#
include
<
cstdint
>
7
#
include
<
string
>
8
#
include
<
type_traits
>
9
10
#
include
<
userver
/
compiler
/
impl
/
lifetime
.
hpp
>
11
#
include
<
userver
/
dynamic_config
/
impl
/
snapshot
.
hpp
>
12
#
include
<
userver
/
dynamic_config
/
impl
/
to_json
.
hpp
>
13
#
include
<
userver
/
dynamic_config
/
registered_config_meta
.
hpp
>
14
#
include
<
userver
/
formats
/
json_fwd
.
hpp
>
15
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
16
17
USERVER_NAMESPACE_BEGIN
18
19
namespace
dynamic_config {
20
21
/// A strong typedef for usage in dynamic_config::Key constructors.
22
struct
DefaultAsJsonString
final
{
23
constexpr
explicit
DefaultAsJsonString(std::string_view json_string);
24
25
std::string_view json_string;
26
};
27
28
/// A config name-value pair for usage in dynamic_config::Key constructors.
29
struct
ConfigDefault
final
{
30
template
<
typename
T>
31
ConfigDefault(std::string_view name,
const
T& value);
32
33
ConfigDefault(std::string_view name, DefaultAsJsonString default_json);
34
35
std::string_view name;
36
std::string default_json;
37
};
38
39
/// A tag type for usage in dynamic_config::Key constructors.
40
struct
ConstantConfig
final
{
41
constexpr
explicit
ConstantConfig() =
default
;
42
};
43
44
/// @brief A config key is a unique identifier for a config variable
45
/// @snippet core/src/dynamic_config/config_test.cpp key bool
46
template
<
typename
Variable>
47
class
Key
final
{
48
public
:
49
/// The type of the parsed config variable.
50
using
VariableType
= Variable;
51
52
using
JsonParser = Variable (*)(
const
formats::
json
::
Value
&);
53
using
DocsMapParser = Variable (*)(
const
DocsMap&);
54
55
/// @brief The constructor for a trivial `VariableType`, e.g. `bool`, integer,
56
/// `double`, `string`. The default is passed by value.
57
///
58
/// Usage example:
59
/// @snippet core/src/dynamic_config/config_test.cpp key bool
60
Key
(std::string_view name,
const
VariableType
& default_value);
61
62
/// @brief The constructor for a non-trivial `VariableType`. The default is
63
/// passed as a JSON string.
64
///
65
/// Uses formats::json::Value `Parse` customization point function to parse
66
/// `VariableType`.
67
///
68
/// Usage example:
69
/// @snippet core/src/dynamic_config/config_test.cpp struct config cpp
70
Key
(std::string_view name, DefaultAsJsonString default_json);
71
72
/// @brief The constructor that provides a special parser from JSON.
73
/// @warning Prefer the constructors above whenever possible.
74
/// @details Can be used when generic `Parse` is not applicable. Sometimes
75
/// used to add validation, e.g. minimum, maximum, string pattern, etc.
76
Key
(std::string_view name, JsonParser parser, DefaultAsJsonString default_json);
77
78
/// @brief Constructor with a schema_hash, used by chaotic codegen.
79
/// @param name config variable name
80
/// @param parser custom JSON parser for the variable
81
/// @param default_json default value as a JSON string
82
/// @param schema_hash SHA-256(canonical JSON of schema with inlined definitions),
83
/// lowercase hex, 64 chars. Stored in the global registry and
84
/// retrievable via dynamic_config::impl::GetRegisteredConfigsMeta()
85
/// as dynamic_config::RegisteredConfigMeta::schema_hash.
86
/// @warning This constructor is intended for use by chaotic codegen only,
87
/// not for manual calls. Backwards-incompatible changes may be
88
/// introduced in the future, e.g. adding additional parameters.
89
Key
(std::string_view name, JsonParser parser, DefaultAsJsonString default_json, std::string_view schema_hash);
90
91
/// @brief The constructor that parses multiple JSON config items
92
/// into a single C++ object.
93
/// @warning Prefer to use a separate `Key` per JSON config item and use the
94
/// constructors above whenever possible.
95
template
<std::size_t N>
96
Key
(DocsMapParser parser,
const
ConfigDefault (&default_json_map)[N]);
97
98
/// Creates a config that always has the same value.
99
Key
(ConstantConfig,
VariableType
value);
100
101
/// @cond
102
Key(impl::InternalTag, std::string_view name);
103
104
Key(impl::InternalTag, DocsMapParser parser);
105
/// @endcond
106
107
Key(
const
Key
&)
noexcept
=
delete
;
108
Key
& operator=(
const
Key
&)
noexcept
=
delete
;
109
110
/// @returns the name of the config variable, as passed at the construction.
111
std::string_view
GetName
()
const
noexcept
;
112
113
/// Parses the config. Useful only in some very niche scenarios. The config
114
/// value should be typically be retrieved from dynamic_config::Snapshot,
115
/// which is obtained from components::DynamicConfig in production or from
116
/// dynamic_config::StorageMock in unit tests.
117
VariableType
Parse
(
const
DocsMap& docs_map)
const
;
118
119
private
:
120
friend
struct
impl::ConfigIdGetter;
121
122
const
impl::ConfigId id_;
123
};
124
125
/// @brief The shared snapshot of
126
/// @ref scripts/docs/en/userver/dynamic_config.md "dynamic configs". Cheap to
127
/// copy, even cheaper to move. Thread safe, not updated with new dynamic
128
/// config values in background (it's a snapshot!).
129
///
130
/// When a config update comes in via new `DocsMap`, configs of all
131
/// the registered types are constructed and stored in `Config`. After that
132
/// the `DocsMap` is dropped.
133
///
134
/// Config types are automatically registered if they are used
135
/// somewhere in the program.
136
///
137
/// ## Usage example:
138
/// @snippet core/src/components/component_sample_test.cpp Sample user component runtime config source
139
class
Snapshot
final
{
140
public
:
141
Snapshot(
const
Snapshot&);
142
Snapshot& operator=(
const
Snapshot&);
143
144
Snapshot(Snapshot&&)
noexcept
;
145
Snapshot& operator=(Snapshot&&)
noexcept
;
146
147
~Snapshot();
148
149
/// Used to access individual configs in the type-safe config map
150
template
<
typename
VariableType>
151
const
VariableType&
operator
[](
const
Key
<VariableType>& key)
const
& USERVER_IMPL_LIFETIME_BOUND;
152
153
/// Used to access individual configs in the type-safe config map
154
template
<
typename
VariableType>
155
const
VariableType&
operator
[](
const
Key
<VariableType>&) &&;
156
157
private
:
158
// for the constructor
159
friend
class
Source;
160
friend
class
impl::StorageData;
161
friend
struct
Diff;
162
163
explicit
Snapshot(
const
impl::StorageData& storage);
164
165
const
impl::SnapshotData& GetData()
const
;
166
167
struct
Impl;
168
utils
::FastPimpl<Impl, 16, 8> impl_;
169
};
170
171
// ========================== Implementation follows ==========================
172
173
constexpr
DefaultAsJsonString::DefaultAsJsonString(std::string_view json_string)
174
: json_string(json_string)
175
{}
176
177
template
<
typename
T>
178
ConfigDefault::ConfigDefault(std::string_view name,
const
T& value)
179
: name(name),
180
default_json(impl::ToJsonString(value))
181
{}
182
183
template
<
typename
Variable>
184
Key
<Variable>::
Key
(std::string_view name,
const
VariableType
& default_value)
185
: id_(impl::Register(
186
std::string{name},
187
[name = std::string{name}](
const
auto
& docs_map) -> std::any {
188
return
impl::DocsMapGet(docs_map, name).
template
As<
VariableType
>();
189
},
190
impl::ValueToDocsMapString(name, default_value)
191
))
192
{}
193
194
template
<
typename
Variable>
195
Key
<Variable>::
Key
(std::string_view name, DefaultAsJsonString default_json)
196
: id_(impl::Register(
197
std::string{name},
198
[name = std::string{name}](
const
auto
& docs_map) -> std::any {
199
return
impl::DocsMapGet(docs_map, name).
template
As<
VariableType
>();
200
},
201
impl::SingleToDocsMapString(name, default_json.json_string)
202
))
203
{}
204
205
template
<
typename
Variable>
206
Key
<Variable>::
Key
(std::string_view name, JsonParser parser, DefaultAsJsonString default_json)
207
: id_(impl::Register(
208
std::string{name},
209
[name = std::string{name}, parser](
const
auto
& docs_map) -> std::any {
210
return
parser(impl::DocsMapGet(docs_map, name));
211
},
212
impl::SingleToDocsMapString(name, default_json.json_string)
213
))
214
{}
215
216
template
<
typename
Variable>
217
Key
<Variable>::
Key
(
218
std::string_view name,
219
JsonParser parser,
220
DefaultAsJsonString default_json,
221
std::string_view schema_hash
222
)
223
: id_(impl::Register(
224
std::string{name},
225
[name = std::string{name}, parser](
const
auto
& docs_map) -> std::any {
226
return
parser(impl::DocsMapGet(docs_map, name));
227
},
228
impl::SingleToDocsMapString(name, default_json.json_string),
229
std::string{schema_hash}
230
))
231
{}
232
233
template
<
typename
Variable>
234
template
<std::size_t N>
235
Key
<Variable>::
Key
(DocsMapParser parser,
const
ConfigDefault (&default_json_map)[N])
236
: id_(impl::Register(
237
std::string{},
238
[parser](
const
DocsMap& docs_map) -> std::any {
return
parser(docs_map); },
239
impl::MultipleToDocsMapString(default_json_map, N)
240
))
241
{}
242
243
template
<
typename
Variable>
244
Key
<Variable>::
Key
(ConstantConfig
/*tag*/
,
VariableType
value)
245
: id_(impl::Register(std::string{}, [value = std::move(value)](
const
DocsMap&
/*unused*/
) {
return
value; },
"{}"
))
246
{}
247
248
template
<
typename
Variable>
249
Key
<Variable>::Key(impl::InternalTag, std::string_view name)
250
: id_(impl::Register(
251
std::string{name},
252
[name = std::string{name}](
const
auto
& docs_map) -> std::any {
253
return
impl::DocsMapGet(docs_map, name).
template
As<
VariableType
>();
254
},
255
"{}"
256
))
257
{}
258
259
template
<
typename
Variable>
260
Key
<Variable>::Key(impl::InternalTag, DocsMapParser parser)
261
: id_(impl::Register(
262
std::string{},
263
[parser](
const
DocsMap& docs_map) -> std::any {
return
parser(docs_map); },
264
"{}"
265
))
266
{}
267
268
template
<
typename
VariableType>
269
std::string_view
Key
<VariableType>::
GetName
()
const
noexcept
{
270
return
impl::GetName(id_);
271
}
272
273
template
<
typename
VariableType>
274
VariableType
Key
<VariableType>::
Parse
(
const
DocsMap& docs_map)
const
{
275
return
std::any_cast<
VariableType
>(impl::MakeConfig(id_, docs_map));
276
}
277
278
template
<
typename
VariableType>
279
const
VariableType&
Snapshot
::
operator
[](
const
Key
<VariableType>& key)
const
& USERVER_IMPL_LIFETIME_BOUND {
280
return
GetData().Get<VariableType>(impl::ConfigIdGetter::Get(key));
281
}
282
283
template
<
typename
VariableType>
284
const
VariableType& Snapshot::
operator
[](
const
Key
<VariableType>&) && {
285
static_assert
(!
sizeof
(VariableType),
"keep the Snapshot before using, please"
);
286
}
287
288
}
// namespace dynamic_config
289
290
USERVER_NAMESPACE_END
userver
dynamic_config
snapshot.hpp
Generated on
for userver by
Doxygen
1.17.0