Sylar服务器框架——配置模块
创始人
2025-01-17 18:32:19
0

1、配置说明

  • 配置一般包含名称、值、类型、变更通知几项。其中名称对应一个字符串,必须唯一,不能与其他的配置冲突。类型可以是基本类型,也可以是复杂类型。关于值,最好给一个默认值,比如http默认端口是80。当配置项发生改变时,需要通知到使用该配置的代码。
    2、配置模块需要具有的功能
  • 可以定义配置项,也就是在提供配置名称、类型以及可选的默认值的情况下生成一个可用的配置项。由于一项配置可能在多个源文件中使用,所以配置模块还应该支持跨文件声明配置项的方法。
  • 应支持更新配置项的接口
  • 支持从配置文件中加载配置项,这里不仅应该支持基本数据类型的加载,也应该支持复杂数据类型的加载,比如直接从配置文件中加载一个map类型的配置项,或是直接从一个预定格式的配置文件中加载一个自定义结构体。
  • 支持配置项注册配置变更通知,配置模块应该提供方法让程序知道某项配置被修改了,以便于进行一些操作。比如对于网络服务器而言,如果服务器端口配置变化了,那程序应该重新起监听端口。这个功能一般是通过注册回调函数来实现的,配置使用方预先给配置项注册一个配置变更回调函数,配置项发生变化时,触发对应的回调函数以通知调用方。由于一项配置可能在多个地方引用,所以配置变更回调函数应该是一个数组的形式
  • 支持导出当前配置
    3、核心组件
  • ConfigVarBase: 配置项基类,虚基类,定义了配置项公有的成员和方法。sylar对每个配置项都包括名称和描述两项成员,以及toString/fromString两个纯虚函数方法。ConfigVarBase并不包含配置项类型和值,这些由继承类实现,由继承类实现的还包括具体类型的toString/fromString方法,用于和YAML字符串进行相互转换。
  • ConfigVar: 具体的配置参数类,继承自ConfigVarBase,并且是一个模板类,有3个模板参数。第一个模板参数是类型T,表示配置项的类型。另外两个模板参数是FromStr和ToStr,这两个参数是仿函数,FromStr用于将YAML字符串转类型T,ToStr用于将T转YAML字符串。这两个模板参数具有默认值LexicalCast和LexicalCast,根据不同的类型T,FromStr和ToStr具有不同的偏特化实现。ConfigVar类在ConfigVarBase上基础上包含了一个T类型的成员和一个变更回调函数数组,此外,ConfigVar还提供了setValue/getValue方法用于获取/更新配置值(更新配置时会一并触发全部的配置变更回调函数),以及addListener/delListener方法用于添加或删除配置变更回调函数。
  • Config: ConfigVar的管理类,负责托管全部的ConfigVar对象,单例模式。提供Lookup方法,用于根据配置名称查询配置项。如果调用Lookup查询时同时提供了默认值和配置项的描述信息,那么在未找到对应的配置时,会自动创建一个对应的配置项,这样就保证了配置模块定义即可用的特性。除此外,Config类还提供了LoadFromYaml和LoadFromConfDir两个方法,用于从YAML对象或从命令行-c选项指定的配置文件路径中加载配置。Config的全部成员变量和方法都是static类型,保证了全局只有一个实例。
    4、核心代码
    由于要支持从Yaml文件加载配置,一大难点就是既要支持普通类型又要支持想vector、list、set、map这些复杂类型。sylar的方法非常巧妙,使用模版类实现,并为每个类型实现了片特化。
/**  * @brief 类型转换模板类(F 源类型, T 目标类型)  */ template class LexicalCast { public:     /**      * @brief 类型转换      * @param[in] v 源类型值      * @return 返回v转换后的目标类型      * @exception 当类型不可转换时抛出异常      */     T operator()(const F& v) {         return boost::lexical_cast(v);     } };  /**  * @brief 类型转换模板类偏特化(YAML String 转换成 std::vector)  */ template class LexicalCast > { public:     std::vector operator()(const std::string& v) {         YAML::Node node = YAML::Load(v);         typename std::vector vec;         std::stringstream ss;         for(size_t i = 0; i < node.size(); ++i) {             ss.str("");             ss << node[i];             vec.push_back(LexicalCast()(ss.str()));         }         return vec;     } };  /**  * @brief 类型转换模板类偏特化(std::vector 转换成 YAML String)  */ template class LexicalCast, std::string> { public:     std::string operator()(const std::vector& v) {         YAML::Node node(YAML::NodeType::Sequence);         for(auto& i : v) {             node.push_back(YAML::Load(LexicalCast()(i)));         }         std::stringstream ss;         ss << node;         return ss.str();     } }; 

相关内容

热门资讯

2分钟德州透视挂!hhpoke... 2分钟德州透视挂!hhpoker开挂教程,德州透视插件,详细教程(有挂功能)1、完成德州透视插件透视...
九分钟开辅助!wepoker辅... 九分钟开辅助!wepoker辅助软件价格(透视底牌)详细辅助程序(本来是真的有挂)1、任何wepok...
9分钟透视插件!hh poke... 9分钟透视插件!hh poker软件,hhpoker是正品吗,详细教程(有挂智能)1、hh poke...
7分钟插件辅助!wepoker... 7分钟插件辅助!wepoker买钻石有用吗(透视底牌)详细辅助插件(果然是有挂)7分钟插件辅助!we...
八分钟作弊实战!hhpoker... 八分钟作弊实战!hhpoker脚本,hhpoker辅助靠谱吗,详细教程(有挂安装)1、完成hhpok...
二分钟苹果版!wepoker有... 二分钟苹果版!wepoker有辅助器吗(透视底牌)详细辅助免费(切实真的是有挂)1、点击下载安装,插...
八分钟破解工具!德州透视hhp... 八分钟破解工具!德州透视hhpoker,hh poker辅助器先试用,详细教程(有挂插件)1、该软件...
二分钟作弊!wepoker私人... 二分钟作弊!wepoker私人局可以透视(透视底牌)详细辅助作弊器(本来真的有挂);暗藏猫腻,小编详...
五分钟外挂!德扑HHpoker... 五分钟外挂!德扑HHpoker有挂吗(透视脚本)详细辅助助手(确实真的是有挂)1、任何ai辅助神器的...
5分钟新号!wepoker透视... 5分钟新号!wepoker透视器免费(透视底牌)详细辅助外挂(确实是真的有挂)1、打开软件启动之后找...