implement eh-steve/goloader

This commit is contained in:
Aliberk Sandıkçı 2023-09-01 00:42:38 +03:00
parent 6ac65abfa3
commit 3e2a03204b
Signed by: asandikci
GPG Key ID: 25C67A03B5666BC1
5 changed files with 59 additions and 88 deletions

View File

@ -1,74 +1,51 @@
package main
import (
"encoding/json"
"log"
"fmt"
"git.aliberksandikci.com.tr/asandikci/go-loader-test/pkg/utils"
"github.com/eh-steve/goloader/jit"
)
// General Functions/Methods that each plugin has
type PlugGeneral interface {
Info() map[string]interface{}
}
// plugins/tmptest
type TmpTest interface {
TmpTest()
}
// FILLME creating new plugin interface, template
// type NewPluginInterface interface {
// PluginMethod() returnType
// }
// Loads Plugins and runs them concurrently.
// When you create a new plugin create a new interface and call this plugin in this function
func PluginManager(params ...string) {
chanPlug := make(chan interface{})
conf := jit.BuildConfig{
KeepTempFiles: false, // Files are copied/written to a temp dir to ensure it is writable. This retains the temporary copies
ExtraBuildFlags: []string{"-x"}, // Flags passed to go build command
BuildEnv: []string{"GOOS=windows"}, // Env vars to set for go build toolchain
TmpDir: "/tmp/inner", // To control where temporary files are copied
DebugLog: true, //
}
if len(params) > 0 && params[0] == "tmptest" {
go LoadPlugin("tmptest", chanPlug)
res, ok := <-chanPlug
var tmptest TmpTest = res.(TmpTest)
checkPlugin(res, ok)
tmptest.TmpTest()
loadable, err := jit.BuildGoPackage(conf, "plugins/tmptest/")
if err != nil {
panic(err)
}
module, err := loadable.Load()
// module.SymbolsByPkg is a map[string]map[string]interface{} of all packages and their exported functions and global vars
symbols := module.SymbolsByPkg[loadable.ImportPath]
if err != nil {
panic(err)
}
// defer func() {
// err = module.Unload()
// if err != nil {
// panic(err)
// }
// }()
switch f := symbols["MyFunc"].(type) {
case func([]byte) (interface{}, error):
result, err := f([]byte(`{"k":"v"}`))
if err != nil {
panic(err)
}
fmt.Println(result)
default:
fmt.Println(f)
panic("Function signature was not what was expected")
}
err = module.Unload()
if err != nil {
panic(err)
}
}
// Logs plugin outputs.
func logPlugin(title string, mp map[string]interface{}, toJson bool) {
log.Printf("\n----- %v -----\n", title)
if toJson {
data, err := json.MarshalIndent(&mp, "", " ")
utils.Check(err)
log.Println(string(data))
} else {
for i, v := range mp {
log.Printf("%v: %v\n", i, v)
}
}
}
// Checks plugin status
func checkPlugin(plugVal interface{}, status bool) {
if status {
if plugVal == nil {
log.Fatal("Plugin loaded but there is no value!")
} else {
plugInfo := plugVal.(PlugGeneral).Info()
log.Printf("Plugin \"%v\" loaded and ready to use, version \"%v\" ", plugInfo["name"], plugInfo["version"])
}
} else {
if plugVal == nil {
log.Fatal("Plugin closed and there is no value! ")
} else {
log.Fatal("Plugin closed or there is an error")
}
}
}
// // TODO response to Lider
// // func createResponse() {
// // }

7
go.mod
View File

@ -2,4 +2,9 @@ module git.aliberksandikci.com.tr/asandikci/go-loader-test
go 1.21.0
require golang.org/x/text v0.12.0
require (
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550
golang.org/x/text v0.12.0
)
require github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 // indirect

4
go.sum
View File

@ -1,2 +1,6 @@
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 h1:0mZ2Y8x4dhPfm9eOlbzBx31YSLaECdPvKEBrL5Hc0YE=
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2/go.mod h1:k7xs3CUwCvOU9aw851I6AEb6ZzZJ3nos5dZ6A/2ewM0=
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550 h1:clY7T47fFZdFcILcu7uksS7FStRaKMssCYGW0l/AoMo=
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550/go.mod h1:p18VKcPYO8oWGYcQt/K5EGIGqak0ZT5HwVirGpUGZBg=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=

View File

@ -1,6 +1,6 @@
package main
package mypackage
func (p plug) Info() map[string]interface{} {
func Info() map[string]interface{} {
return map[string]interface{}{
"name": "tmptest",
"version": "1.0.2",

View File

@ -1,24 +1,9 @@
package main
package mypackage
import (
"fmt"
"time"
)
import "encoding/json"
type plug string
// exported plugin Symbol
var TmptestConnect plug
func (p plug) TmpTest() {
fmt.Println()
fmt.Println("----- Entered Test Area -----")
fmt.Println()
fmt.Println()
fmt.Println()
fmt.Println()
fmt.Println("----- End of Test Area -----")
fmt.Println()
time.Sleep(3 * time.Second)
func MyFunc(input []byte) (interface{}, error) {
var output interface{}
err := json.Unmarshal(input, &output)
return output, err
}