修订记录
版本 | 日期 | 变更内容 | 变更原因 |
---|---|---|---|
1.0 | 2024-12-23 | 创建 |
本篇文档介绍如何在插件系统中增加新的插件类型,如何新增插件接口和API,以及一些注意事项。
增加新的插件类型¶
新增插件类型枚举值并修改插件API版本号¶
代码位于src/plugin/include/oceanbase/ob_plugin.h。
插件类型枚举值定义是 ObPluginType
,只能在紧接着 OBP_PLUGIN_TYPE_MAX
之前新增,不能影响当前任何插件的类型的值。
插件版本号新增需要增加新的版本号定义,不能修改当前已有的版本号,比如新增 0.2.0 版本:
#define OBP_PLUGIN_API_VERSION OBP_MAKE_VERSION(0, 1, 0) // 已有版本号
#define OBP_PLUGIN_API_VERSION_020 OBP_MAKE_VERSION(0, 2, 0) // 新增版本号
// 修改当前版本号定义
#define OBP_PLUGIN_API_VERSION_CURRENT OBP_PLUGIN_API_VERSION_020
版本号的具体含义可以参考版本号约定。
抽象内部功能接口¶
某个功能插件化,最终这个功能模块调用相关的接口时不需要直接调用外部插件接口,但是需要先做好抽象,尽量抽出来单个模块接口,比如当前的分词器插件,抽象了两个类 ObIFTParserDesc 和 ObITokenIterator,其中 ObIFTParserDesc 继承了插件接口基类 ObIPluginDescriptor。在具体使用插件时,会根据插件的名称(可以加上版本号)查找具体的实现。
除了抽象接口,还可以在 ObPluginHelper 中增加根据名称查找具体实现的辅助函数,参考 ObPluginHelper::find_ftparser
。
新增插件C接口¶
我们约定,对外提供的插件开发库,开发者可以使用C语言来开发插件,所以对外提供的接口以C形式提供。
当我们已经实现了内部接口封装后,再封装为C接口会比较容易:通常是将class
中以virtual
函数提供的接口,改成struct
中成员变量的函数指针。但是需要注意:
- 需要使用 `extern "C"` 将所有对外暴露的符号(包括函数、类型、变量等)括起来,保证不会在C++编译时对这些符号做额外的修饰,而保持与C编译器输出结果一致;
- 增加版本号的定义。每个接口都有自己的版本号,方便开发者在开发和排查问题时,了解当前插件库中使用的版本号与内核使用的某个插件类型的版本号是对应或兼容的,可以参考分词器插件接口定义 `OBP_FTPARSER_INTERFACE_VERSION`;
- 增加相关的辅助函数。在插件接口调用时,一般需要在接口中传递参数,那参数的含义解释,也需要使用接口来定义,尽量不要使用结构体,因为接口可以保持更好的兼容性,即当我们想要增加成员变量时,不需要考虑成员变量的布局。可以参考分词器参数 `ObPluginFTParserParamPtr`以及相关的接口定义。所有的函数接口都必须以 obp_ 作为前缀,否则可能在链接后从observer中删除;
- 接口的实现,代码放在 src/plugin/export 中;
- 对外提供的数据结构、函数接口等需要增加 `OBP_PUBLIC_API`前缀,表示此接口对外暴露;
- 对外提供的接口,尽量增加开发者友好的代码注释和文档;
- 不要使用C中不能友好兼容的特性,默认使用C99标准;
- 对外接口只能提供声明,不允许包含任何实现;
创建C接口Adaptor¶
插件管理器在插件安装时会执行插件的初始化接口,所有注册上来的插件接口实现都会包装成 ObIPluginDescriptor
,因此我们需要把对外暴露的C接口封装一个适配器。适配器也方便内核功能模块调用。适配器的封装可以参考 ObFtParserAdaptor
。
编写样例代码¶
样例代码可以帮助开发者快速上手,所有插件类型必须有对应的样例代码。样例代码放在 src/plugin/examples/ 下。
记录变更日志¶
在CHANGELOG.md中描述本次变更的内容。
发布开发包¶
插件开发者可以仅依赖开发包提供的内容开发编译插件。可以使用rpm目录下的oceanbase-plugin-devel-build.sh脚本打包RPM包,同时也需要通过发布平台发布新版本的开发包。
插件接口或API变更¶
为了保持接口的兼容性,我们应该尽量新增接口,并且在内核中处理不同版本或旧的接口。
插件接口版本号调整¶
如果变更了某个类型的插件接口,应该同时调整对应的版本号。版本号的调整方法参考1.1章节。每个类型的插件接口都有自己的版本号,参考 ob_plugin_ftparser.h 文件中的 OBP_FTPARSER_INTERFACE_VERSION。
API 版本号调整¶
如果新增了API接口、某个插件类型的参数增加了功能、结构体变更等,就需要变更API的版本号,版本号调整参考修改API版本号。
注意,即使是仅与某个插件功能相关的接口发生了变更,也需要更新API版本号,就是只要更新了对外提供的API,就需要变更版本号。
注意事项¶
版本号约定¶
插件系统中所有与版本相关的概念都使用当前约定。版本号使用3个数字,即major、minor和patch:
- MAJOR:如果有不兼容的变更,或者新增了非常重大的特性;
- MINOR:新增了向后兼容(兼容旧版本)的功能或接口;
- PATCH:修复了一些向后兼容的BUG或一些细微的变动。
当前插件系统中每个版本号可以是从0到99,一共100个数字。
对外提供的接口都是C接口¶
对外提供的接口必须是C接口,使用C99支持的特性,不要使用兼容不太友好的特性以及C++的特性,比如:
- C++标准库;
- 命名空间;
_Alignas
和_Alignof
static_assert
如果不确定某个特性是否支持,可以查看 C99特性列表。其它的标准可以参考 C 标准列表。
基础能力封装¶
一些插件可能会需要使用到内核的基础能力,比如配置项、会话变量、系统变量等,这些基础能力应该由插件系统本身提供这种能力。
代码注释¶
对外提供的接口应该具有良好风格的代码注释,并使用doxygen 格式编写注释,注释语法可以参考doxygen文档。