From 507f1f50905b06e86a6d55cbf22a439ac3a71510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 13 Nov 2024 18:26:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E7=A1=80=E7=9A=84=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=B3=A8=E5=86=8C+=E8=8E=B7=E5=8F=96+=E8=B0=83=E5=BA=A6?= =?UTF-8?q?=E8=83=BD=E5=8A=9B,=20=E5=BE=85=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/context.go | 18 ++++ define/plugin.go | 3 + plugins/{ => abstract}/abstract.go | 8 +- plugins/register.go | 135 +++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 3 deletions(-) rename plugins/{ => abstract}/abstract.go (78%) create mode 100644 plugins/register.go diff --git a/define/context.go b/define/context.go index 078b72a..3d17a37 100644 --- a/define/context.go +++ b/define/context.go @@ -47,6 +47,24 @@ func (rc *RequestContext) SetPluginResult(r *PluginResult) { rc.pluginResultTable[r.ID] = append(rc.pluginResultTable[r.ID], r) } +// TraceID 获取traceID +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:22 2024/11/13 +func (rc *RequestContext) TraceID() string { + return rc.traceID +} + +// Trace 追踪实例 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:24 2024/11/13 +func (rc *RequestContext) Trace() *trace.Runtime { + return rc.runtimeInstance +} + func (rc *RequestContext) Lock() { rc.lock.Lock() } diff --git a/define/plugin.go b/define/plugin.go index c340a0d..eb2bc3b 100644 --- a/define/plugin.go +++ b/define/plugin.go @@ -7,6 +7,8 @@ // Date : 2024-11-13 17:26 package define +import "git.zhangdeman.cn/zhangdeman/trace" + // PluginResult 插件执行结果 // // Author : go_developer@163.com<白茶清欢> @@ -14,6 +16,7 @@ package define // Date : 17:28 2024/11/13 type PluginResult struct { ID string `json:"id"` // 插件ID + Trace *trace.Runtime `json:"-"` // 执行跟踪 StartTime int64 `json:"start_time"` // 开始执行时间: ms FinishTime int64 `json:"finish_time"` // 完成执行时间: ms IsSuccess bool `json:"is_success"` // 是否成功 diff --git a/plugins/abstract.go b/plugins/abstract/abstract.go similarity index 78% rename from plugins/abstract.go rename to plugins/abstract/abstract.go index 19a7e19..606b9ab 100644 --- a/plugins/abstract.go +++ b/plugins/abstract/abstract.go @@ -1,11 +1,11 @@ -// Package plugins ... +// Package abstract ... // // Description : plugins ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2024-11-13 16:21 -package plugins +package abstract import ( "git.zhangdeman.cn/gateway/core/define" @@ -23,8 +23,10 @@ type IPlugin interface { Description() string // Config 读取插件的配置 Config() (map[string]any, error) + // Allow 插件是否允许执行 + Allow() bool // SkipFailure 插件执行失败, 是否跳过 SkipFailure() bool // Logic 插件执行的逻辑 - Logic(rc *define.RequestContext) *define.PluginResult + Logic(rc *define.RequestContext, cfg map[string]any) *define.PluginResult } diff --git a/plugins/register.go b/plugins/register.go new file mode 100644 index 0000000..240e826 --- /dev/null +++ b/plugins/register.go @@ -0,0 +1,135 @@ +// Package plugins ... +// +// Description : plugins ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-11-13 17:57 +package plugins + +import ( + "errors" + "git.zhangdeman.cn/gateway/core/define" + "git.zhangdeman.cn/gateway/core/plugins/abstract" + "git.zhangdeman.cn/zhangdeman/trace" + "sync" + "time" +) + +var ( + lock = &sync.RWMutex{} +) + +// pluginTable 全局插件注册表 +var pluginTable = map[string]abstract.IPlugin{} + +// Register 注册插件 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:58 2024/11/13 +func Register(plugin abstract.IPlugin) error { + if nil == plugin { + return errors.New("plugin instance is nil") + } + lock.Lock() + defer lock.Unlock() + if len(plugin.ID()) == 0 { + return errors.New("plugin id empty") + } + if _, exist := pluginTable[plugin.ID()]; exist { + return errors.New(plugin.ID() + " : plugin instance already exist") + } + pluginTable[plugin.ID()] = plugin + return nil +} + +// Get 获取插件实例 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:02 2024/11/13 +func Get(pluginID string) (abstract.IPlugin, error) { + lock.RLock() + lock.RUnlock() + if _, exist := pluginTable[pluginID]; !exist { + return nil, errors.New(pluginID + " : plugin instance not found") + } + return pluginTable[pluginID], nil +} + +// NewPluginResult 获取plugin的执行结果实例 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:19 2024/11/13 +func NewPluginResult(rc *define.RequestContext) *define.PluginResult { + return &define.PluginResult{ + Trace: trace.NewRuntime(rc.TraceID(), 1), + StartTime: time.Now().UnixMilli(), + FinishTime: 0, + IsSuccess: false, + SkipFailure: false, + Data: make(map[string]any), + ErrMsg: "", + Config: make(map[string]any), + } +} + +// Dispatch 调度执行插件 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:07 2024/11/13 +func Dispatch(rc *define.RequestContext, pluginIDList []string) (map[string]abstract.IPlugin, error) { + l := &sync.RWMutex{} + errList := []string{} + for _, itemPluginID := range pluginIDList { + go func(pluginID string) { + defer func() { + if r := recover(); r != nil { + l.Lock() + errList = append(errList, r.(error).Error()) + l.Unlock() + } + }() + pluginInstance, err := Get(pluginID) + if nil != err { + l.Lock() + errList = append(errList, err.Error()) + l.Unlock() + return + } + pluginCfg, err := pluginInstance.Config() + if nil != err { + l.Lock() + errList = append(errList, err.Error()) + l.Unlock() + return + } + pluginResult := pluginInstance.Logic(rc, pluginCfg) + if nil == pluginResult { + l.Lock() + errList = append(errList, "plugin result is nil") + l.Unlock() + return + } + }(itemPluginID) + } + return nil, nil +} + +// InitDefault 初始化注册默认的插件 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:04 2024/11/13 +func InitDefault() error { + defaultPluginList := []abstract.IPlugin{} + for _, itemPlugin := range defaultPluginList { + if err := Register(itemPlugin); err != nil { + return err + } + } + return nil +}