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 schema_hash SHA-256(canonical JSON of schema with inlined definitions),
80
/// lowercase hex, 64 chars. Stored in the global registry and
81
/// retrievable via dynamic_config::impl::GetRegisteredConfigsMeta()
82
/// as dynamic_config::RegisteredConfigMeta::schema_hash.
83
/// @warning This constructor is intended for use by chaotic codegen only,
84
/// not for manual calls. Backwards-incompatible changes may be
85
/// introduced in the future, e.g. adding additional parameters.
86
Key
(std::string_view name, JsonParser parser, DefaultAsJsonString default_json, std::string_view schema_hash);
87
88
/// @brief The constructor that parses multiple JSON config items
89
/// into a single C++ object.
90
/// @warning Prefer to use a separate `Key` per JSON config item and use the
91
/// constructors above whenever possible.
92
template
<std::size_t N>
93
Key
(DocsMapParser parser,
const
ConfigDefault (&default_json_map)[N]);
94
95
/// Creates a config that always has the same value.
96
Key
(ConstantConfig,
VariableType
value);
97
98
/// @cond
99
Key(impl::InternalTag, std::string_view name);
100
101
Key(impl::InternalTag, DocsMapParser parser);
102
/// @endcond
103
104
Key(
const
Key
&)
noexcept
=
delete
;
105
Key
& operator=(
const
Key
&)
noexcept
=
delete
;
106
107
/// @returns the name of the config variable, as passed at the construction.
108
std::string_view
GetName
()
const
noexcept
;
109
110
/// Parses the config. Useful only in some very niche scenarios. The config
111
/// value should be typically be retrieved from dynamic_config::Snapshot,
112
/// which is obtained from components::DynamicConfig in production or from
113
/// dynamic_config::StorageMock in unit tests.
114
VariableType
Parse
(
const
DocsMap& docs_map)
const
;
115
116
private
:
117
friend
struct
impl::ConfigIdGetter;
118
119
const
impl::ConfigId id_;
120
};
121
122
/// @brief The shared snapshot of
123
/// @ref scripts/docs/en/userver/dynamic_config.md "dynamic configs". Cheap to
124
/// copy, even cheaper to move. Thread safe, not updated with new dynamic
125
/// config values in background (it's a snapshot!).
126
///
127
/// When a config update comes in via new `DocsMap`, configs of all
128
/// the registered types are constructed and stored in `Config`. After that
129
/// the `DocsMap` is dropped.
130
///
131
/// Config types are automatically registered if they are used
132
/// somewhere in the program.
133
///
134
/// ## Usage example:
135
/// @snippet components/component_sample_test.cpp Sample user component runtime config source
136
class
Snapshot
final
{
137
public
:
138
Snapshot(
const
Snapshot&);
139
Snapshot& operator=(
const
Snapshot&);
140
141
Snapshot(Snapshot&&)
noexcept
;
142
Snapshot& operator=(Snapshot&&)
noexcept
;
143
144
~Snapshot();
145
146
/// Used to access individual configs in the type-safe config map
147
template
<
typename
VariableType>
148
const
VariableType&
operator
[](
const
Key
<VariableType>& key)
const
& USERVER_IMPL_LIFETIME_BOUND;
149
150
/// Used to access individual configs in the type-safe config map
151
template
<
typename
VariableType>
152
const
VariableType&
operator
[](
const
Key
<VariableType>&) &&;
153
154
private
:
155
// for the constructor
156
friend
class
Source;
157
friend
class
impl::StorageData;
158
friend
struct
Diff;
159
160
explicit
Snapshot(
const
impl::StorageData& storage);
161
162
const
impl::SnapshotData& GetData()
const
;
163
164
struct
Impl;
165
utils
::FastPimpl<Impl, 16, 8> impl_;
166
};
167
168
// ========================== Implementation follows ==========================
169
170
constexpr
DefaultAsJsonString::DefaultAsJsonString(std::string_view json_string)
171
: json_string(json_string)
172
{}
173
174
template
<
typename
T>
175
ConfigDefault::ConfigDefault(std::string_view name,
const
T& value)
176
: name(name),
177
default_json(impl::ToJsonString(value))
178
{}
179
180
template
<
typename
Variable>
181
Key
<Variable>::
Key
(std::string_view name,
const
VariableType
& default_value)
182
: id_(impl::Register(
183
std::string{name},
184
[name = std::string{name}](
const
auto
& docs_map) -> std::any {
185
return
impl::DocsMapGet(docs_map, name).
template
As<
VariableType
>();
186
},
187
impl::ValueToDocsMapString(name, default_value)
188
))
189
{}
190
191
template
<
typename
Variable>
192
Key
<Variable>::
Key
(std::string_view name, DefaultAsJsonString default_json)
193
: id_(impl::Register(
194
std::string{name},
195
[name = std::string{name}](
const
auto
& docs_map) -> std::any {
196
return
impl::DocsMapGet(docs_map, name).
template
As<
VariableType
>();
197
},
198
impl::SingleToDocsMapString(name, default_json.json_string)
199
))
200
{}
201
202
template
<
typename
Variable>
203
Key
<Variable>::
Key
(std::string_view name, JsonParser parser, DefaultAsJsonString default_json)
204
: id_(impl::Register(
205
std::string{name},
206
[name = std::string{name}, parser](
const
auto
& docs_map) -> std::any {
207
return
parser(impl::DocsMapGet(docs_map, name));
208
},
209
impl::SingleToDocsMapString(name, default_json.json_string)
210
))
211
{}
212
213
template
<
typename
Variable>
214
Key
<Variable>::
Key
(
215
std::string_view name,
216
JsonParser parser,
217
DefaultAsJsonString default_json,
218
std::string_view schema_hash
219
)
220
: id_(impl::Register(
221
std::string{name},
222
[name = std::string{name}, parser](
const
auto
& docs_map) -> std::any {
223
return
parser(impl::DocsMapGet(docs_map, name));
224
},
225
impl::SingleToDocsMapString(name, default_json.json_string),
226
std::string{schema_hash}
227
))
228
{}
229
230
template
<
typename
Variable>
231
template
<std::size_t N>
232
Key
<Variable>::
Key
(DocsMapParser parser,
const
ConfigDefault (&default_json_map)[N])
233
: id_(impl::Register(
234
std::string{},
235
[parser](
const
DocsMap& docs_map) -> std::any {
return
parser(docs_map); },
236
impl::MultipleToDocsMapString(default_json_map, N)
237
))
238
{}
239
240
template
<
typename
Variable>
241
Key
<Variable>::
Key
(ConstantConfig
/*tag*/
,
VariableType
value)
242
: id_(impl::Register(std::string{}, [value = std::move(value)](
const
DocsMap&
/*unused*/
) {
return
value; },
"{}"
))
243
{}
244
245
template
<
typename
Variable>
246
Key
<Variable>::Key(impl::InternalTag, std::string_view name)
247
: id_(impl::Register(
248
std::string{name},
249
[name = std::string{name}](
const
auto
& docs_map) -> std::any {
250
return
impl::DocsMapGet(docs_map, name).
template
As<
VariableType
>();
251
},
252
"{}"
253
))
254
{}
255
256
template
<
typename
Variable>
257
Key
<Variable>::Key(impl::InternalTag, DocsMapParser parser)
258
: id_(impl::Register(
259
std::string{},
260
[parser](
const
DocsMap& docs_map) -> std::any {
return
parser(docs_map); },
261
"{}"
262
))
263
{}
264
265
template
<
typename
VariableType>
266
std::string_view
Key
<VariableType>::
GetName
()
const
noexcept
{
267
return
impl::GetName(id_);
268
}
269
270
template
<
typename
VariableType>
271
VariableType
Key
<VariableType>::
Parse
(
const
DocsMap& docs_map)
const
{
272
return
std::any_cast<
VariableType
>(impl::MakeConfig(id_, docs_map));
273
}
274
275
template
<
typename
VariableType>
276
const
VariableType&
Snapshot
::
operator
[](
const
Key
<VariableType>& key)
const
& USERVER_IMPL_LIFETIME_BOUND {
277
return
GetData().Get<VariableType>(impl::ConfigIdGetter::Get(key));
278
}
279
280
template
<
typename
VariableType>
281
const
VariableType& Snapshot::
operator
[](
const
Key
<VariableType>&) && {
282
static_assert
(!
sizeof
(VariableType),
"keep the Snapshot before using, please"
);
283
}
284
285
}
// namespace dynamic_config
286
287
USERVER_NAMESPACE_END
userver
dynamic_config
snapshot.hpp
Generated on
for userver by
Doxygen
1.17.0