natsbot

NATS bot
git clone https://git.instinctive.eu/natsbot.git
Log | Files | Refs | README | LICENSE

commit ec67fbb5c22c154250c9bd07d60cd86a56964405
parent 182cd131215db7a00726ae98715f1988b94e558a
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Mon, 25 Aug 2025 18:19:53 +0000

Application core is further simplified
Diffstat:
Mnatsbot.go | 166++++++++-----------------------------------------------------------------------
1 file changed, 15 insertions(+), 151 deletions(-)

diff --git a/natsbot.go b/natsbot.go @@ -18,7 +18,6 @@ package natsbot import ( "log" - "strings" "time" "github.com/nats-io/nats.go" @@ -30,22 +29,8 @@ type NatsBot interface { Teardown(L *lua.LState) } -type NatsReloadingBot interface { - Setup(L *lua.LState) - ReloadBegin(oldL, newL *lua.LState) - ReloadAbort(oldL, newL *lua.LState) - ReloadEnd(oldL, newL *lua.LState) - Teardown(L *lua.LState) -} - -type internalMsg struct { - timestamp float64 - connId int - msg nats.Msg -} - func Loop(cb NatsBot, mainScript string, capacity int) { - msgChan := make(chan internalMsg, capacity) + msgChan := make(chan *nats.Msg, capacity) L := lua.NewState() defer L.Close() @@ -55,8 +40,7 @@ func Loop(cb NatsBot, mainScript string, capacity int) { registerConnType(L) registerTimerType(L) - registerState(L, cb, msgChan) - defer cleanupConns(L) + registerState(L, msgChan) if err := L.DoFile(mainScript); err != nil { panic(err) @@ -76,19 +60,13 @@ func Loop(cb NatsBot, mainScript string, capacity int) { break } - processMsg(L, &msg) + processMsg(L, msg) case <-timer.C: } runTimers(L, timer) - if stateReloadRequested(L) { - L = reload(L, mainScript) - runTimers(L, timer) - stateRequestReload(L, lua.LNil) - } - if tableIsEmpty(stateConnTable(L)) && tableIsEmpty(stateTimerTable(L)) { break } @@ -97,105 +75,28 @@ func Loop(cb NatsBot, mainScript string, capacity int) { log.Println("natsbot finished") } -func processMsg(L *lua.LState, msg *internalMsg) { +func processMsg(L *lua.LState, msg *nats.Msg) { // TODO } -func reload(oldL *lua.LState, mainScript string) *lua.LState { - log.Println("Reloading", mainScript) - cb := stateCB(oldL) - reloader, isReloader := cb.(NatsReloadingBot) - - newL := lua.NewState() - - if isReloader { - reloader.ReloadBegin(oldL, newL) - } else { - cb.Setup(newL) - } - - registerConnType(newL) - registerTimerType(newL) - - stateReloadBegin(oldL, newL) - - if err := newL.DoFile(mainScript); err != nil { - log.Println("Reload failed:", err) - stateReloadAbort(oldL, newL) - if isReloader { - reloader.ReloadAbort(oldL, newL) - } else { - cb.Teardown(newL) - } - newL.Close() - return oldL - } else { - stateReloadEnd(oldL, newL) - if isReloader { - reloader.ReloadEnd(oldL, newL) - } else { - cb.Teardown(oldL) - } - oldL.Close() - log.Println("Reload successful") - return newL - } -} - /********** State Object in the Lua Interpreter **********/ const luaStateName = "_natsbot" -const keyMsgChan = 1 -const keyCB = 2 -const keyConnNextId = 3 -const keyCfgMap = 4 -const keyConnTable = 5 -const keyTimerTable = 6 -const keyReloadRequest = 7 -const keyOldCfgMap = 8 - -func registerState(L *lua.LState, cb NatsBot, msgChan chan<- internalMsg) { +const ( + _ = iota + keyMsgChan + keyCfgMap + keyConnTable + keyTimerTable +) + +func registerState(L *lua.LState, msgChan chan<- *nats.Msg) { st := L.NewTable() L.RawSetInt(st, keyMsgChan, newUserData(L, msgChan)) - L.RawSetInt(st, keyCB, newUserData(L, cb)) - L.RawSetInt(st, keyConnNextId, lua.LNumber(1)) L.RawSetInt(st, keyCfgMap, newUserData(L, make(natsConfigMap))) L.RawSetInt(st, keyConnTable, L.NewTable()) L.RawSetInt(st, keyTimerTable, L.NewTable()) stateSet(L, st) - L.SetGlobal("reload", L.NewFunction(requestReload)) -} - -func stateReloadBegin(oldL, newL *lua.LState) { - oldSt := stateGet(oldL) - msgChan := oldL.RawGetInt(oldSt, keyMsgChan).(*lua.LUserData).Value.(chan<- internalMsg) - cb := oldL.RawGetInt(oldSt, keyCB).(*lua.LUserData).Value.(NatsBot) - nextId := oldL.RawGetInt(oldSt, keyConnNextId) - cfgMap := oldL.RawGetInt(oldSt, keyCfgMap).(*lua.LUserData).Value.(natsConfigMap) - - st := newL.NewTable() - newL.RawSetInt(st, keyMsgChan, newUserData(newL, msgChan)) - newL.RawSetInt(st, keyCB, newUserData(newL, cb)) - newL.RawSetInt(st, keyConnNextId, nextId) - newL.RawSetInt(st, keyCfgMap, newUserData(newL, make(natsConfigMap))) - newL.RawSetInt(st, keyConnTable, newL.NewTable()) - newL.RawSetInt(st, keyTimerTable, newL.NewTable()) - newL.RawSetInt(st, keyOldCfgMap, newUserData(newL, cfgMap)) - stateSet(newL, st) - newL.SetGlobal("reload", newL.NewFunction(requestReload)) -} - -func stateReloadAbort(oldL, newL *lua.LState) { - statePartialCleanup(newL, oldL) -} - -func stateReloadEnd(oldL, newL *lua.LState) { - statePartialCleanup(oldL, newL) - newL.RawSetInt(stateGet(newL), keyOldCfgMap, lua.LNil) -} - -func statePartialCleanup(staleL, keptL *lua.LState) { - // TODO } func stateUncheckedGet(L *lua.LState) *lua.LTable { @@ -226,14 +127,9 @@ func stateValue(L *lua.LState, key int) lua.LValue { return L.RawGetInt(stateGet(L), key) } -func stateMsgChan(L *lua.LState) chan<- internalMsg { +func stateMsgChan(L *lua.LState) chan<- *nats.Msg { ud := stateValue(L, keyMsgChan) - return ud.(*lua.LUserData).Value.(chan<- internalMsg) -} - -func stateCB(L *lua.LState) NatsBot { - ud := stateValue(L, keyCB) - return ud.(*lua.LUserData).Value.(NatsBot) + return ud.(*lua.LUserData).Value.(chan<- *nats.Msg) } func stateCfgMap(L *lua.LState) natsConfigMap { @@ -248,28 +144,6 @@ func stateTimerTable(L *lua.LState) *lua.LTable { return stateValue(L, keyTimerTable).(*lua.LTable) } -func stateReloadRequested(L *lua.LState) bool { - return lua.LVAsBool(stateValue(L, keyReloadRequest)) -} - -func stateRequestReload(L *lua.LState, v lua.LValue) { - L.RawSetInt(stateGet(L), keyReloadRequest, v) -} - -func stateOldCfgMap(L *lua.LState) natsConfigMap { - val := stateValue(L, keyOldCfgMap) - if val == lua.LNil { - return nil - } else { - return val.(*lua.LUserData).Value.(natsConfigMap) - } -} - -func requestReload(L *lua.LState) int { - stateRequestReload(L, lua.LTrue) - return 0 -} - /********** NATS Connection Configuration **********/ type natsConfig struct { @@ -380,16 +254,6 @@ func runTimers(L *lua.LState, parentTimer *time.Timer) { /********** Tools **********/ -const internalRoot = "$SYS.SELF." - -func isInternal(subject string) bool { - return strings.HasPrefix(subject, internalRoot) -} - -func internalSubject(domain string) string { - return internalRoot + domain -} - func newUserData(L *lua.LState, v interface{}) *lua.LUserData { res := L.NewUserData() res.Value = v