Flow 1.0.1
Flow project: Full implementation reference.
dynamic_cfg_context.hpp
Go to the documentation of this file.
1/* Flow
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
21#include "flow/cfg/cfg_fwd.hpp"
22#include <boost/function.hpp>
23#include <algorithm>
24#include <type_traits>
25
26namespace flow::cfg
27{
28
29/**
30 * Class which facilitates managing access to a dynamic configuration. Another class can make use of this one by means
31 * of a composition relationship, either through inheritance (probably `private` or `protected`) or by containing one or
32 * more `Dynamic_cfg_context` members. If using inheritance, the class will gain methods which can be used to access
33 * the dynamic configuration. If using composition by members, more than one dynamic configuration can be used, each of
34 * which can be accessed separately by calling the access methods of the associated member.
35 *
36 * A "configuration," here, is a data object (probably a `struct`), which is referred to as the "root", containing an
37 * internal data object, which is referred to as the "target". The target is the configuration object which is expected
38 * to be normally accessed. The root and the target can be the same.
39 *
40 * @tparam Root
41 * Type for the root configuration. This should meet the requirements of the template argument for
42 * `Option_set`. A `Root::Const_ptr` type for a ref-counted pointer to an immutable `Root` must at least be
43 * defined (which can be provided by deriving from `util::Shared_ptr_alias_holder`). See Option_set.
44 * @tparam Target
45 * Type for the target configuration.
46 * @tparam Target_ptr
47 * Please leave this at its default. Background: This would not have been a template parameter in the
48 * first place, had the authors known of `pointer_traits::rebind` at that the time. To preserve
49 * backwards compatibility this parameter remains for now (albeit deprecated).
50 *
51 * @todo flow::cfg::Dynamic_cfg_context `Target_ptr` is deprecated and shall be always left at its default
52 * value in future code; eventually remove it entirely and hard-code the default value internally.
53 */
54template<typename Root, typename Target,
55 typename Target_ptr> // See default in _fwd.hpp.
57{
58 static_assert(std::is_same_v<typename Target_ptr::element_type, std::add_const_t<Target>>,
59 "The `element_type` of `Target_ptr` must be `const Target`.");
60
61public:
62 // Types.
63
64 /// Type alias for `Target_ptr`.
65 using Target_ptr_type = Target_ptr;
66
67 /// Type for a function object which returns a ref-counted pointer to an immutable root configuration object.
68 using Get_root_func = Function<typename Root::Const_ptr ()>;
69
70 /// Type for a function object which translates a `Root` object to a contained `Target` object.
71 using Root_to_target_func = Function<const Target& (const Root&)>;
72
73 // Constructors/destructor.
74
75 /**
76 * Constructor.
77 *
78 * @param get_root_func_moved
79 * Returns a ref-counted pointer to the (immutable) root configuration object.
80 * @param root_to_target_func_moved
81 * Translates a root configuration object to a contained target configuration object.
82 */
83 Dynamic_cfg_context(Get_root_func&& get_root_func_moved, Root_to_target_func&& root_to_target_func_moved);
84
85 /**
86 * Constructor.
87 *
88 * This produces a `Dynamic_cfg_context` which will obtain its configuration from a `Config_manager`.
89 *
90 * @param config_manager
91 * A `Config_manager` which is currently managing the desired dynamic configuration.
92 * @param root_to_target_func_moved
93 * Translates a root configuration object to a contained target configuration object.
94 * @param d_value_set_idx
95 * The dynamic config slot index of `config_manager` which corresponds to the desired dynamic configuration.
96 * @see `Config_manager`.
97 */
98 template<typename... S_d_value_set>
100 Root_to_target_func&& root_to_target_func_moved, size_t d_value_set_idx = 0);
101
102 // Methods.
103
104 /**
105 * Obtain the root configuration.
106 *
107 * @return a ref-counted pointer to the (immutable) root configuration object.
108 */
109 typename Root::Const_ptr root_dynamic_cfg() const;
110
111 /**
112 * Obtain the target configuration.
113 *
114 * This method provides the key mechanism of the class. The returned pointer object can be used to easily access the
115 * target object, but will additionally cause the containing root object to be held valid in memory.
116 *
117 * @return a ref-counted pointer to the (immutable) target configuration object, but which shares ownership of the
118 * containing root configuration object.
119 */
120 Target_ptr dynamic_cfg() const;
121
122private:
123 // Data.
124
125 /// Called to obtain the root configuration.
127
128 /// Translates a root configuration object to a contained target configuration object.
130}; // class Dynamic_cfg_context
131
132// Template implementations.
133
134template<typename Root, typename Target, typename Target_ptr>
136 (Get_root_func&& get_root_func_moved, Root_to_target_func&& root_to_target_func_moved) :
137 m_get_root_func(std::move(get_root_func_moved)),
138 m_root_to_target_func(std::move(root_to_target_func_moved))
139{
140}
141
142template<typename Root, typename Target, typename Target_ptr>
143template<typename... S_d_value_set>
145 (const Config_manager<S_d_value_set...>& config_manager, Root_to_target_func&& root_to_target_func_moved,
146 size_t d_value_set_idx) :
147 m_get_root_func([&config_manager, d_value_set_idx]()
148 {
149 return config_manager.template dynamic_values<Root>(d_value_set_idx);
150 }),
151 m_root_to_target_func(std::move(root_to_target_func_moved))
152{
153}
154
155template<typename Root, typename Target, typename Target_ptr>
157{
158 return m_get_root_func();
159}
160
161template<typename Root, typename Target, typename Target_ptr>
163{
164 auto root = root_dynamic_cfg();
165 /* This aliasing constructor provides the key mechanism: the constructed pointer object *shares ownership* of `root`,
166 * but *stores* (and operates on) a pointer to the target object (contained by and translated from `root`). */
167 return Target_ptr(root, &(m_root_to_target_func(*root)));
168}
169
170} // namespace flow::cfg
Manages a config setup, intended for a single daemon process, by maintaining 1 or more set(s) of stat...
Class which facilitates managing access to a dynamic configuration.
const Root_to_target_func m_root_to_target_func
Translates a root configuration object to a contained target configuration object.
Target_ptr dynamic_cfg() const
Obtain the target configuration.
Root::Const_ptr root_dynamic_cfg() const
Obtain the root configuration.
Target_ptr Target_ptr_type
Type alias for Target_ptr.
const Get_root_func m_get_root_func
Called to obtain the root configuration.
Dynamic_cfg_context(Get_root_func &&get_root_func_moved, Root_to_target_func &&root_to_target_func_moved)
Constructor.
Flow module that facilitates configuring modules, such as applications and APIs, via statically and/o...
Definition: cfg_fwd.hpp:112