# 插件系统

Monibuca 采用插件化架构设计，通过插件机制来扩展功能。插件系统是 Monibuca 的核心特性之一，它允许开发者以模块化的方式添加新功能，而不需要修改核心代码。

## 插件生命周期

插件系统具有完整的生命周期管理，主要包含以下阶段：

### 1. 注册阶段

插件通过 `InstallPlugin` 泛型函数进行注册，在此阶段会：

- 创建插件元数据(PluginMeta)，包含：
  - 插件名称：自动从插件结构体名称中提取(去除"Plugin"后缀)
  - 插件版本：从调用者的文件路径或包路径中提取，如果无法提取则默认为"dev"
  - 插件类型：通过反射获取插件结构体类型
  
- 注册可选功能：
  - 退出处理器(OnExitHandler)
  - 默认配置(DefaultYaml)
  - 拉流器(Puller)
  - 推流器(Pusher)
  - 录制器(Recorder)
  - 转换器(Transformer)
  - 发布认证(AuthPublisher)
  - 订阅认证(AuthSubscriber)
  - gRPC服务(ServiceDesc)
  - gRPC网关处理器(RegisterGRPCHandler)

- 将插件元数据添加到全局插件列表中

注册阶段是插件生命周期的第一个阶段，它为插件系统提供了插件的基本信息和功能定义，为后续的初始化和启动做准备。

### 2. 初始化阶段 (Init)

插件通过 `Plugin.Init` 方法进行初始化，此阶段包含以下步骤：

1. 实例化检查
   - 检查插件是否实现了 IPlugin 接口
   - 通过反射获取插件实例

2. 基础设置
   - 设置插件元数据和服务器引用
   - 配置插件日志记录器
   - 设置插件名称和版本信息

3. 环境检查
   - 检查环境变量是否禁用插件(通过 {PLUGIN_NAME}_ENABLE=false)
   - 检查全局禁用状态(DisableAll)
   - 检查用户配置中的启用状态(enable)

4. 配置加载
   - 解析通用配置
   - 加载默认YAML配置
   - 合并用户配置
   - 应用最终配置并记录

5. 数据库初始化（如果需要）
   - 检查数据库连接配置(DSN)
   - 建立数据库连接
   - 自动迁移数据库表结构(针对录制功能)

6. 状态记录
   - 记录插件版本
   - 记录用户配置
   - 设置日志级别
   - 记录初始化状态

如果在初始化过程中发生错误：
- 插件将被标记为禁用状态
- 记录禁用原因
- 添加到已禁用插件列表

初始化阶段为插件的运行准备必要的环境和资源，是确保插件正常运行的关键阶段。

### 3. 启动阶段 (Start)

插件通过 `Plugin.Start` 方法启动，此阶段按顺序执行以下操作：

1. gRPC服务注册（如果配置）
   - 注册gRPC服务
   - 注册gRPC网关处理器
   - 处理gRPC相关错误

2. 插件管理
   - 将插件添加到服务器的插件列表中
   - 设置插件状态为运行中

3. 网络监听初始化
   - HTTP/HTTPS服务启动
   - TCP/TLS服务启动（如果实现了ITCPPlugin接口）
   - UDP服务启动（如果实现了IUDPPlugin接口）
   - QUIC服务启动（如果实现了IQUICPlugin接口）

4. 插件初始化回调
   - 调用插件的OnInit方法
   - 处理初始化错误

5. 定时任务设置
   - 配置服务器保活任务（如果启用）
   - 设置其他定时任务

如果在启动过程中发生错误：
- 记录错误原因
- 将插件标记为禁用状态
- 停止后续启动步骤

启动阶段是插件开始提供服务的关键阶段，此时插件完成了所有准备工作，可以开始处理业务逻辑。

### 4. 停止阶段 (Stop)

插件的停止阶段通过 `Plugin.OnStop` 方法和相关的停止处理逻辑实现，主要包含以下步骤：

1. 停止服务
   - 停止所有网络服务（HTTP/HTTPS/TCP/UDP/QUIC）
   - 关闭所有网络连接
   - 停止处理新的请求

2. 资源清理
   - 停止所有定时任务
   - 关闭数据库连接（如果有）
   - 清理临时文件和缓存

3. 状态处理
   - 更新插件状态为已停止
   - 从服务器的活动插件列表中移除
   - 触发停止事件通知

4. 回调处理
   - 调用插件自定义的OnStop方法
   - 执行注册的停止回调函数
   - 处理停止过程中的错误

5. 连接处理
   - 等待当前请求处理完成
   - 优雅关闭现有连接
   - 拒绝新的连接请求

停止阶段的主要目标是确保插件能够安全、干净地停止运行，不影响系统的其他部分。

### 5. 销毁阶段 (Destroy)

插件的销毁阶段通过 `Plugin.Dispose` 方法实现，这是插件生命周期的最后阶段，主要包含以下步骤：

1. 资源释放
   - 调用插件的OnStop方法进行停止处理
   - 从服务器的插件列表中移除
   - 释放所有分配的系统资源

2. 状态清理
   - 清除插件的所有状态信息
   - 重置插件的内部变量
   - 清空插件的配置信息

3. 连接断开
   - 断开与其他插件的所有连接
   - 清理插件间的依赖关系
   - 移除事件监听器

4. 数据清理
   - 清理插件产生的临时数据
   - 关闭并清理数据库连接
   - 删除不再需要的文件

5. 最终处理
   - 执行注册的销毁回调函数
   - 记录销毁日志
   - 确保所有资源都被正确释放

销毁阶段的主要目标是确保插件完全清理所有资源，不留下任何残留状态，防止内存泄漏和资源泄露。
