增强插件系统:引入插件辅助器和自动方法发现功能

- 在插件系统中添加 PluginHelper 结构体,简化插件方法的自动发现和注册。
- 更新 BasePluginImpl 以支持通过辅助器执行插件方法,增强 Execute 方法的灵活性。
- 统计插件和示例程序中实现新的方法调用方式,展示如何使用自动注册的方法。
- 通过结构体参数传递,简化插件调用过程,提升用户体验。

此更新提升了插件系统的可扩展性和易用性,便于开发者动态管理和执行插件功能。
This commit is contained in:
2025-03-14 11:37:42 +08:00
parent 9f78cb483b
commit b6bf2c5699
6 changed files with 969 additions and 193 deletions

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/darkit/goproxy/examples/plugin"
)
@@ -51,8 +50,10 @@ func DynamicParamsExample() {
}
fmt.Println()
// 示例1: 调用日志插件
fmt.Println("=== 示例1: 调用日志插件 ===")
// ======= 旧方式直接使用Execute方法 =======
fmt.Println("=== 示例1: 直接使用Execute方法 ===")
// 调用日志插件
logResult, err := pm.ExecutePlugin(ctx, "LoggerPlugin", "info", map[string]interface{}{
"message": "这是通过动态参数传递的日志消息",
})
@@ -62,8 +63,60 @@ func DynamicParamsExample() {
statusResult, err := pm.ExecutePlugin(ctx, "LoggerPlugin", "getLoggerStatus", nil)
fmt.Printf("日志插件状态: %v, 错误: %v\n", statusResult, err)
// 示例2: 调用存储插件
fmt.Println("\n=== 示例2: 调用存储插件 ===")
// ======= 新方式:使用自动发现的方法 =======
fmt.Println("\n=== 示例2: 使用自动注册的方法 ===")
// 获取StatsPlugin
_, ok := pm.GetPlugin("StatsPlugin")
if !ok {
fmt.Println("未找到StatsPlugin")
return
}
// 获取StatsPlugin支持的所有操作
operationsResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "getAvailableOperations", nil)
if err != nil {
fmt.Printf("获取操作失败: %v\n", err)
} else {
fmt.Println("StatsPlugin支持的操作:")
operations, ok := operationsResult.([]string)
if ok {
for i, op := range operations {
fmt.Printf(" %d. %s\n", i+1, op)
}
}
}
// 使用结构体参数
fmt.Println("\n使用结构体参数记录请求:")
recordResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "recordrequest", map[string]interface{}{
"bytesReceived": 2048,
"bytesSent": 4096,
"isError": false,
})
fmt.Printf("记录请求结果: %v, 错误: %v\n", recordResult, err)
// 获取统计数据
fmt.Println("\n获取统计数据:")
statsResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "getallstats", nil)
fmt.Printf("统计数据: %v, 错误: %v\n", statsResult, err)
// 增加自定义统计项
fmt.Println("\n增加自定义统计项:")
incrResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "incrementstat", map[string]interface{}{
"name": "custom_counter",
"value": 42,
})
fmt.Printf("增加统计项结果: %v, 错误: %v\n", incrResult, err)
// 获取统计报告
fmt.Println("\n获取统计报告:")
reportResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "generatestatsreport", nil)
fmt.Printf("统计报告: %v, 错误: %v\n", reportResult, err)
// 动态调用StoragePlugin方法
fmt.Println("\n=== 示例3: 动态调用StoragePlugin方法 ===")
// 保存文件
saveResult, err := pm.ExecutePlugin(ctx, "StoragePlugin", "saveFile", map[string]interface{}{
"filename": "test.txt",
@@ -71,7 +124,7 @@ func DynamicParamsExample() {
})
fmt.Printf("保存文件结果: %v, 错误: %v\n", saveResult, err)
// 列出文件
// 列出所有文件
listResult, err := pm.ExecutePlugin(ctx, "StoragePlugin", "listFiles", nil)
fmt.Printf("文件列表: %v, 错误: %v\n", listResult, err)
@@ -81,47 +134,19 @@ func DynamicParamsExample() {
})
fmt.Printf("读取文件内容: %v, 错误: %v\n", loadResult, err)
// 获取存储信息
infoResult, err := pm.ExecutePlugin(ctx, "StoragePlugin", "getStorageInfo", nil)
fmt.Printf("存储插件信息: %v, 错误: %v\n", infoResult, err)
// 示例3: 调用统计插件
fmt.Println("\n=== 示例3: 调用统计插件 ===")
// 记录请求
pm.ExecutePlugin(ctx, "StatsPlugin", "recordRequest", map[string]interface{}{
"bytesReceived": 1024.0,
"bytesSent": 2048.0,
"isError": false,
// 展示操作名不区分大小写
fmt.Println("\n=== 示例4: 操作名不区分大小写 ===")
caseSensitiveResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "IncrementStat", map[string]interface{}{
"name": "case_test",
"value": 100,
})
fmt.Printf("使用大写操作名结果: %v, 错误: %v\n", caseSensitiveResult, err)
// 睡眠一段时间以便观察
time.Sleep(1 * time.Second)
// 再次记录请求
pm.ExecutePlugin(ctx, "StatsPlugin", "recordRequest", map[string]interface{}{
"bytesReceived": 512.0,
"bytesSent": 768.0,
"isError": true,
// 获取后验证
checkResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "getstat", map[string]interface{}{
"name": "case_test",
})
// 获取统计报告
reportResult, err := pm.ExecutePlugin(ctx, "StatsPlugin", "getStatsReport", nil)
fmt.Printf("统计报告: %v, 错误: %v\n", reportResult, err)
// 示例4: 使用ExecutePluginsByType调用所有工具类插件
fmt.Println("\n=== 示例4: 按类型调用插件 ===")
typeResults := pm.ExecutePluginsByType(ctx, plugin.PluginTypeUtils, "info", map[string]interface{}{
"message": "这条消息将发送给所有工具类插件",
})
fmt.Printf("工具类插件调用结果: %v\n", typeResults)
// 示例5: 使用ExecuteAllPlugins调用所有插件
fmt.Println("\n=== 示例5: 调用所有插件 ===")
allResults := pm.ExecuteAllPlugins(ctx, "getLoggerStatus", nil)
fmt.Println("所有插件调用结果:")
for name, result := range allResults {
fmt.Printf(" %s: %v\n", name, result)
}
fmt.Printf("验证结果: %v, 错误: %v\n", checkResult, err)
// 停止所有插件
if err := pm.StopPlugins(ctx); err != nil {