定时更新配置的C++实现
最近的几个系统都用到了定时更新配置
获取到的配置是需要高频使用的,不能直接使用字符串
需要预处理为整数或浮点数,甚至是一个整数数组
因此整理了一下Config设计:
分为元数据Meta,配置的存储和注册Config两个模块
Meta由用户来指定反射所需类型信息Config定义
Config是定时拉取远程的信息,用来更新本地的变量
Meta的职责
- 在Config中定位配置项的地址
- 配置默认值或拿到的字符串如何转化为值的lambda
- 这还提供了数据类型的信息
Config的职责
- 存储配置的实际数据
- 关联存储和元数据,将元数据注册进来,在外部调用updateConfig时更新所有关联元数据所存储的数据
类图如下
Meta还包含了一个lambda特化
在Config和Meta以外
- Value用于数据的存储,封装在Config类内不对外暴露
- ConfigHelper用于使用Config和Meta获取数据
classDiagram
direction LR
class MetaValue["Meta<T>"] {
+const char* key;
+T defaultValue;
}
class MetaFunc["template <typename Ret, typename... Args><br>Meta<function<Ret(Args...) noexcept>>"] {
+const char* key;
+function<Ret[Args...] noexcept> func
}
class ValueBase["ValueBase<InputConfigDataT>"] {
+virtual parse(const InputConfigDataT &)* void
}
class Value["Value<InputConfigDataT, T><br> : public ValueBase<InputConfigDataT>"] {
+Value(const function<T[const InputConfigDataT&]>&) //初始化parseFunc_
+parse(const InputConfigDataT&) void // override,使用注册的parseFunc_解析出值存储到value_
+getPtr() shared_ptr~T~ //使用atomic_load读取值
-setPtr(shared_ptr~T~ &) //使用atomic_store存储值
-shared_ptr~T~ value_;
-function<T[const InputConfigDataT&]> parseFunc_;
}
Value ..|> ValueBase
class Config["Config<InputConfigDataT>"] {
+virtual register()* void
#registerMeta(Meta~T~) void //实现了注册Meta的接口,用来override的register中调用
+updateConfig(const InputConfigDataT& data) //用于定时更新Config,这里对存储的values_依次调用parse(data)接口来存储数据
-map<const char*, ValueBase<InputConfigDataT>> values_;
}
Config *-- ValueBase
Config ..> MetaValue
class ConfigHelper {
+getPtr(const Config~InputConfigData~ &, const Meta~T~&)$void //将Config中values_存储的数据提取出来
}
ConfigHelper ..> Config
ConfigHelper ..> MetaValue
MetaFunc ..|> MetaValue
使用代码:
1 | //in LeafConfigClient.hpp |
单例数据可以再封装一层
1 | template <typename InputConfigDataT, typename MetaT> |