From 9ab527b9be01de1b9a294869bfcdb0c0c0989bee Mon Sep 17 00:00:00 2001 From: unwox Date: Mon, 9 Dec 2024 14:33:25 +0600 Subject: add -D flag for development --- luajit.go | 3 +++ main.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++---------------- worker.go | 15 ++++++++++++-- 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/luajit.go b/luajit.go index 7439023..373beb1 100644 --- a/luajit.go +++ b/luajit.go @@ -217,6 +217,9 @@ func (l *Lua) PushAny(v any) error { case float64: v, _ := v.(float64) l.PushFloatNumber(v) + case bool: + v, _ := v.(bool) + l.PushBoolean(v) case map[string]any: v, _ := v.(map[string]any) err := l.PushObject(v) diff --git a/main.go b/main.go index 3a031e2..e3f29a2 100644 --- a/main.go +++ b/main.go @@ -20,10 +20,14 @@ import ( _ "github.com/mattn/go-sqlite3" ) +var debug bool + func main() { lAddr := flag.String("l", "127.0.0.1:3000", "Address HTTP-server will listen to") wrksNum := flag.Int("n", runtime.NumCPU(), "Number of HTTP-workers to start") + dbg := flag.Bool("D", false, "Debug mode") flag.Parse() + debug = *dbg if flag.NArg() == 0 { printUsage() @@ -31,7 +35,20 @@ func main() { luaArgv := flag.Args() mustExist(luaArgv[0]) + dbMux := sync.Mutex{} httpClient := &http.Client{} + dbPool := []*sql.DB{} + dbCur := 0 + dbGet := func() *sql.DB { + dbMux.Lock() + defer dbMux.Unlock() + dbCur = (dbCur + 1) % 300 + return dbPool[dbCur] + } + for i := 0; i < 300; i++ { + db, _ := sql.Open("sqlite3", "file:var/db.sqlite?_journal=WAL&_sync=NORMAL") + dbPool = append(dbPool, db) + } // queue for http messages for workers to handle msgs := make(chan *HTTPRequest, 4096) @@ -243,7 +260,7 @@ func main() { if err != nil { return luaErr(l, err) } - db := handle.Value().(*sql.DB) + db := dbGet() _, err = db.Exec(query, params...) if err != nil { return luaErr(l, err) @@ -259,7 +276,7 @@ func main() { return luaErr(l, err) } ares := []any{} - db := handle.Value().(*sql.DB) + db := dbGet() rows, err := db.Query(query, params...) if err != nil { return luaErr(l, err) @@ -295,7 +312,7 @@ func main() { if err != nil { return luaErr(l, err) } - db := handle.Value().(*sql.DB) + db := dbGet() rows, err := db.Query(query, params...) if err != nil { return luaErr(l, err) @@ -382,6 +399,21 @@ func main() { module["http"] = httpModule module["db"] = dbModule module["utf8"] = utf8Module + module["repl"] = func (l *Lua) int { + var repl LuaRef + err := l.Scan(&repl) + if err != nil { + return luaErr(l, err) + } + for _, wrk := range wrks { + if wrk.HasSameLua(l) { + wrk.repl = &repl + break + } + } + return luaOk(l, nil) + } + module["debug"] = debug wg := sync.WaitGroup{} wg.Add(*wrksNum) @@ -403,22 +435,24 @@ func main() { } wg.Wait() - // listen for evals from stdio - go func () { - reader := bufio.NewReader(os.Stdin) - for { - code, _ := reader.ReadString('\n') - if len(code) == 0 { - continue - } - for _, wrk := range wrks { - if err := wrk.Eval(code); err != nil { - log.Printf("error: %s\n", err) - break + // listen for commands from stdio + if debug { + go func () { + reader := bufio.NewReader(os.Stdin) + for { + code, _ := reader.ReadString('\n') + if len(code) == 0 { + continue + } + for _, wrk := range wrks { + if err := wrk.Eval(code); err != nil { + log.Printf("error: %s\n", err) + break + } } } - } - }() + }() + } if len(routes) > 0 { log.Printf("luna is running at %s...", *lAddr) diff --git a/worker.go b/worker.go index 5ae69c2..e7d76e4 100644 --- a/worker.go +++ b/worker.go @@ -40,6 +40,7 @@ type Worker struct { routes map[string]LuaRef started bool mu sync.Mutex + repl *LuaRef } // NewWorker creates a new instance of Worker type. @@ -167,10 +168,16 @@ func (w *Worker) Listen(queue chan *HTTPRequest) { err = l.PCall(1, 3, -3) if err != nil { + var body string + if debug { + body = err.Error() + } else { + body = "server error" + } r.result <- &HTTPResponse{ Code: 500, Headers: make(map[string]string), - Body: "server error", + Body: body, } log.Println("could not process request:\n" + err.Error()) return @@ -234,7 +241,11 @@ outer: func (w *Worker) Eval(code string) error { w.mu.Lock() defer w.mu.Unlock() - defer w.lua.RestoreStackFunc()() + if w.repl != nil { + w.lua.PushFromRef(*w.repl) + w.lua.PushString(code) + return w.lua.PCall(1, 0, 0) + } return w.lua.LoadString(code) } -- cgit v1.2.3