这个作业属于哪个课程 | 广工2023软件工程课程 |
---|---|
这个作业要求在哪里 | 作业要求 |
文章内容 | 第二篇敏捷冲刺 |
文章目录
一、任务分配与预期任务量
模块 | 主要负责人 |
---|---|
日志模块 | 钟海超 |
配置模块 | 李昊旃 |
线程模块 | 江周勉 |
协程模块 | 宫旭 |
协程调度模块 | 赵光明 |
I/O协程调度模块 | 李伟东 |
Hook模块 | 邱棋浩(组长) |
二、近日任务安排
时间 | 任务 |
---|---|
今天 | 配置模块 |
明天 | 线程模块 |
三、实现
1.为什么需要配置模块
1.1 定义
将每个主机应该配置的服务、文件等信息保存在一台主机上,随时监控(通过采样的方式)每个目标主机是否处于期望状态,如果不是,强制转移为期望状态。这套系统称为配置系统。
1.2 作用
支持定义/声明配置项,也就是在提供配置名称、类型以及可选的默认值的情况下生成一个可用的配置项。由于一项配置可能在多个源文件中使用,所以配置模块还应该支持跨文件声明配置项的方法。
2.支持更新配置项的值。这点很好理解,配置项刚被定义时可能有一个初始默认值,但用户可能会有新的值来覆盖掉原来的值。
3.支持从预置的途径中加载配置项,一般是配置文件,也可以是命令行参数,或是网络服务器。这里不仅应该支持基本数据类型的加载,也应该支持复杂数据类型的加载,比如直接从配置文件中加载一个map类型的配置项,或是直接从一个预定格式的配置文件中加载一个自定义结构体。
4.支持给配置项注册配置变更通知。配置模块应该提供方法让程序知道某项配置被修改了,以便于进行一些操作。比如对于网络服务器而言,如果服务器端口配置变化了,那程序应该重新起监听端口。这个功能一般是通过注册回调函数来实现的,配置使用方预先给配置项注册一个配置变更回调函数,配置项发生变化时,触发对应的回调函数以通知调用方。由于一项配置可能在多个地方引用,所以配置变更回调函数应该是一个数组的形式。
5.支持给配置项设置校验方法。配置项在定义时也可以指定一个校验方法,以保证该项配置不会被设置成一个非法的值,比如对于文件路径类的配置,可以通过校验方法来确保该路径一定存在。
6.支持导出当前配置。
1.3 类的设计
2.配置模块设计
2.1 概述
在sylar的配置模块设计中,采用约定优于配置的思想,其常规使用方法如下:
sylar::ConfigVar<int>::ptr g_int_value_config =
sylar::Config::Lookup("system.port", (int)8080, "system port");
// 定义了system.port未int类型的8090,可通过g_int_value_config->getValue()获得当前参数值
其中“约定优于配置”,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。本质是说,开发人员仅需规定应用中不符约定的部分。例如,如果模型中有个名为Sale的类,那么数据库中对应的表就会默认命名为sales。只有在偏离这一约定时,例如将该表命名为"products_sold",才需写有关这个名字的配置。
2.2 配置模块相关类
* @brief 配置变量的基类
/**
* @brief 配置变量的基类
*/
class ConfigVarBase {};
/**
* @brief 类型转换模板类(F 源类型, T 目标类型)
*/
template<class F, class T>
class LexicalCast {};
/**
* @brief 配置参数模板子类,保存对应类型的参数值
* @details T 参数的具体类型
* FromStr 从std::string转换成T类型的仿函数
* ToStr 从T转换成std::string的仿函数
* std::string 为YAML格式的字符串
*/
template<class T, class FromStr = LexicalCast<std::string, T>
,class ToStr = LexicalCast<T, std::string> >
class ConfigVar : public ConfigVarBase {};
/**
* @brief ConfigVar的管理类
* @details 提供便捷的方法创建/访问ConfigVar
*/
class Config {};
ConfigVarBase:配置变量的基类,其主要是虚方法,定义了配置项中共有的成员和方法,其具体实验由基类的具体子类负责实现。其中重点是toString()方法和fromString()方法,其分别负责将配置信息转化字符串和从字符串中解析出配置。
ConfigVar:配置参数模板子类,并且是模板类,其具有三个模板参数,分别是配置项类型模板T、仿函数FromStr和仿函数Tostr。ConfigVar类在ConfigVarBase的基础上,增加了AddListener方法和delListener等方法,用于增删配置变更回调函数。
Config:ConfigVar的管理类,其提供便捷的方法创建、访问ConfigVar,其主要方法未Lookup方法,可根据配置的名称查询配置项,如果查询时未找到对应的配置则新建一个配置项。其还有从配置文件中读取配置、遍历所有配置项等方法。其中,Config中的方法都是static方法,确保全局只有一个实例。
2.3 YAML配置文件
YAML是一种简洁的非标记语言。YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读。
# yaml测试样例
# null 或 NULL 为关键字,不能写
# 名称
# 字符串
name: conf file
# 版本
# 如按浮点,2.0会转换成2
# 如按字符串,保留原样
version: 2.0
# 布尔类,转换为1或0
need: true
# 时间
time: 2020-10-03T09:21:13
empty: nul
# 对象
# 加双引号会转义\n,即会换行
my:
name: late \n lee
name1: "late \n lee"
age: 99
# 块
text: |
hello
world!
# 数组
fruit:
- apple
- apple1
- apple2
- apple3
- apple4
- apple5
# 多级数组
multi:
sta:
- 110 210 ddd 99
- 133 135 1 2 1588 1509
- 310-410
- 333-444
四、感想与期望
今天是敏捷冲刺的第二天,实现并测试配置模块,过程虽然遇到许多问题,但借助团队的帮助都能解决,希望接下来的模块能顺利完成