Skip to content

Commit

Permalink
Merge pull request flipped-aurora#631 from songzhibin97/gva_gormv2_dev
Browse files Browse the repository at this point in the history
feat:插件模式尝鲜
奇淼(piexlmax authored Aug 20, 2021
2 parents 493e399 + 32327fe commit 6e6b488
Showing 3 changed files with 126 additions and 0 deletions.
16 changes: 16 additions & 0 deletions server/router/example/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package example

import "github.com/gin-gonic/gin"

type Plugin struct {
}

func (*Plugin) Register(group *gin.RouterGroup) {
group.GET("hello", func(context *gin.Context) {
context.JSON(200, "hello world")
})
}

func (*Plugin) RouterPath() string {
return "group"
}
41 changes: 41 additions & 0 deletions server/utils/plugin/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package plugin

import (
"plugin"
"sync"

"github.com/gin-gonic/gin"
)

const (
OnlyFuncName = "Plugin"
)

var ManagementPlugin = managementPlugin{mp: make(map[string]*plugin.Plugin)}

type managementPlugin struct {
mp map[string]*plugin.Plugin
sync.Mutex
}

func (m *managementPlugin) SetPlugin(key string, p *plugin.Plugin) {
m.Lock()
defer m.Unlock()
m.mp[key] = p
}

func (m *managementPlugin) GetPlugin(key string) (p *plugin.Plugin, ok bool) {
m.Lock()
defer m.Unlock()
p, ok = m.mp[key]
return
}

// Plugin 插件模式接口化
type Plugin interface {
// Register 注册路由
Register(group *gin.RouterGroup)

// RouterPath 用户返回注册路由
RouterPath() string
}
69 changes: 69 additions & 0 deletions server/utils/plugin/plugin_uinx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//+build !windows

package plugin

import (
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"plugin"
)

// LoadPlugin 加载插件 传入path
func LoadPlugin(path string) error {
path, err := filepath.Abs(path)
if err != nil {
return err
}
fileInfo, err := os.Stat(path)
if err != nil {
return err
}
if fileInfo.IsDir() {
fileSlice, err := ioutil.ReadDir(path)
if err != nil {
return err
}
for _, ff := range fileSlice {
if !ff.IsDir() && filepath.Ext(ff.Name()) == ".so" {
if err = loadPlugin(path, ff); err != nil {
return err
}
} else if ff.IsDir() {
_ = LoadPlugin(filepath.Join(path, ff.Name()))
}
}
return nil
} else {
return loadPlugin(path, fileInfo)
}
}

func loadPlugin(path string, f fs.FileInfo) error {
if filepath.Ext(f.Name()) == ".so" {
fPath := filepath.Join(path, f.Name())
// 加载插件
p, err := plugin.Open(fPath)
if err != nil {
fmt.Println("loadPlugin err ", err)
return err
}
// 判断是否满足协议
// 要满足 OnlyFuncName && 实现 Plugin 接口
if v, err := p.Lookup(OnlyFuncName); err != nil {
fmt.Println("loadPlugin err ", err)
return err
} else if _, ok := v.(Plugin); !ok {
fmt.Println("loadPlugin err ", fmt.Sprintf("path:%s 没有实现 %s 接口", filepath.Base(fPath), OnlyFuncName))
return errors.New("没有实现指定接口")
} else {

}
fmt.Println("loadPlugin add ", filepath.Base(fPath))
ManagementPlugin.SetPlugin(filepath.Base(fPath), p)
}
return nil
}

0 comments on commit 6e6b488

Please sign in to comment.