Files
plugins/plugin.go
T

1868 lines
46 KiB
Go

package plugins
import (
"context"
"encoding/json"
"fmt"
"io/fs"
"log"
"os"
"path/filepath"
"plugin"
"reflect"
"runtime"
"strconv"
"strings"
"sync"
"time"
)
// PluginInfo 插件信息
type PluginInfo struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author"`
Type PluginType `json:"type"`
Enabled bool `json:"enabled"`
Config map[string]interface{} `json:"config,omitempty"`
}
// PluginManager 插件管理器
type PluginManager struct {
pluginsDir string
plugins map[string]IPlugin
pluginsByType map[PluginType]map[string]IPlugin
configs map[string]map[string]interface{}
mu sync.RWMutex
dynamicLoadingSupported bool // 是否支持动态加载插件
eventHandlers map[PluginEventType][]PluginEventHandler // 全局事件处理器
}
// NewPluginManager 创建插件管理器
func NewPluginManager(pluginsDir string) *PluginManager {
// 检查当前系统是否支持动态加载插件
dynamicLoadingSupported := runtime.GOOS == "linux" || runtime.GOOS == "darwin"
return &PluginManager{
pluginsDir: pluginsDir,
plugins: make(map[string]IPlugin),
pluginsByType: make(map[PluginType]map[string]IPlugin),
configs: make(map[string]map[string]interface{}),
dynamicLoadingSupported: dynamicLoadingSupported,
eventHandlers: make(map[PluginEventType][]PluginEventHandler),
}
}
// IsDynamicLoadingSupported 检查是否支持动态加载插件
func (pm *PluginManager) IsDynamicLoadingSupported() bool {
return pm.dynamicLoadingSupported
}
// LoadPlugins 加载插件
func (pm *PluginManager) LoadPlugins() error {
// 确保插件目录存在
if err := os.MkdirAll(pm.pluginsDir, 0o755); err != nil {
return fmt.Errorf("创建插件目录失败: %v", err)
}
// 加载插件配置
if err := pm.loadPluginConfigs(); err != nil {
return fmt.Errorf("加载插件配置失败: %v", err)
}
// 如果不支持动态加载,则返回
if !pm.dynamicLoadingSupported {
fmt.Printf("警告: 当前系统(%s)不支持动态加载插件,跳过加载\n", runtime.GOOS)
return nil
}
// 遍历插件目录
err := filepath.Walk(pm.pluginsDir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
// 跳过目录和非.so文件
if info.IsDir() || filepath.Ext(path) != ".so" {
return nil
}
// 加载插件
if err := pm.loadPlugin(path); err != nil {
fmt.Printf("加载插件 %s 失败: %v\n", path, err)
}
return nil
})
return err
}
// loadPluginConfigs 加载插件配置
func (pm *PluginManager) loadPluginConfigs() error {
configPath := filepath.Join(pm.pluginsDir, "plugins.json")
// 先检查配置文件是否存在
_, err := os.Stat(configPath)
if os.IsNotExist(err) {
// 配置文件不存在,创建一个空的
// 注意:这里的文件IO操作在锁之外执行
file, err := os.Create(configPath)
if err != nil {
return fmt.Errorf("创建插件配置文件失败: %v", err)
}
file.Write([]byte("{}"))
file.Close()
// 初始化空配置
pm.mu.Lock()
pm.configs = make(map[string]map[string]interface{})
pm.mu.Unlock()
return nil
} else if err != nil {
return fmt.Errorf("检查插件配置文件状态失败: %v", err)
}
// 读取配置文件 - 在锁之外执行IO操作
data, err := os.ReadFile(configPath)
if err != nil {
return fmt.Errorf("读取插件配置文件失败: %v", err)
}
// 解析配置
var configs map[string]map[string]interface{}
if err := json.Unmarshal(data, &configs); err != nil {
return fmt.Errorf("解析插件配置文件失败: %v", err)
}
// 最后才用锁更新配置
pm.mu.Lock()
defer pm.mu.Unlock()
// 如果配置为nil,初始化为空映射
if configs == nil {
configs = make(map[string]map[string]interface{})
}
pm.configs = configs
return nil
}
// savePluginConfigs 保存插件配置
func (pm *PluginManager) savePluginConfigs() error {
configPath := filepath.Join(pm.pluginsDir, "plugins.json")
// 创建配置数据的深度副本,使用读锁,减少锁持有时间
configs := make(map[string]map[string]interface{})
pm.mu.RLock()
// 复制所有插件的配置
for name, plugin := range pm.plugins {
config := make(map[string]interface{})
// 获取并复制现有配置
if existingConfig, ok := pm.configs[name]; ok {
for k, v := range existingConfig {
// 对于复杂类型,执行深度复制
switch val := v.(type) {
case map[string]interface{}:
nestedMap := make(map[string]interface{})
for nk, nv := range val {
nestedMap[nk] = nv
}
config[k] = nestedMap
case []interface{}:
nestedArray := make([]interface{}, len(val))
copy(nestedArray, val)
config[k] = nestedArray
default:
config[k] = v
}
}
}
// 添加基本信息
config["enabled"] = plugin.IsEnabled()
config["type"] = string(plugin.Type())
configs[name] = config
}
pm.mu.RUnlock()
// 在释放锁后执行所有IO操作
// 序列化配置
data, err := json.MarshalIndent(configs, "", " ")
if err != nil {
return fmt.Errorf("序列化插件配置失败: %v", err)
}
// 创建临时文件
tmpDir := filepath.Dir(configPath)
// 确保目录存在
if err := os.MkdirAll(tmpDir, 0755); err != nil {
return fmt.Errorf("创建配置目录失败: %v", err)
}
// 使用一个唯一的临时文件名
tmpFile := fmt.Sprintf("%s.%d.tmp", configPath, time.Now().UnixNano())
if err := os.WriteFile(tmpFile, data, 0o644); err != nil {
return fmt.Errorf("写入临时配置文件失败: %v", err)
}
// 重命名临时文件为正式文件(原子操作)
if err := os.Rename(tmpFile, configPath); err != nil {
// 如果重命名失败,确保清理临时文件
os.Remove(tmpFile)
return fmt.Errorf("更新配置文件失败: %v", err)
}
return nil
}
// CheckDependencies 检查插件依赖关系
func (pm *PluginManager) CheckDependencies(plugin IPlugin) error {
dependencies := plugin.Dependencies()
if len(dependencies) == 0 {
return nil // 没有依赖,直接返回
}
for _, dep := range dependencies {
depPlugin, exists := pm.plugins[dep.Name]
if !exists {
if dep.IsOptional {
continue // 可选依赖,忽略
}
return fmt.Errorf("依赖的插件 %s 不存在", dep.Name)
}
// 验证版本兼容性
if dep.MinVersion != "" || dep.MaxVersion != "" {
currentVersion := depPlugin.Version()
if dep.MinVersion != "" {
result, err := compareVersions(currentVersion, dep.MinVersion)
if err != nil {
return fmt.Errorf("版本比较错误: %v", err)
}
if result < 0 {
return fmt.Errorf("依赖插件 %s 版本 %s 低于最低版本要求 %s",
dep.Name, currentVersion, dep.MinVersion)
}
}
if dep.MaxVersion != "" {
result, err := compareVersions(currentVersion, dep.MaxVersion)
if err != nil {
return fmt.Errorf("版本比较错误: %v", err)
}
if result > 0 {
return fmt.Errorf("依赖插件 %s 版本 %s 高于最高版本要求 %s",
dep.Name, currentVersion, dep.MaxVersion)
}
}
}
// 检查依赖插件是否启用
if !depPlugin.IsEnabled() && !dep.IsOptional {
if dep.AutoDisableWith {
// 自动禁用当前插件
plugin.SetEnabled(false)
return fmt.Errorf("依赖插件 %s 已禁用,当前插件自动禁用", dep.Name)
}
return fmt.Errorf("依赖插件 %s 已禁用", dep.Name)
}
}
return nil
}
// InitializeWithDependencies 根据依赖关系初始化插件
func (pm *PluginManager) InitializeWithDependencies(ctx context.Context) error {
// 构建依赖图
dependencyGraph := make(map[string][]string)
pluginDeps := make(map[string][]PluginDependency)
pm.mu.RLock()
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
deps := plugin.Dependencies()
pluginDeps[name] = deps
dependencyGraph[name] = []string{}
for _, dep := range deps {
if !dep.IsOptional && dep.InitAfter {
dependencyGraph[name] = append(dependencyGraph[name], dep.Name)
}
}
}
pm.mu.RUnlock()
// 拓扑排序
initOrder, err := topologicalSort(dependencyGraph)
if err != nil {
return fmt.Errorf("解析依赖关系失败: %v", err)
}
// 按依赖顺序初始化插件
for _, name := range initOrder {
pm.mu.RLock()
plugin, exists := pm.plugins[name]
config := pm.configs[name]
pm.mu.RUnlock()
if !exists || !plugin.IsEnabled() {
continue
}
if err := plugin.Init(ctx, config); err != nil {
return fmt.Errorf("初始化插件 %s 失败: %v", name, err)
}
}
return nil
}
// SubscribeEvent 订阅全局插件事件
func (pm *PluginManager) SubscribeEvent(eventType PluginEventType, handler PluginEventHandler) {
pm.mu.Lock()
defer pm.mu.Unlock()
if pm.eventHandlers[eventType] == nil {
pm.eventHandlers[eventType] = []PluginEventHandler{}
}
pm.eventHandlers[eventType] = append(pm.eventHandlers[eventType], handler)
}
// UnsubscribeEvent 取消订阅全局插件事件
func (pm *PluginManager) UnsubscribeEvent(eventType PluginEventType, handler PluginEventHandler) {
pm.mu.Lock()
defer pm.mu.Unlock()
if handlers, exists := pm.eventHandlers[eventType]; exists {
for i, h := range handlers {
if fmt.Sprintf("%p", h) == fmt.Sprintf("%p", handler) {
pm.eventHandlers[eventType] = append(handlers[:i], handlers[i+1:]...)
break
}
}
}
}
// HandleEvent 处理全局插件事件
func (pm *PluginManager) HandleEvent(event PluginEvent) {
pm.mu.RLock()
defer pm.mu.RUnlock()
if handlers, exists := pm.eventHandlers[event.Type]; exists {
for _, handler := range handlers {
handler(event) // 忽略错误,不影响其他处理器
}
}
}
// BroadcastEvent 广播插件事件到所有处理器
func (pm *PluginManager) BroadcastEvent(event PluginEvent) {
// 先处理全局事件
pm.HandleEvent(event)
// 再传播到特定插件
if event.PluginID != "" {
pm.mu.RLock()
plugin, exists := pm.plugins[event.PluginID]
pm.mu.RUnlock()
if exists {
plugin.EmitEvent(event)
}
}
}
// 加载插件时的事件通知
func (pm *PluginManager) notifyPluginLoaded(plugin IPlugin) {
pm.BroadcastEvent(PluginEvent{
Type: PluginEventLoaded,
PluginID: plugin.Name(),
Timestamp: time.Now(),
Data: map[string]interface{}{
"name": plugin.Name(),
"version": plugin.Version(),
"type": plugin.Type(),
},
})
}
// loadPlugin 加载单个插件
func (pm *PluginManager) loadPlugin(path string) error {
if !strings.HasSuffix(path, ".so") && !strings.HasSuffix(path, ".dll") {
return nil
}
// 打开插件
plug, err := plugin.Open(path)
if err != nil {
return fmt.Errorf("打开插件失败: %v", err)
}
// 查找 Plugin 符号
symPlugin, err := plug.Lookup("Plugin")
if err != nil {
return fmt.Errorf("查找 Plugin 符号失败: %v", err)
}
// 尝试直接类型断言
fmt.Printf("插件类型: %T\n", symPlugin)
if p, ok := symPlugin.(IPlugin); ok {
pm.registerPlugin(p)
pm.notifyPluginLoaded(p)
return nil
}
// 直接类型断言失败,尝试通过反射获取值
fmt.Println("直接类型断言失败,尝试通过反射获取值")
// 获取原始插件值,用于存储在适配器中
origValue := reflect.ValueOf(symPlugin)
// 尝试在所有指针级别上查找方法
// 保存每一级指针值,用于查找方法
pointerValues := []reflect.Value{origValue}
currentValue := origValue
// 解引用并保存每一级指针
for currentValue.Kind() == reflect.Ptr && currentValue.Elem().IsValid() {
currentValue = currentValue.Elem()
pointerValues = append(pointerValues, currentValue)
}
// 尝试在不同级别的指针上查找Name和Version方法
var nameMethod reflect.Value
var versionMethod reflect.Value
var methodPointerLevel reflect.Value
for _, ptrValue := range pointerValues {
nm := ptrValue.MethodByName("Name")
vm := ptrValue.MethodByName("Version")
if nm.IsValid() && vm.IsValid() {
nameMethod = nm
versionMethod = vm
methodPointerLevel = ptrValue
break
}
}
if !nameMethod.IsValid() || !versionMethod.IsValid() {
return fmt.Errorf("插件缺少必需的方法: Name 或 Version")
}
// 调用 Name 和 Version 方法获取基本信息
nameResult := nameMethod.Call(nil)
versionResult := versionMethod.Call(nil)
if len(nameResult) == 0 || len(versionResult) == 0 {
return fmt.Errorf("插件方法返回无效结果")
}
pluginName := nameResult[0].String()
pluginVersion := versionResult[0].String()
fmt.Printf("找到插件: %s (版本 %s)\n", pluginName, pluginVersion)
// 创建适配器以包装插件
adapter := &PluginAdapter{
symPlugin: symPlugin,
pluginValue: methodPointerLevel, // 使用找到有效方法的指针级别
pluginName: pluginName,
pluginVersion: pluginVersion,
}
// 使用找到方法的同一级别指针值检查是否具有Execute方法
executeMethod := methodPointerLevel.MethodByName("Execute")
if !executeMethod.IsValid() {
fmt.Printf("插件未实现 Execute 方法,尝试查找特定操作方法\n")
// 查找常见的操作方法,如果找到,也可以认为是有效插件
methodFound := false
commonMethods := []string{"Log", "Info", "Error", "GetStat", "SaveFile", "LoadFile"}
for _, methodName := range commonMethods {
if method := methodPointerLevel.MethodByName(methodName); method.IsValid() {
methodFound = true
break
}
}
if !methodFound {
return fmt.Errorf("插件类型错误: 未实现 Execute 方法或任何已知的操作方法")
}
}
pm.registerPlugin(adapter)
pm.notifyPluginLoaded(adapter)
return nil
}
// registerPlugin 注册插件到插件管理器
func (pm *PluginManager) registerPlugin(plugin IPlugin) {
name := plugin.Name()
// 检查插件名称是否已存在
pm.mu.Lock()
defer pm.mu.Unlock()
if _, exists := pm.plugins[name]; exists {
log.Printf("警告: 插件 %s 已存在,将被覆盖", name)
}
// 设置插件启用状态
if config, exists := pm.configs[name]; exists {
if enabled, ok := config["enabled"].(bool); ok {
plugin.SetEnabled(enabled)
} else {
plugin.SetEnabled(true) // 默认启用
}
} else {
plugin.SetEnabled(true) // 默认启用
}
// 检查依赖关系
if err := pm.CheckDependencies(plugin); err != nil {
log.Printf("警告: 插件 %s 依赖检查失败: %v", name, err)
}
// 添加到插件映射
pm.plugins[name] = plugin
// 添加到类型映射
pluginType := plugin.Type()
if pm.pluginsByType[pluginType] == nil {
pm.pluginsByType[pluginType] = make(map[string]IPlugin)
}
pm.pluginsByType[pluginType][name] = plugin
log.Printf("插件 %s (类型: %s, 版本: %s) 已注册", name, pluginType, plugin.Version())
}
// RegisterPlugin 注册内置插件, 用于在不支持动态加载的平台上注册插件
func (pm *PluginManager) RegisterPlugin(plugin IPlugin) error {
pm.mu.Lock()
defer pm.mu.Unlock()
if _, exists := pm.plugins[plugin.Name()]; exists {
return fmt.Errorf("插件 %s 已存在", plugin.Name())
}
// 设置插件启用状态
if config, exists := pm.configs[plugin.Name()]; exists {
if enabled, ok := config["enabled"].(bool); ok {
plugin.SetEnabled(enabled)
} else {
plugin.SetEnabled(true) // 默认启用
}
} else {
plugin.SetEnabled(true) // 默认启用
}
// 检查依赖关系
if err := pm.CheckDependencies(plugin); err != nil {
return fmt.Errorf("依赖检查失败: %v", err)
}
// 注册插件
pm.registerPlugin(plugin)
// 通知插件已加载
go pm.notifyPluginLoaded(plugin)
return nil
}
// GetPlugin 获取插件
func (pm *PluginManager) GetPlugin(name string) (IPlugin, bool) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
return plugin, exists
}
// GetPluginsByType 按类型获取插件
func (pm *PluginManager) GetPluginsByType(pluginType PluginType) []IPlugin {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugins := make([]IPlugin, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for _, plugin := range typePlugins {
if plugin.IsEnabled() {
plugins = append(plugins, plugin)
}
}
}
return plugins
}
// GetAllPluginsByType 获取所有指定类型的插件,无论是否启用
func (pm *PluginManager) GetAllPluginsByType(pluginType PluginType) []IPlugin {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugins := make([]IPlugin, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for _, plugin := range typePlugins {
plugins = append(plugins, plugin)
}
}
return plugins
}
// GetAllPlugins 获取所有插件
func (pm *PluginManager) GetAllPlugins() []IPlugin {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugins := make([]IPlugin, 0, len(pm.plugins))
for _, plugin := range pm.plugins {
plugins = append(plugins, plugin)
}
return plugins
}
// GetPluginInfos 获取所有插件信息
func (pm *PluginManager) GetPluginInfos() []PluginInfo {
pm.mu.RLock()
defer pm.mu.RUnlock()
infos := make([]PluginInfo, 0, len(pm.plugins))
for name, plugin := range pm.plugins {
info := PluginInfo{
Name: plugin.Name(),
Version: plugin.Version(),
Description: plugin.Description(),
Author: plugin.Author(),
Type: plugin.Type(),
Enabled: plugin.IsEnabled(),
Config: pm.configs[name],
}
infos = append(infos, info)
}
return infos
}
// GetPluginInfosByType 按类型获取插件信息
func (pm *PluginManager) GetPluginInfosByType(pluginType PluginType) []PluginInfo {
pm.mu.RLock()
defer pm.mu.RUnlock()
infos := make([]PluginInfo, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
info := PluginInfo{
Name: plugin.Name(),
Version: plugin.Version(),
Description: plugin.Description(),
Author: plugin.Author(),
Type: plugin.Type(),
Enabled: plugin.IsEnabled(),
Config: pm.configs[name],
}
infos = append(infos, info)
}
}
return infos
}
// EnablePlugin 启用插件
func (pm *PluginManager) EnablePlugin(name string) error {
// 先获取插件,避免长时间持有锁
pm.mu.RLock()
plugin, exists := pm.plugins[name]
pm.mu.RUnlock()
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
// 设置插件状态
plugin.SetEnabled(true)
// 更新配置
config := make(map[string]interface{})
pm.mu.RLock()
if existingConfig, ok := pm.configs[name]; ok {
// 复制现有配置
for k, v := range existingConfig {
config[k] = v
}
}
pm.mu.RUnlock()
config["enabled"] = true
// 使用单独的锁来更新配置
pm.mu.Lock()
pm.configs[name] = config
pm.mu.Unlock()
// 保存配置到文件
return pm.savePluginConfigs()
}
// DisablePlugin 禁用插件
func (pm *PluginManager) DisablePlugin(name string) error {
// 先获取插件,避免长时间持有锁
pm.mu.RLock()
plugin, exists := pm.plugins[name]
pm.mu.RUnlock()
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
// 设置插件状态
plugin.SetEnabled(false)
// 更新配置
config := make(map[string]interface{})
pm.mu.RLock()
if existingConfig, ok := pm.configs[name]; ok {
// 复制现有配置
for k, v := range existingConfig {
config[k] = v
}
}
pm.mu.RUnlock()
config["enabled"] = false
// 使用单独的锁来更新配置
pm.mu.Lock()
pm.configs[name] = config
pm.mu.Unlock()
// 保存配置到文件
return pm.savePluginConfigs()
}
// InitPlugins 初始化所有插件
func (pm *PluginManager) InitPlugins(ctx context.Context) error {
// 使用基于依赖的初始化
return pm.InitializeWithDependencies(ctx)
}
// InitPluginsByType 初始化指定类型的所有插件
func (pm *PluginManager) InitPluginsByType(ctx context.Context, pluginType PluginType) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
config := pm.configs[name]
if err := plugin.Init(ctx, config); err != nil {
return fmt.Errorf("初始化插件 %s 失败: %v", name, err)
}
}
}
return nil
}
// StartPlugins 启动所有插件
func (pm *PluginManager) StartPlugins(ctx context.Context) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Start(ctx); err != nil {
return fmt.Errorf("启动插件 %s 失败: %v", name, err)
}
}
return nil
}
// StartPluginsByType 启动指定类型的所有插件
func (pm *PluginManager) StartPluginsByType(ctx context.Context, pluginType PluginType) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Start(ctx); err != nil {
return fmt.Errorf("启动插件 %s 失败: %v", name, err)
}
}
}
return nil
}
// StopPlugins 停止所有插件
func (pm *PluginManager) StopPlugins(ctx context.Context) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Stop(ctx); err != nil {
return fmt.Errorf("停止插件 %s 失败: %v", name, err)
}
}
return nil
}
// StopPluginsByType 停止指定类型的所有插件
func (pm *PluginManager) StopPluginsByType(ctx context.Context, pluginType PluginType) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Stop(ctx); err != nil {
return fmt.Errorf("停止插件 %s 失败: %v", name, err)
}
}
}
return nil
}
// SetPluginConfig 设置插件配置
func (pm *PluginManager) SetPluginConfig(name string, config map[string]interface{}) error {
// 先检查插件是否存在,使用读锁
pm.mu.RLock()
_, exists := pm.plugins[name]
pm.mu.RUnlock()
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
// 创建配置的深度副本
configCopy := make(map[string]interface{})
for k, v := range config {
// 对复杂类型进行深度复制
switch val := v.(type) {
case map[string]interface{}:
// 复制嵌套的map
nestedMap := make(map[string]interface{})
for nk, nv := range val {
nestedMap[nk] = nv
}
configCopy[k] = nestedMap
case []interface{}:
// 复制数组
nestedArray := make([]interface{}, len(val))
copy(nestedArray, val)
configCopy[k] = nestedArray
default:
// 简单类型直接复制
configCopy[k] = v
}
}
// 使用写锁更新配置,但尽量减少锁持有时间
pm.mu.Lock()
pm.configs[name] = configCopy
pm.mu.Unlock()
// 创建一个带有超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 使用 channel 来处理保存操作
errChan := make(chan error, 1)
go func() {
errChan <- pm.savePluginConfigs()
}()
// 等待保存完成或超时
select {
case err := <-errChan:
return err
case <-ctx.Done():
return fmt.Errorf("保存配置超时")
}
}
// GetPluginConfig 获取插件配置
func (pm *PluginManager) GetPluginConfig(name string) (map[string]interface{}, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
if _, exists := pm.plugins[name]; !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
// 确保存在配置
config := pm.configs[name]
if config == nil {
return make(map[string]interface{}), nil
}
// 创建配置的深度副本
result := make(map[string]interface{})
for k, v := range config {
// 对复杂类型进行深度复制
switch val := v.(type) {
case map[string]interface{}:
// 复制嵌套的map
nestedMap := make(map[string]interface{})
for nk, nv := range val {
nestedMap[nk] = nv
}
result[k] = nestedMap
case []interface{}:
// 复制数组
nestedArray := make([]interface{}, len(val))
copy(nestedArray, val)
result[k] = nestedArray
default:
// 简单类型直接复制
result[k] = v
}
}
return result, nil
}
// ExecutePlugin 执行指定插件的操作
func (pm *PluginManager) ExecutePlugin(ctx context.Context, name string, action string, params map[string]interface{}) (interface{}, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
if !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
if !plugin.IsEnabled() {
return nil, fmt.Errorf("插件 %s 已禁用", name)
}
return plugin.Execute(ctx, action, params)
}
// ExecutePluginsByType 对指定类型的所有插件执行操作
func (pm *PluginManager) ExecutePluginsByType(ctx context.Context, pluginType PluginType, action string, params map[string]interface{}) map[string]interface{} {
pm.mu.RLock()
defer pm.mu.RUnlock()
results := make(map[string]interface{})
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
result, err := plugin.Execute(ctx, action, params)
results[name] = map[string]interface{}{
"result": result,
"error": err,
}
}
}
return results
}
// ExecuteAllPlugins 对所有插件执行操作
func (pm *PluginManager) ExecuteAllPlugins(ctx context.Context, action string, params map[string]interface{}) map[string]interface{} {
pm.mu.RLock()
defer pm.mu.RUnlock()
results := make(map[string]interface{})
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
result, err := plugin.Execute(ctx, action, params)
results[name] = map[string]interface{}{
"result": result,
"error": err,
}
}
return results
}
// GetPluginOperationInfo 获取插件特定操作的参数信息
func (pm *PluginManager) GetPluginOperationInfo(name string, operation string) (*OperationInfo, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
if !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
if !plugin.IsEnabled() {
return nil, fmt.Errorf("插件 %s 已禁用", name)
}
return plugin.GetOperationInfo(operation)
}
// GetPluginAllOperations 获取插件所有操作及其参数信息
func (pm *PluginManager) GetPluginAllOperations(name string) (*PluginOperations, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
if !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
if !plugin.IsEnabled() {
return nil, fmt.Errorf("插件 %s 已禁用", name)
}
ops := plugin.GetAllOperations()
return &PluginOperations{
PluginName: plugin.Name(),
PluginType: plugin.Type(),
Operations: ops,
}, nil
}
// GetOperationsByType 获取指定类型插件的所有操作信息
func (pm *PluginManager) GetOperationsByType(pluginType PluginType) []*PluginOperations {
pm.mu.RLock()
defer pm.mu.RUnlock()
result := make([]*PluginOperations, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for _, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
ops := plugin.GetAllOperations()
result = append(result, &PluginOperations{
PluginName: plugin.Name(),
PluginType: plugin.Type(),
Operations: ops,
})
}
}
return result
}
// GetAllPluginsOperations 获取所有插件的所有操作信息
func (pm *PluginManager) GetAllPluginsOperations() []*PluginOperations {
pm.mu.RLock()
defer pm.mu.RUnlock()
result := make([]*PluginOperations, 0, len(pm.plugins))
for _, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
ops := plugin.GetAllOperations()
result = append(result, &PluginOperations{
PluginName: plugin.Name(),
PluginType: plugin.Type(),
Operations: ops,
})
}
return result
}
// ReloadPlugin 重新加载单个插件
func (pm *PluginManager) ReloadPlugin(ctx context.Context, name string) error {
pm.mu.Lock()
plugin, exists := pm.plugins[name]
config := pm.configs[name]
pm.mu.Unlock()
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
// 发出重载事件
pm.BroadcastEvent(PluginEvent{
Type: PluginEventCustom,
PluginID: name,
Timestamp: time.Now(),
Data: map[string]interface{}{
"action": "reloading",
},
})
// 执行重载
if err := plugin.Reload(ctx, config); err != nil {
// 发送错误事件
pm.BroadcastEvent(PluginEvent{
Type: PluginEventError,
PluginID: name,
Timestamp: time.Now(),
Data: map[string]interface{}{
"error": err.Error(),
"context": "reload",
},
})
return fmt.Errorf("重载插件 %s 失败: %v", name, err)
}
// 发送重载完成事件
pm.BroadcastEvent(PluginEvent{
Type: PluginEventCustom,
PluginID: name,
Timestamp: time.Now(),
Data: map[string]interface{}{
"action": "reloaded",
},
})
return nil
}
// ReloadAllPlugins 重新加载所有插件
func (pm *PluginManager) ReloadAllPlugins(ctx context.Context) map[string]error {
errors := make(map[string]error)
pm.mu.RLock()
pluginNames := make([]string, 0, len(pm.plugins))
for name := range pm.plugins {
pluginNames = append(pluginNames, name)
}
pm.mu.RUnlock()
for _, name := range pluginNames {
if err := pm.ReloadPlugin(ctx, name); err != nil {
errors[name] = err
}
}
return errors
}
// InstallErrorHandler 为插件安装错误处理器
func (pm *PluginManager) InstallErrorHandler() {
pm.SubscribeEvent(PluginEventError, func(event PluginEvent) error {
errData, ok := event.Data["error"].(string)
if !ok {
errData = "未知错误"
}
context, _ := event.Data["context"].(string)
if context == "" {
context = "general"
}
fmt.Printf("[错误] 插件 %s 在 %s 上下文中发生错误: %s\n",
event.PluginID, context, errData)
return nil
})
}
// RecoverPlugin 尝试恢复错误状态的插件
func (pm *PluginManager) RecoverPlugin(ctx context.Context, name string) error {
pm.mu.Lock()
plugin, exists := pm.plugins[name]
config := pm.configs[name]
pm.mu.Unlock()
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
if plugin.Status() != PluginStatusError {
return nil // 插件不在错误状态,无需恢复
}
// 尝试清理、重新初始化和启动
if err := plugin.Cleanup(ctx); err != nil {
return fmt.Errorf("清理插件失败: %v", err)
}
if err := plugin.Init(ctx, config); err != nil {
return fmt.Errorf("重新初始化插件失败: %v", err)
}
if plugin.IsEnabled() {
if err := plugin.Start(ctx); err != nil {
return fmt.Errorf("重新启动插件失败: %v", err)
}
}
// 发送恢复事件
pm.BroadcastEvent(PluginEvent{
Type: PluginEventCustom,
PluginID: name,
Timestamp: time.Now(),
Data: map[string]interface{}{
"action": "recovered",
},
})
return nil
}
// RecoverAllPlugins 尝试恢复所有错误状态的插件
func (pm *PluginManager) RecoverAllPlugins(ctx context.Context) map[string]error {
errors := make(map[string]error)
pm.mu.RLock()
plugins := make([]IPlugin, 0)
for _, plugin := range pm.plugins {
if plugin.Status() == PluginStatusError {
plugins = append(plugins, plugin)
}
}
pm.mu.RUnlock()
for _, plugin := range plugins {
name := plugin.Name()
if err := pm.RecoverPlugin(ctx, name); err != nil {
errors[name] = err
}
}
return errors
}
// UnloadPlugin 卸载插件
func (pm *PluginManager) UnloadPlugin(ctx context.Context, name string) error {
pm.mu.Lock()
defer pm.mu.Unlock()
plugin, exists := pm.plugins[name]
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
// 检查是否有其他插件依赖该插件
for otherName, otherPlugin := range pm.plugins {
if otherName == name {
continue
}
for _, dep := range otherPlugin.Dependencies() {
if dep.Name == name && !dep.IsOptional {
return fmt.Errorf("无法卸载插件 %s: 插件 %s 依赖它", name, otherName)
}
}
}
// 停止并清理插件
if plugin.Status() == PluginStatusRunning {
if err := plugin.Stop(ctx); err != nil {
return fmt.Errorf("停止插件失败: %v", err)
}
}
if err := plugin.Cleanup(ctx); err != nil {
return fmt.Errorf("清理插件失败: %v", err)
}
// 从管理器中移除插件
delete(pm.plugins, name)
if typePlugins, exists := pm.pluginsByType[plugin.Type()]; exists {
delete(typePlugins, name)
}
// 发送卸载事件
pm.BroadcastEvent(PluginEvent{
Type: PluginEventCustom,
PluginID: name,
Timestamp: time.Now(),
Data: map[string]interface{}{
"action": "unloaded",
},
})
return nil
}
// topologicalSort 拓扑排序,解决依赖顺序问题
func topologicalSort(graph map[string][]string) ([]string, error) {
result := make([]string, 0, len(graph))
visited := make(map[string]bool)
temp := make(map[string]bool)
var visit func(string) error
visit = func(node string) error {
if temp[node] {
return fmt.Errorf("检测到循环依赖: %s", node)
}
if visited[node] {
return nil
}
temp[node] = true
for _, dep := range graph[node] {
if err := visit(dep); err != nil {
return err
}
}
temp[node] = false
visited[node] = true
result = append(result, node)
return nil
}
for node := range graph {
if !visited[node] {
if err := visit(node); err != nil {
return nil, err
}
}
}
return result, nil
}
// 简单的版本比较函数
func compareVersions(v1, v2 string) (int, error) {
// 移除可能的'v'前缀
v1 = strings.TrimPrefix(v1, "v")
v2 = strings.TrimPrefix(v2, "v")
// 分割版本号
parts1 := strings.Split(v1, ".")
parts2 := strings.Split(v2, ".")
// 确保有足够的部分进行比较
for len(parts1) < 3 {
parts1 = append(parts1, "0")
}
for len(parts2) < 3 {
parts2 = append(parts2, "0")
}
// 比较各部分
for i := 0; i < 3; i++ {
n1, err := strconv.Atoi(parts1[i])
if err != nil {
return 0, fmt.Errorf("无效的版本号部分 %s: %v", parts1[i], err)
}
n2, err := strconv.Atoi(parts2[i])
if err != nil {
return 0, fmt.Errorf("无效的版本号部分 %s: %v", parts2[i], err)
}
if n1 < n2 {
return -1, nil // v1 < v2
} else if n1 > n2 {
return 1, nil // v1 > v2
}
}
return 0, nil // v1 == v2
}
// PluginAdapter 插件适配器
// 用于将通过反射获取的插件包装为 IPlugin 接口
type PluginAdapter struct {
symPlugin interface{}
pluginValue reflect.Value
pluginName string
pluginVersion string
}
// Name 获取插件名称
func (p *PluginAdapter) Name() string {
return p.pluginName
}
// Version 获取插件版本
func (p *PluginAdapter) Version() string {
return p.pluginVersion
}
// Description 获取插件描述
func (p *PluginAdapter) Description() string {
method := p.pluginValue.MethodByName("Description")
if !method.IsValid() {
return "未提供描述"
}
return method.Call(nil)[0].String()
}
// Author 获取插件作者
func (p *PluginAdapter) Author() string {
method := p.pluginValue.MethodByName("Author")
if !method.IsValid() {
return "未知作者"
}
return method.Call(nil)[0].String()
}
// Type 获取插件类型
func (p *PluginAdapter) Type() PluginType {
method := p.pluginValue.MethodByName("Type")
if !method.IsValid() {
return PluginTypeGeneral
}
return PluginType(method.Call(nil)[0].String())
}
// Status 获取插件状态
func (p *PluginAdapter) Status() PluginStatus {
method := p.pluginValue.MethodByName("Status")
if !method.IsValid() {
return PluginStatusUninitialized
}
return PluginStatus(method.Call(nil)[0].String())
}
// Dependencies 获取插件依赖
func (p *PluginAdapter) Dependencies() []PluginDependency {
method := p.pluginValue.MethodByName("Dependencies")
if !method.IsValid() {
return []PluginDependency{}
}
result := method.Call(nil)[0]
if result.IsNil() {
return []PluginDependency{}
}
// 尝试直接类型断言
if dependencies, ok := result.Interface().([]PluginDependency); ok {
return dependencies
}
// 尝试使用反射迭代切片并转换每个元素
if result.Kind() == reflect.Slice {
length := result.Len()
dependencies := make([]PluginDependency, 0, length)
for i := 0; i < length; i++ {
item := result.Index(i).Interface()
// 尝试将元素转换为PluginDependency
if dep, ok := item.(PluginDependency); ok {
dependencies = append(dependencies, dep)
} else {
// 如果无法直接转换,尝试使用反射读取字段
depValue := reflect.ValueOf(item)
if depValue.Kind() == reflect.Struct || (depValue.Kind() == reflect.Ptr && depValue.Elem().Kind() == reflect.Struct) {
// 解引用指针
if depValue.Kind() == reflect.Ptr {
depValue = depValue.Elem()
}
dependency := PluginDependency{}
// 获取字段值
if nameField := depValue.FieldByName("Name"); nameField.IsValid() {
dependency.Name = nameField.String()
}
if minVersionField := depValue.FieldByName("MinVersion"); minVersionField.IsValid() {
dependency.MinVersion = minVersionField.String()
}
if maxVersionField := depValue.FieldByName("MaxVersion"); maxVersionField.IsValid() {
dependency.MaxVersion = maxVersionField.String()
}
if isOptionalField := depValue.FieldByName("IsOptional"); isOptionalField.IsValid() && isOptionalField.Kind() == reflect.Bool {
dependency.IsOptional = isOptionalField.Bool()
}
if loadAfterField := depValue.FieldByName("LoadAfter"); loadAfterField.IsValid() && loadAfterField.Kind() == reflect.Bool {
dependency.LoadAfter = loadAfterField.Bool()
}
if initAfterField := depValue.FieldByName("InitAfter"); initAfterField.IsValid() && initAfterField.Kind() == reflect.Bool {
dependency.InitAfter = initAfterField.Bool()
}
if strictVersionsField := depValue.FieldByName("StrictVersions"); strictVersionsField.IsValid() && strictVersionsField.Kind() == reflect.Bool {
dependency.StrictVersions = strictVersionsField.Bool()
}
if autoDisableWithField := depValue.FieldByName("AutoDisableWith"); autoDisableWithField.IsValid() && autoDisableWithField.Kind() == reflect.Bool {
dependency.AutoDisableWith = autoDisableWithField.Bool()
}
dependencies = append(dependencies, dependency)
}
}
}
return dependencies
}
return []PluginDependency{}
}
// Init 初始化插件
func (p *PluginAdapter) Init(ctx context.Context, config map[string]interface{}) error {
method := p.pluginValue.MethodByName("Init")
if !method.IsValid() {
fmt.Printf("插件 %s 没有 Init 方法,跳过初始化\n", p.Name())
return nil
}
args := []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(config),
}
result := method.Call(args)
if len(result) > 0 && !result[0].IsNil() {
return result[0].Interface().(error)
}
return nil
}
// Start 启动插件
func (p *PluginAdapter) Start(ctx context.Context) error {
method := p.pluginValue.MethodByName("Start")
if !method.IsValid() {
fmt.Printf("插件 %s 没有 Start 方法,跳过启动\n", p.Name())
return nil
}
args := []reflect.Value{
reflect.ValueOf(ctx),
}
result := method.Call(args)
if len(result) > 0 && !result[0].IsNil() {
return result[0].Interface().(error)
}
return nil
}
// Stop 停止插件
func (p *PluginAdapter) Stop(ctx context.Context) error {
method := p.pluginValue.MethodByName("Stop")
if !method.IsValid() {
return fmt.Errorf("插件未实现 Stop 方法")
}
args := []reflect.Value{
reflect.ValueOf(ctx),
}
result := method.Call(args)
if len(result) > 0 && !result[0].IsNil() {
return result[0].Interface().(error)
}
return nil
}
// IsEnabled 插件是否启用
func (p *PluginAdapter) IsEnabled() bool {
method := p.pluginValue.MethodByName("IsEnabled")
if !method.IsValid() {
return true
}
return method.Call(nil)[0].Bool()
}
// SetEnabled 设置插件启用状态
func (p *PluginAdapter) SetEnabled(enabled bool) {
method := p.pluginValue.MethodByName("SetEnabled")
if !method.IsValid() {
return
}
args := []reflect.Value{
reflect.ValueOf(enabled),
}
method.Call(args)
}
// GetOperationInfo 获取操作的参数信息
func (p *PluginAdapter) GetOperationInfo(operation string) (*OperationInfo, error) {
method := p.pluginValue.MethodByName("GetOperationInfo")
if !method.IsValid() {
return nil, fmt.Errorf("插件未实现 GetOperationInfo 方法")
}
args := []reflect.Value{
reflect.ValueOf(operation),
}
result := method.Call(args)
if len(result) > 1 && !result[1].IsNil() {
return nil, result[1].Interface().(error)
}
if result[0].IsNil() {
return nil, nil
}
// 尝试直接类型断言
if opInfo, ok := result[0].Interface().(*OperationInfo); ok {
return opInfo, nil
}
// 如果直接断言失败,尝试使用反射获取字段值
opValue := reflect.Indirect(result[0])
if opValue.Kind() != reflect.Struct {
// 如果不是结构体,返回基本信息
return &OperationInfo{
Name: operation,
Description: "通过适配器调用的操作",
Params: []OperationParamInfo{},
}, nil
}
// 创建操作信息对象
opInfo := &OperationInfo{
Name: operation,
Description: "",
Params: []OperationParamInfo{},
Extra: make(map[string]interface{}),
}
// 获取描述字段
if descField := opValue.FieldByName("Description"); descField.IsValid() && descField.Kind() == reflect.String {
opInfo.Description = descField.String()
}
// 获取参数列表
if paramsField := opValue.FieldByName("Params"); paramsField.IsValid() && paramsField.Kind() == reflect.Slice {
length := paramsField.Len()
opInfo.Params = make([]OperationParamInfo, 0, length)
for i := 0; i < length; i++ {
paramValue := reflect.Indirect(paramsField.Index(i))
if paramValue.Kind() != reflect.Struct {
continue
}
param := OperationParamInfo{}
// 获取参数字段
if nameField := paramValue.FieldByName("Name"); nameField.IsValid() && nameField.Kind() == reflect.String {
param.Name = nameField.String()
}
if typeField := paramValue.FieldByName("Type"); typeField.IsValid() && typeField.Kind() == reflect.String {
param.Type = typeField.String()
}
if requiredField := paramValue.FieldByName("Required"); requiredField.IsValid() && requiredField.Kind() == reflect.Bool {
param.Required = requiredField.Bool()
}
if defaultField := paramValue.FieldByName("Default"); defaultField.IsValid() {
param.Default = defaultField.Interface()
}
if descField := paramValue.FieldByName("Description"); descField.IsValid() && descField.Kind() == reflect.String {
param.Description = descField.String()
}
opInfo.Params = append(opInfo.Params, param)
}
}
// 获取额外信息
if extraField := opValue.FieldByName("Extra"); extraField.IsValid() && extraField.Kind() == reflect.Map {
for _, key := range extraField.MapKeys() {
if key.Kind() == reflect.String {
opInfo.Extra[key.String()] = extraField.MapIndex(key).Interface()
}
}
}
return opInfo, nil
}
// GetAllOperations 获取所有操作及其参数信息
func (p *PluginAdapter) GetAllOperations() []*OperationInfo {
method := p.pluginValue.MethodByName("GetAllOperations")
if !method.IsValid() {
return []*OperationInfo{}
}
result := method.Call(nil)[0]
if result.IsNil() {
return []*OperationInfo{}
}
// 解析返回的操作信息并返回
if operations, ok := result.Interface().([]*OperationInfo); ok {
return operations
}
// 尝试使用反射获取切片内容
if result.Kind() == reflect.Slice {
length := result.Len()
operations := make([]*OperationInfo, 0, length)
for i := 0; i < length; i++ {
item := result.Index(i).Interface()
if op, ok := item.(*OperationInfo); ok {
operations = append(operations, op)
}
}
return operations
}
// 如果无法解析,返回空数组
return []*OperationInfo{}
}
// Execute 执行插件功能
func (p *PluginAdapter) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
// 首先尝试调用 Execute 方法
method := p.pluginValue.MethodByName("Execute")
if method.IsValid() {
args := []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(action),
reflect.ValueOf(params),
}
result := method.Call(args)
var retValue interface{}
var retError error
if len(result) > 0 && !result[0].IsNil() {
retValue = result[0].Interface()
}
if len(result) > 1 && !result[1].IsNil() {
retError = result[1].Interface().(error)
}
return retValue, retError
}
return nil, nil
}
// SubscribeEvent 订阅插件事件
func (p *PluginAdapter) SubscribeEvent(eventType PluginEventType, handler PluginEventHandler) {
method := p.pluginValue.MethodByName("SubscribeEvent")
if !method.IsValid() {
return
}
args := []reflect.Value{
reflect.ValueOf(eventType),
reflect.ValueOf(handler),
}
method.Call(args)
}
// UnsubscribeEvent 取消订阅插件事件
func (p *PluginAdapter) UnsubscribeEvent(eventType PluginEventType, handler PluginEventHandler) {
method := p.pluginValue.MethodByName("UnsubscribeEvent")
if !method.IsValid() {
return
}
args := []reflect.Value{
reflect.ValueOf(eventType),
reflect.ValueOf(handler),
}
method.Call(args)
}
// EmitEvent 发送插件事件
func (p *PluginAdapter) EmitEvent(event PluginEvent) error {
method := p.pluginValue.MethodByName("EmitEvent")
if !method.IsValid() {
return nil
}
args := []reflect.Value{
reflect.ValueOf(event),
}
result := method.Call(args)
if len(result) > 0 && !result[0].IsNil() {
return result[0].Interface().(error)
}
return nil
}
// Reload 重新加载插件
func (p *PluginAdapter) Reload(ctx context.Context, config map[string]interface{}) error {
method := p.pluginValue.MethodByName("Reload")
if !method.IsValid() {
// 默认实现:先停止,然后重新初始化和启动
if err := p.Stop(ctx); err != nil {
return fmt.Errorf("停止插件失败: %v", err)
}
if err := p.Init(ctx, config); err != nil {
return fmt.Errorf("重新初始化插件失败: %v", err)
}
if p.IsEnabled() {
if err := p.Start(ctx); err != nil {
return fmt.Errorf("重新启动插件失败: %v", err)
}
}
return nil
}
args := []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(config),
}
result := method.Call(args)
if len(result) > 0 && !result[0].IsNil() {
return result[0].Interface().(error)
}
return nil
}
// Cleanup 清理插件资源
func (p *PluginAdapter) Cleanup(ctx context.Context) error {
method := p.pluginValue.MethodByName("Cleanup")
if !method.IsValid() {
// 默认实现:停止插件
if p.Status() == PluginStatusRunning {
return p.Stop(ctx)
}
return nil
}
args := []reflect.Value{
reflect.ValueOf(ctx),
}
result := method.Call(args)
if len(result) > 0 && !result[0].IsNil() {
return result[0].Interface().(error)
}
return nil
}