package plugin import ( "context" "errors" "fmt" "io/fs" "os" "path/filepath" "plugin" "sync" ) // Plugin 插件接口 type Plugin interface { // Name 插件名称 Name() string // Version 插件版本 Version() string // Init 初始化插件 Init(ctx context.Context) error // Start 启动插件 Start(ctx context.Context) error // Stop 停止插件 Stop(ctx context.Context) error } // PluginManager 插件管理器 type PluginManager struct { pluginsDir string plugins map[string]Plugin mu sync.RWMutex } // NewPluginManager 创建插件管理器 func NewPluginManager(pluginsDir string) *PluginManager { return &PluginManager{ pluginsDir: pluginsDir, plugins: make(map[string]Plugin), } } // LoadPlugins 加载插件 func (pm *PluginManager) LoadPlugins() error { // 确保插件目录存在 if err := os.MkdirAll(pm.pluginsDir, 0755); err != nil { return fmt.Errorf("创建插件目录失败: %v", err) } // 遍历插件目录 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 } // loadPlugin 加载单个插件 func (pm *PluginManager) loadPlugin(path string) error { // 打开插件文件 p, err := plugin.Open(path) if err != nil { return fmt.Errorf("打开插件失败: %v", err) } // 查找Plugin变量 symPlugin, err := p.Lookup("Plugin") if err != nil { return fmt.Errorf("查找Plugin变量失败: %v", err) } // 类型断言 plugin, ok := symPlugin.(Plugin) if !ok { return errors.New("插件类型错误") } // 检查插件名称是否已存在 pm.mu.Lock() if _, exists := pm.plugins[plugin.Name()]; exists { pm.mu.Unlock() return fmt.Errorf("插件 %s 已存在", plugin.Name()) } pm.plugins[plugin.Name()] = plugin pm.mu.Unlock() return nil } // GetPlugin 获取插件 func (pm *PluginManager) GetPlugin(name string) (Plugin, bool) { pm.mu.RLock() defer pm.mu.RUnlock() plugin, exists := pm.plugins[name] return plugin, exists } // GetAllPlugins 获取所有插件 func (pm *PluginManager) GetAllPlugins() []Plugin { pm.mu.RLock() defer pm.mu.RUnlock() plugins := make([]Plugin, 0, len(pm.plugins)) for _, plugin := range pm.plugins { plugins = append(plugins, plugin) } return plugins } // InitPlugins 初始化所有插件 func (pm *PluginManager) InitPlugins(ctx context.Context) error { pm.mu.RLock() defer pm.mu.RUnlock() for name, plugin := range pm.plugins { if err := plugin.Init(ctx); 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 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 err := plugin.Stop(ctx); err != nil { return fmt.Errorf("停止插件 %s 失败: %v", name, err) } } return nil }