Skip to content

Commit

Permalink
dev: first step for local lua apps
Browse files Browse the repository at this point in the history
  • Loading branch information
wwhai committed Mar 6, 2023
1 parent cf0bfea commit 958acad
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 61 deletions.
34 changes: 26 additions & 8 deletions appstack/appstack_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ func NewApplication(uuid, Name, Version, Filepath string) *Application {
*
*/
type AppStack struct {
RuleEngine typex.RuleX
Applications map[string]*Application
}

func NewAppStack() *AppStack {
func NewAppStack(rulex typex.RuleX) *AppStack {
as := new(AppStack)
as.Applications = map[string]*Application{}
as.RuleEngine = rulex
return as
}

Expand Down Expand Up @@ -107,17 +109,30 @@ func (as *AppStack) LoadApp(app *Application) error {
if AppMain.Type() != lua.LTFunction {
return fmt.Errorf("'Main' must be function(arg)")
}

// 加载到内存里
fMain := *AppMain.(*lua.LFunction)
// 释放语法验证阶段的临时虚拟机
tempVm.Close()
tempVm = nil
//----------------------------------------------------------------------------------------------
app.vm.DoString(string(bytes))
// 检查函数入口
AppMainVM := app.vm.GetGlobal("Main")
if AppMainVM == nil {
return fmt.Errorf("'Main' field not exists")
}
if AppMainVM.Type() != lua.LTFunction {
return fmt.Errorf("'Main' must be function(arg)")
}
// 抽取main
fMain := *AppMainVM.(*lua.LFunction)
app.luaMainFunc = &fMain
// 加载库
app.loadAppLib(as.RuleEngine)
if err := as.startApp(app); err != nil {
return err
}
// 加载到内存里
as.Applications[app.UUID] = app
//
tempVm.Close()
tempVm = nil

return nil
}

Expand All @@ -132,12 +147,15 @@ func (as *AppStack) startApp(app *Application) error {
app.ctx = ctx
app.cancel = cancel
go func(ctx context.Context) {
defer func() {
glogger.GLogger.Debug("app exit:", app.UUID)
}()
app.vm.SetContext(ctx)
err := app.vm.CallByParam(lua.P{
Fn: app.luaMainFunc, // 回调函数
NRet: 1, // 一个返回值
Protect: true, // 受保护
})
}, lua.LBool(false))
if err != nil {
glogger.GLogger.Error("startApp error:", err)
return
Expand Down
108 changes: 108 additions & 0 deletions appstack/lua_libloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package appstack

import (
"github.com/i4de/rulex/rulexlib"
"github.com/i4de/rulex/typex"
lua "github.com/yuin/gopher-lua"
)

/*
*
* AddLib: 根据 KV形式加载库(推荐)
* - Global: 命名空间
* - funcName: 函数名称
*/
func (app *Application) addLib(rx typex.RuleX, Global string, funcName string,
f func(l *lua.LState) int) {
rulexTb := app.vm.G.Global
app.vm.SetGlobal(Global, rulexTb)
mod := app.vm.SetFuncs(rulexTb, map[string]lua.LGFunction{
funcName: f,
})
app.vm.Push(mod)
}

/*
*
* 加载app库函数
*
*/
func (app *Application) loadAppLib(e typex.RuleX) {
// 消息转发
app.addLib(e, "rulexlib", "DataToHttp", rulexlib.DataToHttp(e))
app.addLib(e, "rulexlib", "DataToMqtt", rulexlib.DataToMqtt(e))
// JQ
app.addLib(e, "rulexlib", "JqSelect", rulexlib.JqSelect(e))
app.addLib(e, "rulexlib", "JQ", rulexlib.JqSelect(e))
// 日志
app.addLib(e, "rulexlib", "log", rulexlib.Log(e))
// 二进制操作
app.addLib(e, "rulexlib", "MB", rulexlib.MatchBinary(e))
app.addLib(e, "rulexlib", "B2BS", rulexlib.ByteToBitString(e))
app.addLib(e, "rulexlib", "Bit", rulexlib.GetABitOnByte(e))
app.addLib(e, "rulexlib", "B2I64", rulexlib.ByteToInt64(e))
app.addLib(e, "rulexlib", "B64S2B", rulexlib.B64S2B(e))
app.addLib(e, "rulexlib", "BS2B", rulexlib.BitStringToBytes(e))
app.addLib(e, "rulexlib", "HToN", rulexlib.HToN(e))
app.addLib(e, "rulexlib", "HsubToN", rulexlib.HsubToN(e))
// 浮点数处理
app.addLib(e, "rulexlib", "Bin2F32", rulexlib.BinToFloat32(e))
app.addLib(e, "rulexlib", "Bin2F64", rulexlib.BinToFloat64(e))
// URL处理
app.addLib(e, "rulexlib", "UrlBuild", rulexlib.UrlBuild(e))
app.addLib(e, "rulexlib", "UrlBuildQS", rulexlib.UrlBuildQS(e))
app.addLib(e, "rulexlib", "UrlParse", rulexlib.UrlParse(e))
app.addLib(e, "rulexlib", "UrlResolve", rulexlib.UrlResolve(e))
// 数据持久化
app.addLib(e, "rulexlib", "DataToTdEngine", rulexlib.DataToTdEngine(e))
app.addLib(e, "rulexlib", "DataToMongo", rulexlib.DataToMongo(e))
// 时间库
app.addLib(e, "rulexlib", "Time", rulexlib.Time(e))
app.addLib(e, "rulexlib", "TsUnix", rulexlib.TsUnix(e))
app.addLib(e, "rulexlib", "TsUnixNano", rulexlib.TsUnixNano(e))
app.addLib(e, "rulexlib", "NtpTime", rulexlib.NtpTime(e))
// 缓存器库
app.addLib(e, "rulexlib", "VSet", rulexlib.StoreSet(e))
app.addLib(e, "rulexlib", "VGet", rulexlib.StoreGet(e))
app.addLib(e, "rulexlib", "VDel", rulexlib.StoreDelete(e))
// JSON
app.addLib(e, "rulexlib", "T2J", rulexlib.JSONE(e)) // Lua Table -> JSON
app.addLib(e, "rulexlib", "J2T", rulexlib.JSOND(e)) // JSON -> Lua Table
// Get Rule ID
app.addLib(e, "rulexlib", "RUUID", rulexlib.SelfRuleUUID(e, app.UUID))
// Codec
app.addLib(e, "rulexlib", "RPCENC", rulexlib.RPCEncode(e))
app.addLib(e, "rulexlib", "RPCDEC", rulexlib.RPCDecode(e))
// Device R/W
app.addLib(e, "rulexlib", "ReadDevice", rulexlib.ReadDevice(e))
app.addLib(e, "rulexlib", "WriteDevice", rulexlib.WriteDevice(e))
// Source R/W
app.addLib(e, "rulexlib", "ReadSource", rulexlib.ReadSource(e))
app.addLib(e, "rulexlib", "WriteSource", rulexlib.WriteSource(e))
// String
app.addLib(e, "rulexlib", "T2Str", rulexlib.T2Str(e))
app.addLib(e, "rulexlib", "Throw", rulexlib.Throw(e))
//------------------------------------------------------------------------
// IotHUB 库, 主要是为了适配iothub的回复消息, 注意:这个规范是w3c的
// https://www.w3.org/TR/wot-thing-description
//------------------------------------------------------------------------
app.addLib(e, "iothub", "PropertySuccess", rulexlib.PropertyReplySuccess(e))
app.addLib(e, "iothub", "PropertyFailed", rulexlib.PropertyReplyFailed(e))
app.addLib(e, "iothub", "ActionSuccess", rulexlib.ActionReplySuccess(e))
app.addLib(e, "iothub", "ActionFailed", rulexlib.ActionReplyFailed(e))
//------------------------------------------------------------------------
// 设备操作
//------------------------------------------------------------------------
app.addLib(e, "device", "DCACall", rulexlib.DCACall(e))
//------------------------------------------------------------------------
// 十六进制编码处理
//------------------------------------------------------------------------
app.addLib(e, "hex", "Bytes2Hexs", rulexlib.Bytes2Hexs(e))
app.addLib(e, "hex", "Hexs2Bytes", rulexlib.Hexs2Bytes(e))
//------------------------------------------------------------------------
// 注册GPIO操作函数到LUA运行时
//------------------------------------------------------------------------
app.addLib(e, "eekit", "GPIOGet", rulexlib.EEKIT_GPIOGet(e))
app.addLib(e, "eekit", "GPIOSet", rulexlib.EEKIT_GPIOSet(e))

}
78 changes: 39 additions & 39 deletions engine/lua_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,59 @@ import (
*/
func LoadBuildInLuaLib(e typex.RuleX, r *typex.Rule) {
// 消息转发
r.AddLib(e, "rulexlib", "DataToHttp", rulexlib.DataToHttp(e))
r.AddLib(e, "rulexlib", "DataToMqtt", rulexlib.DataToMqtt(e))
r.AddLib(e, "applib", "DataToHttp", rulexlib.DataToHttp(e))
r.AddLib(e, "applib", "DataToMqtt", rulexlib.DataToMqtt(e))
// JQ
r.AddLib(e, "rulexlib", "JqSelect", rulexlib.JqSelect(e))
r.AddLib(e, "rulexlib", "JQ", rulexlib.JqSelect(e))
r.AddLib(e, "applib", "JqSelect", rulexlib.JqSelect(e))
r.AddLib(e, "applib", "JQ", rulexlib.JqSelect(e))
// 日志
r.AddLib(e, "rulexlib", "log", rulexlib.Log(e))
r.AddLib(e, "applib", "log", rulexlib.Log(e))
// 二进制操作
r.AddLib(e, "rulexlib", "MB", rulexlib.MatchBinary(e))
r.AddLib(e, "rulexlib", "B2BS", rulexlib.ByteToBitString(e))
r.AddLib(e, "rulexlib", "Bit", rulexlib.GetABitOnByte(e))
r.AddLib(e, "rulexlib", "B2I64", rulexlib.ByteToInt64(e))
r.AddLib(e, "rulexlib", "B64S2B", rulexlib.B64S2B(e))
r.AddLib(e, "rulexlib", "BS2B", rulexlib.BitStringToBytes(e))
r.AddLib(e, "rulexlib", "HToN", rulexlib.HToN(e))
r.AddLib(e, "rulexlib", "HsubToN", rulexlib.HsubToN(e))
r.AddLib(e, "applib", "MB", rulexlib.MatchBinary(e))
r.AddLib(e, "applib", "B2BS", rulexlib.ByteToBitString(e))
r.AddLib(e, "applib", "Bit", rulexlib.GetABitOnByte(e))
r.AddLib(e, "applib", "B2I64", rulexlib.ByteToInt64(e))
r.AddLib(e, "applib", "B64S2B", rulexlib.B64S2B(e))
r.AddLib(e, "applib", "BS2B", rulexlib.BitStringToBytes(e))
r.AddLib(e, "applib", "HToN", rulexlib.HToN(e))
r.AddLib(e, "applib", "HsubToN", rulexlib.HsubToN(e))
// 浮点数处理
r.AddLib(e, "rulexlib", "Bin2F32", rulexlib.BinToFloat32(e))
r.AddLib(e, "rulexlib", "Bin2F64", rulexlib.BinToFloat64(e))
r.AddLib(e, "applib", "Bin2F32", rulexlib.BinToFloat32(e))
r.AddLib(e, "applib", "Bin2F64", rulexlib.BinToFloat64(e))
// URL处理
r.AddLib(e, "rulexlib", "UrlBuild", rulexlib.UrlBuild(e))
r.AddLib(e, "rulexlib", "UrlBuildQS", rulexlib.UrlBuildQS(e))
r.AddLib(e, "rulexlib", "UrlParse", rulexlib.UrlParse(e))
r.AddLib(e, "rulexlib", "UrlResolve", rulexlib.UrlResolve(e))
r.AddLib(e, "applib", "UrlBuild", rulexlib.UrlBuild(e))
r.AddLib(e, "applib", "UrlBuildQS", rulexlib.UrlBuildQS(e))
r.AddLib(e, "applib", "UrlParse", rulexlib.UrlParse(e))
r.AddLib(e, "applib", "UrlResolve", rulexlib.UrlResolve(e))
// 数据持久化
r.AddLib(e, "rulexlib", "DataToTdEngine", rulexlib.DataToTdEngine(e))
r.AddLib(e, "rulexlib", "DataToMongo", rulexlib.DataToMongo(e))
r.AddLib(e, "applib", "DataToTdEngine", rulexlib.DataToTdEngine(e))
r.AddLib(e, "applib", "DataToMongo", rulexlib.DataToMongo(e))
// 时间库
r.AddLib(e, "rulexlib", "Time", rulexlib.Time(e))
r.AddLib(e, "rulexlib", "TsUnix", rulexlib.TsUnix(e))
r.AddLib(e, "rulexlib", "TsUnixNano", rulexlib.TsUnixNano(e))
r.AddLib(e, "rulexlib", "NtpTime", rulexlib.NtpTime(e))
r.AddLib(e, "applib", "Time", rulexlib.Time(e))
r.AddLib(e, "applib", "TsUnix", rulexlib.TsUnix(e))
r.AddLib(e, "applib", "TsUnixNano", rulexlib.TsUnixNano(e))
r.AddLib(e, "applib", "NtpTime", rulexlib.NtpTime(e))
// 缓存器库
r.AddLib(e, "rulexlib", "VSet", rulexlib.StoreSet(e))
r.AddLib(e, "rulexlib", "VGet", rulexlib.StoreGet(e))
r.AddLib(e, "rulexlib", "VDel", rulexlib.StoreDelete(e))
r.AddLib(e, "applib", "VSet", rulexlib.StoreSet(e))
r.AddLib(e, "applib", "VGet", rulexlib.StoreGet(e))
r.AddLib(e, "applib", "VDel", rulexlib.StoreDelete(e))
// JSON
r.AddLib(e, "rulexlib", "T2J", rulexlib.JSONE(e)) // Lua Table -> JSON
r.AddLib(e, "rulexlib", "J2T", rulexlib.JSOND(e)) // JSON -> Lua Table
r.AddLib(e, "applib", "T2J", rulexlib.JSONE(e)) // Lua Table -> JSON
r.AddLib(e, "applib", "J2T", rulexlib.JSOND(e)) // JSON -> Lua Table
// Get Rule ID
r.AddLib(e, "rulexlib", "RUUID", rulexlib.SelfRuleUUID(e, r.UUID))
r.AddLib(e, "applib", "RUUID", rulexlib.SelfRuleUUID(e, r.UUID))
// Codec
r.AddLib(e, "rulexlib", "RPCENC", rulexlib.RPCEncode(e))
r.AddLib(e, "rulexlib", "RPCDEC", rulexlib.RPCDecode(e))
r.AddLib(e, "applib", "RPCENC", rulexlib.RPCEncode(e))
r.AddLib(e, "applib", "RPCDEC", rulexlib.RPCDecode(e))
// Device R/W
r.AddLib(e, "rulexlib", "ReadDevice", rulexlib.ReadDevice(e))
r.AddLib(e, "rulexlib", "WriteDevice", rulexlib.WriteDevice(e))
r.AddLib(e, "applib", "ReadDevice", rulexlib.ReadDevice(e))
r.AddLib(e, "applib", "WriteDevice", rulexlib.WriteDevice(e))
// Source R/W
r.AddLib(e, "rulexlib", "ReadSource", rulexlib.ReadSource(e))
r.AddLib(e, "rulexlib", "WriteSource", rulexlib.WriteSource(e))
r.AddLib(e, "applib", "ReadSource", rulexlib.ReadSource(e))
r.AddLib(e, "applib", "WriteSource", rulexlib.WriteSource(e))
// String
r.AddLib(e, "rulexlib", "T2Str", rulexlib.T2Str(e))
r.AddLib(e, "rulexlib", "Throw", rulexlib.Throw(e))
r.AddLib(e, "applib", "T2Str", rulexlib.T2Str(e))
r.AddLib(e, "applib", "Throw", rulexlib.Throw(e))
//------------------------------------------------------------------------
// IotHUB 库, 主要是为了适配iothub的回复消息, 注意:这个规范是w3c的
// https://www.w3.org/TR/wot-thing-description
Expand Down
31 changes: 31 additions & 0 deletions plugin/http_server/appstack_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package httpserver

import (
"github.com/gin-gonic/gin"
"github.com/i4de/rulex/typex"
)

// 列表
func Apps(c *gin.Context, hs *HttpApiServer, e typex.RuleX) {
c.JSON(200, OkWithData("ok"))
}

// 新建
func CreateApp(c *gin.Context, hs *HttpApiServer, e typex.RuleX) {
c.JSON(200, OkWithData("ok"))
}

// 更新
func UpdateApp(c *gin.Context, hs *HttpApiServer, e typex.RuleX) {
c.JSON(200, OkWithData("ok"))
}

// 停止
func StopApp(c *gin.Context, hs *HttpApiServer, e typex.RuleX) {
c.JSON(200, OkWithData("ok"))
}

// 删除
func RemoveApp(c *gin.Context, hs *HttpApiServer, e typex.RuleX) {
c.JSON(200, OkWithData("ok"))
}
7 changes: 5 additions & 2 deletions test/apps/helloworld_1.0.0.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
AppNAME = "test_demo"
AppVERSION = "1.0.0"
AppDESCRIPTION = "A demo app"

function Main(arg)
while true do
print("Message From Main:", AppNAME, AppVERSION, AppDESCRIPTION)
print(arg)
for key, value in pairs(_G) do
print("_G:", key, value)
end
print("Message From Main:", AppNAME, AppVERSION, AppDESCRIPTION, rulexlib:Time())
return 0
end
13 changes: 4 additions & 9 deletions test/appstack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,15 @@ import (

// go test -timeout 30s -run ^Test_appStack github.com/i4de/rulex/test -v -count=1
func Test_appStack(t *testing.T) {
as := appstack.NewAppStack()

engine := RunTestEngine()
engine.Start()
as := appstack.NewAppStack(engine)
err := as.LoadApp(appstack.NewApplication("test-uuid-1", "test-name",
"1.0.1", "helloworld_1.0.0.lua"))
if err != nil {
t.Fatal(err)
}
t.Log(as)
go func() {
for i := 0; i < 1000; i++ {

t.Log("Test_appStack ======>")
}
}()
time.Sleep(30 * time.Second)

engine.Stop()
}
4 changes: 2 additions & 2 deletions typex/version.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// Warning:
// This file is generated by go compiler, don't change it!!!
// Generated Time: "2023-03-06 15:41:01"
// Generated Time: "2023-03-06 19:45:55"
// Build on: 5.18.17-amd64-desktop-community-hwe
//
package typex
Expand All @@ -13,6 +13,6 @@ type Version struct {

var DefaultVersion = Version{
Version: `v0.4.3`,
ReleaseTime: "2023-03-06 15:41:01",
ReleaseTime: "2023-03-06 19:45:55",
}

2 changes: 1 addition & 1 deletion utils/banner.b
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
|
|* Welcome to RULEX framework world <'_'>
|* Version: v0.4.3-d5df539dbd1a97d
|* Build at: 2023-03-06 15:41:01
|* Build at: 2023-03-06 19:45:55
|* Document: https://rulex.pages.dev
|

0 comments on commit 958acad

Please sign in to comment.