summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--luajit.go3
-rw-r--r--main.go68
-rw-r--r--worker.go15
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)
}