natsbot

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

commit 9b90910f15c4d7048f3c8a8312709dc52cc6d124
parent a419697a0406b7a20668e3876e8e90bbc3514739
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Mon,  8 Sep 2025 17:30:25 +0000

Event callbacks are stored in the connection object
Diffstat:
Mnatsbot.go | 64+++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 43 insertions(+), 21 deletions(-)

diff --git a/natsbot.go b/natsbot.go @@ -207,31 +207,34 @@ type natsConfig struct { type natsConfigMap map[natsConfig]*nats.Conn -func connConfig(L *lua.LState) (*natsConfig, error) { +type natsCbMap map[string]*lua.LFunction + +func connConfig(L *lua.LState) (*natsConfig, natsCbMap, error) { arg := L.Get(1) if url, ok := arg.(lua.LString); ok { - if cfg, err := toConfig(L, L.Get(2)); err != nil { - return nil, err + if cfg, cbmap, err := toConfig(L, L.Get(2)); err != nil { + return nil, nil, err } else if cfg.url == "" { cfg.url = string(url) - return cfg, nil + return cfg, cbmap, nil } else if cfg.url != string(url) { - return nil, fmt.Errorf("incompatible URLs %q and %q", cfg.url, string(url)) + return nil, nil, fmt.Errorf("incompatible URLs %q and %q", cfg.url, string(url)) } else { - return cfg, nil + return cfg, cbmap, nil } } else { return toConfig(L, arg) } } -func toConfig(L *lua.LState, lv lua.LValue) (*natsConfig, error) { +func toConfig(L *lua.LState, lv lua.LValue) (*natsConfig, natsCbMap, error) { tbl, ok := lv.(*lua.LTable) if !ok { - return nil, errors.New("configuration is not a table") + return nil, nil, errors.New("configuration is not a table") } var result natsConfig + cbmap := make(natsCbMap) var errStr []string L.ForEach(tbl, func(key, value lua.LValue) { @@ -242,6 +245,21 @@ func toConfig(L *lua.LState, lv lua.LValue) (*natsConfig, error) { } switch skey { + case "closed": + fallthrough + case "disconnected": + fallthrough + case "error": + fallthrough + case "reconnect_error": + fallthrough + case "reconnected": + if s, ok := value.(*lua.LFunction); ok { + cbmap[string(skey)] = s + } else { + errStr = append(errStr, fmt.Sprintf("bad value for key %q: %q", skey, lua.LVAsString(value))) + } + case "url": if s, ok := value.(lua.LString); ok { result.url = string(s) @@ -290,9 +308,9 @@ func toConfig(L *lua.LState, lv lua.LValue) (*natsConfig, error) { }) if len(errStr) > 0 { - return nil, errors.New(strings.Join(errStr, ", ")) + return nil, nil, errors.New(strings.Join(errStr, ", ")) } else { - return &result, nil + return &result, cbmap, nil } } @@ -327,18 +345,11 @@ const keyIndex = 1 type connMap map[*nats.Conn]int func registerConnType(L *lua.LState) { - index := L.NewTable() - L.SetField(index, "publish", L.NewFunction(natsPublish)) - L.SetField(index, "subscribe", L.NewFunction(natsSubscribe)) - - mt := L.NewTypeMetatable(luaNatsConnTypeName) - L.SetField(mt, "__index", index) - L.SetGlobal(luaNatsConnTypeName, L.NewFunction(natsConnect)) } func natsConnect(L *lua.LState) int { - pcfg, err := connConfig(L) + pcfg, cbmap, err := connConfig(L) if err != nil { log.Println(err) L.Push(lua.LNil) @@ -371,13 +382,24 @@ func natsConnect(L *lua.LState) int { } cfgMap[cfg] = nc - L.Push(wrapConn(L, nc)) + L.Push(wrapConn(L, nc, cbmap)) return 1 } -func wrapConn(L *lua.LState, nc *nats.Conn) lua.LValue { +func wrapConn(L *lua.LState, nc *nats.Conn, cbmap natsCbMap) lua.LValue { luaConn := newUserData(L, nc) - L.SetMetatable(luaConn, L.GetTypeMetatable(luaNatsConnTypeName)) + + index := L.NewTable() + L.SetField(index, "publish", L.NewFunction(natsPublish)) + L.SetField(index, "subscribe", L.NewFunction(natsSubscribe)) + + for key, fn := range cbmap { + L.SetField(index, key, fn) + } + + mt := L.NewTable() + L.SetField(mt, "__index", index) + L.SetMetatable(luaConn, mt) tbl, idx := stateConnTable(L) id := tbl.Len() + 1