优化插件注册逻辑

This commit is contained in:
www.xueximeng.com
2025-11-19 19:54:28 +08:00
parent 3f36d54e9b
commit b01da5847e
5 changed files with 92 additions and 66 deletions

View File

@@ -78,12 +78,15 @@ func SetupRouter(searchService *service.SearchService) *gin.Engine {
}
// 注册插件的Web路由如果插件实现了PluginWithWebHandler接口
allPlugins := plugin.GetRegisteredPlugins()
for _, p := range allPlugins {
// 只有当插件功能启用且插件在启用列表中时才注册路由
if config.AppConfig.AsyncPluginEnabled && searchService != nil && searchService.GetPluginManager() != nil {
enabledPlugins := searchService.GetPluginManager().GetPlugins()
for _, p := range enabledPlugins {
if webPlugin, ok := p.(plugin.PluginWithWebHandler); ok {
webPlugin.RegisterWebRoutes(r.Group(""))
}
}
}
return r
}

View File

@@ -52,20 +52,6 @@ var DefaultAccounts = []struct {
var StorageDir string
// 初始化存储目录
func init() {
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
StorageDir = filepath.Join(cachePath, "gying_users")
if err := os.MkdirAll(StorageDir, 0755); err != nil {
fmt.Printf("⚠️ 警告: 无法创建Gying存储目录 %s: %v\n", StorageDir, err)
} else {
fmt.Printf("✓ Gying存储目录: %s\n", StorageDir)
}
}
// HTML模板
const HTMLTemplate = `<!DOCTYPE html>
@@ -386,6 +372,7 @@ type GyingPlugin struct {
scrapers sync.Map // cloudscraper实例缓存hash -> *cloudscraper.Scraper
mu sync.RWMutex
searchCache sync.Map // 插件级缓存:关键词->model.PluginSearchResult
initialized bool // 初始化状态标记
}
// User 用户数据结构
@@ -439,10 +426,25 @@ func init() {
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("gying", 3),
}
plugin.RegisterGlobalPlugin(p)
}
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
func (p *GyingPlugin) Initialize() error {
if p.initialized {
return nil
}
// 初始化存储目录路径
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
StorageDir = filepath.Join(cachePath, "gying_users")
// 初始化存储目录
if err := os.MkdirAll(StorageDir, 0755); err != nil {
fmt.Printf("[Gying] 创建存储目录失败: %v\n", err)
return
return fmt.Errorf("创建存储目录失败: %v", err)
}
// 加载所有用户到内存
@@ -461,7 +463,8 @@ func init() {
// 启动session保活任务防止session超时
go p.startSessionKeepAlive()
plugin.RegisterGlobalPlugin(p)
p.initialized = true
return nil
}
// ============ 插件接口实现 ============

View File

@@ -52,6 +52,16 @@ type PluginWithWebHandler interface {
RegisterWebRoutes(router *gin.RouterGroup)
}
// InitializablePlugin 支持延迟初始化的插件接口
// 插件可以实现此接口,将初始化逻辑延迟到真正被使用时执行
type InitializablePlugin interface {
AsyncSearchPlugin // 继承搜索插件接口
// Initialize 执行插件初始化(创建目录、加载数据等)
// 只会被调用一次,应该是幂等的
Initialize() error
}
// ============================================================
// 第二部分:全局变量和注册表
// ============================================================
@@ -167,6 +177,14 @@ func NewPluginManager() *PluginManager {
// RegisterPlugin 注册异步插件
func (pm *PluginManager) RegisterPlugin(plugin AsyncSearchPlugin) {
// 如果插件支持延迟初始化,先执行初始化
if initPlugin, ok := plugin.(InitializablePlugin); ok {
if err := initPlugin.Initialize(); err != nil {
fmt.Printf("[PluginManager] 插件 %s 初始化失败: %v跳过注册\n", plugin.Name(), err)
return
}
}
pm.plugins = append(pm.plugins, plugin)
}

View File

@@ -39,24 +39,6 @@ const (
var StorageDir string
// 初始化存储目录
func init() {
// 直接从环境变量读取缓存路径不依赖config.AppConfig避免初始化顺序问题
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
// 如果环境变量未设置,使用默认值
cachePath = "./cache"
}
// 构建QQPD用户数据目录路径
StorageDir = filepath.Join(cachePath, "qqpd_users")
// 确保目录存在
if err := os.MkdirAll(StorageDir, 0755); err != nil {
fmt.Printf("⚠️ 警告: 无法创建QQPD存储目录 %s: %v\n", StorageDir, err)
} else {
fmt.Printf("✓ QQPD存储目录: %s\n", StorageDir)
}
}
// HTML模板完整的管理页面
const HTMLTemplate = `<!DOCTYPE html>
@@ -496,6 +478,7 @@ type QQPDPlugin struct {
*plugin.BaseAsyncPlugin
users sync.Map // 内存缓存hash -> *User
mu sync.RWMutex
initialized bool // 初始化状态标记
}
// User 用户数据结构
@@ -530,10 +513,25 @@ func init() {
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("qqpd", 3),
}
plugin.RegisterGlobalPlugin(p)
}
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
func (p *QQPDPlugin) Initialize() error {
if p.initialized {
return nil
}
// 初始化存储目录路径
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
StorageDir = filepath.Join(cachePath, "qqpd_users")
// 初始化存储目录
if err := os.MkdirAll(StorageDir, 0755); err != nil {
fmt.Printf("[QQPD] 创建存储目录失败: %v\n", err)
return
return fmt.Errorf("创建存储目录失败: %v", err)
}
// 加载所有用户到内存
@@ -542,7 +540,8 @@ func init() {
// 启动定期清理任务
go p.startCleanupTask()
plugin.RegisterGlobalPlugin(p)
p.initialized = true
return nil
}
// ============ 插件接口实现 ============

View File

@@ -34,20 +34,6 @@ const (
var StorageDir string
func init() {
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
StorageDir = filepath.Join(cachePath, "weibo_users")
if err := os.MkdirAll(StorageDir, 0755); err != nil {
fmt.Printf("⚠️ 警告: 无法创建Weibo存储目录 %s: %v\n", StorageDir, err)
} else {
fmt.Printf("✓ Weibo存储目录: %s\n", StorageDir)
}
}
const HTMLTemplate = `<!DOCTYPE html>
<html lang="zh-CN">
@@ -424,6 +410,7 @@ type WeiboPlugin struct {
*plugin.BaseAsyncPlugin
users sync.Map
mu sync.RWMutex
initialized bool
}
type User struct {
@@ -452,15 +439,31 @@ func init() {
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("weibo", 3),
}
plugin.RegisterGlobalPlugin(p)
}
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
func (p *WeiboPlugin) Initialize() error {
if p.initialized {
return nil
}
// 初始化存储目录路径
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
StorageDir = filepath.Join(cachePath, "weibo_users")
if err := os.MkdirAll(StorageDir, 0755); err != nil {
fmt.Printf("[Weibo] 创建存储目录失败: %v\n", err)
return
return fmt.Errorf("创建存储目录失败: %v", err)
}
p.loadAllUsers()
go p.startCleanupTask()
plugin.RegisterGlobalPlugin(p)
p.initialized = true
return nil
}
func (p *WeiboPlugin) RegisterWebRoutes(router *gin.RouterGroup) {