mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-03 20:12:25 +00:00
Compare commits
9 Commits
5cdfb2a543
...
83912b6c28
| Author | SHA1 | Date | |
|---|---|---|---|
| 83912b6c28 | |||
| 6ed5a7f9e0 | |||
| 2f78e9367c | |||
| ac074ce0ff | |||
| 8bdf9197d6 | |||
| 4db8fa2360 | |||
| 2a48927a08 | |||
| 58027bb988 | |||
| 30a87fdb4c |
18
com/List.lua
18
com/List.lua
@@ -10,7 +10,7 @@ if In.Params and In.Params.about then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isValidCommand(name)
|
local function isValidName(name)
|
||||||
return name:match("^[%w]+$") ~= nil
|
return name:match("^[%w]+$") ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -21,8 +21,20 @@ local function scanDirectory(basePath, targetPath)
|
|||||||
|
|
||||||
if handle then
|
if handle then
|
||||||
for filePath in handle:lines() do
|
for filePath in handle:lines() do
|
||||||
local fileName = filePath:match("([^/]+)%.lua$")
|
local parts = {}
|
||||||
if fileName and isValidCommand(fileName) then
|
for part in filePath:gsub(".lua$", ""):gmatch("[^/]+") do
|
||||||
|
table.insert(parts, part)
|
||||||
|
end
|
||||||
|
|
||||||
|
local allValid = true
|
||||||
|
for _, part in ipairs(parts) do
|
||||||
|
if not isValidName(part) then
|
||||||
|
allValid = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if allValid then
|
||||||
local relPath = filePath:gsub("^"..basePath.."/", ""):gsub(".lua$", ""):gsub("/", ">")
|
local relPath = filePath:gsub("^"..basePath.."/", ""):gsub(".lua$", ""):gsub("/", ">")
|
||||||
table.insert(res, relPath)
|
table.insert(res, relPath)
|
||||||
end
|
end
|
||||||
|
|||||||
132
hooks/initial.go
132
hooks/initial.go
@@ -12,6 +12,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
@@ -133,7 +134,7 @@ func Init4Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
|||||||
|
|
||||||
// post-init stage
|
// post-init stage
|
||||||
func Init5Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
func Init5Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
||||||
nodeApp.Fallback(func(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
NodeApp.Fallback(func(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
||||||
x.Log.Println("Cleaning up...")
|
x.Log.Println("Cleaning up...")
|
||||||
|
|
||||||
if err := run_manager.Clean(); err != nil {
|
if err := run_manager.Clean(); err != nil {
|
||||||
@@ -184,21 +185,29 @@ func Init5Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init6Hook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
func Init6Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
||||||
if !slices.Contains(*x.Config.Conf.DisableWarnings, "--WNonStdTmpDir") && os.TempDir() != "/tmp" {
|
if !slices.Contains(*x.Config.Conf.DisableWarnings, "--WNonStdTmpDir") && os.TempDir() != "/tmp" {
|
||||||
x.Log.Printf("%s: %s", colors.PrintWarn(), "Non-standard value specified for temporary directory")
|
x.Log.Printf("%s: %s", colors.PrintWarn(), "Non-standard value specified for temporary directory")
|
||||||
}
|
}
|
||||||
if strings.Contains(*x.Config.Conf.Log.OutPath, `%tmp%`) {
|
|
||||||
replaced := strings.ReplaceAll(*x.Config.Conf.Log.OutPath, "%tmp%", filepath.Clean(run_manager.RuntimeDir()))
|
replacements := map[string]any{
|
||||||
x.Config.Conf.Log.OutPath = &replaced
|
"%tmp%": filepath.Clean(run_manager.RuntimeDir()),
|
||||||
|
"%path%": *x.Config.Env.NodePath,
|
||||||
|
"%stdout%": os.Stdout,
|
||||||
|
"%stderr%": os.Stderr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processConfig(&x.Config.Conf, replacements)
|
||||||
|
|
||||||
if !slices.Contains(logs.Levels.Available, *x.Config.Conf.Log.Level) {
|
if !slices.Contains(logs.Levels.Available, *x.Config.Conf.Log.Level) {
|
||||||
if !slices.Contains(*x.Config.Conf.DisableWarnings, "--WUndefLogLevel") {
|
if !slices.Contains(*x.Config.Conf.DisableWarnings, "--WUndefLogLevel") {
|
||||||
x.Log.Printf("%s: %s", colors.PrintWarn(), fmt.Sprintf("Unknown logging level %s, fallback level: %s", *x.Config.Conf.Log.Level, logs.Levels.Fallback))
|
x.Log.Printf("%s: %s", colors.PrintWarn(), fmt.Sprintf("Unknown logging level %s, fallback level: %s", *x.Config.Conf.Log.Level, logs.Levels.Fallback))
|
||||||
}
|
}
|
||||||
x.Config.Conf.Log.Level = &logs.Levels.Fallback
|
x.Config.Conf.Log.Level = &logs.Levels.Fallback
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init7Hook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
||||||
if *x.Config.Conf.Node.ShowConfig {
|
if *x.Config.Conf.Node.ShowConfig {
|
||||||
fmt.Printf("Configuration from %s:\n", x.Config.CMDLine.Run.ConfigPath)
|
fmt.Printf("Configuration from %s:\n", x.Config.CMDLine.Run.ConfigPath)
|
||||||
x.Config.Print(x.Config.Conf)
|
x.Config.Print(x.Config.Conf)
|
||||||
@@ -206,16 +215,16 @@ func Init6Hook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
|||||||
fmt.Printf("Environment:\n")
|
fmt.Printf("Environment:\n")
|
||||||
x.Config.Print(x.Config.Env)
|
x.Config.Print(x.Config.Env)
|
||||||
|
|
||||||
if !askConfirm("Is that ok?", true) {
|
if cs.UUID32 != "" && !askConfirm("Is that ok?", true) {
|
||||||
x.Log.Printf("Cancel launch")
|
x.Log.Printf("Cancel launch")
|
||||||
nodeApp.CallFallback(ctx)
|
NodeApp.CallFallback(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x.Log.Printf("Starting \"%s\" node", *x.Config.Conf.Node.Name)
|
x.Log.Printf("Starting \"%s\" node", *x.Config.Conf.Node.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init7Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
func Init8Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
||||||
cs.Stage = corestate.StageReady
|
cs.Stage = corestate.StageReady
|
||||||
x.Log.SetPrefix(colors.SetGreen(fmt.Sprintf("(%s) ", cs.Stage)))
|
x.Log.SetPrefix(colors.SetGreen(fmt.Sprintf("(%s) ", cs.Stage)))
|
||||||
|
|
||||||
@@ -228,6 +237,111 @@ func Init7Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) {
|
|||||||
*x.SLog = *newSlog
|
*x.SLog = *newSlog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func processConfig(conf any, replacements map[string]any) error {
|
||||||
|
val := reflect.ValueOf(conf)
|
||||||
|
if val.Kind() == reflect.Ptr {
|
||||||
|
val = val.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch val.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
for i := 0; i < val.NumField(); i++ {
|
||||||
|
field := val.Field(i)
|
||||||
|
if field.CanAddr() && field.CanSet() {
|
||||||
|
if err := processConfig(field.Addr().Interface(), replacements); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
for i := 0; i < val.Len(); i++ {
|
||||||
|
elem := val.Index(i)
|
||||||
|
if elem.CanAddr() && elem.CanSet() {
|
||||||
|
if err := processConfig(elem.Addr().Interface(), replacements); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
for _, key := range val.MapKeys() {
|
||||||
|
elem := val.MapIndex(key)
|
||||||
|
if elem.CanInterface() {
|
||||||
|
newVal := reflect.New(elem.Type()).Elem()
|
||||||
|
newVal.Set(elem)
|
||||||
|
|
||||||
|
if err := processConfig(newVal.Addr().Interface(), replacements); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
val.SetMapIndex(key, newVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.String:
|
||||||
|
str := val.String()
|
||||||
|
|
||||||
|
if replacement, exists := replacements[str]; exists {
|
||||||
|
if err := setValue(val, replacement); err != nil {
|
||||||
|
return fmt.Errorf("failed to set %q: %v", str, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for placeholder, replacement := range replacements {
|
||||||
|
if strings.Contains(str, placeholder) {
|
||||||
|
replacementStr, err := toString(replacement)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid replacement for %q: %v", placeholder, err)
|
||||||
|
}
|
||||||
|
newStr := strings.ReplaceAll(str, placeholder, replacementStr)
|
||||||
|
val.SetString(newStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Ptr:
|
||||||
|
if !val.IsNil() {
|
||||||
|
return processConfig(val.Interface(), replacements)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setValue(val reflect.Value, replacement any) error {
|
||||||
|
if !val.CanSet() {
|
||||||
|
return fmt.Errorf("value is not settable")
|
||||||
|
}
|
||||||
|
|
||||||
|
replacementVal := reflect.ValueOf(replacement)
|
||||||
|
if replacementVal.Type().AssignableTo(val.Type()) {
|
||||||
|
val.Set(replacementVal)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.Kind() == reflect.String {
|
||||||
|
str, err := toString(replacement)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot convert replacement to string: %v", err)
|
||||||
|
}
|
||||||
|
val.SetString(str)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("type mismatch: cannot assign %T to %v", replacement, val.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
func toString(v any) (string, error) {
|
||||||
|
switch s := v.(type) {
|
||||||
|
case string:
|
||||||
|
return s, nil
|
||||||
|
case fmt.Stringer:
|
||||||
|
return s.String(), nil
|
||||||
|
default:
|
||||||
|
return fmt.Sprint(v), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func askConfirm(prompt string, defaultYes bool) bool {
|
func askConfirm(prompt string, defaultYes bool) bool {
|
||||||
ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||||
|
|
||||||
@@ -249,7 +363,7 @@ func askConfirm(prompt string, defaultYes bool) bool {
|
|||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
nodeApp.CallFallback(ctx)
|
NodeApp.CallFallback(ctx)
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
case text := <-inputChan:
|
case text := <-inputChan:
|
||||||
text = strings.TrimSpace(strings.ToLower(text))
|
text = strings.TrimSpace(strings.ToLower(text))
|
||||||
|
|||||||
12
hooks/run.go
12
hooks/run.go
@@ -28,16 +28,16 @@ import (
|
|||||||
"golang.org/x/net/netutil"
|
"golang.org/x/net/netutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var nodeApp = app.New()
|
var NodeApp = app.New()
|
||||||
|
|
||||||
func Run(cmd *cobra.Command, args []string) {
|
func Run(cmd *cobra.Command, args []string) {
|
||||||
nodeApp.InitialHooks(
|
NodeApp.InitialHooks(
|
||||||
Init0Hook, Init1Hook, Init2Hook,
|
Init0Hook, Init1Hook, Init2Hook,
|
||||||
Init3Hook, Init4Hook, Init5Hook,
|
Init3Hook, Init4Hook, Init5Hook,
|
||||||
Init6Hook, Init7Hook,
|
Init6Hook, Init7Hook, Init8Hook,
|
||||||
)
|
)
|
||||||
|
|
||||||
nodeApp.Run(RunHook)
|
NodeApp.Run(RunHook)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error {
|
func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error {
|
||||||
@@ -96,7 +96,7 @@ func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error {
|
|||||||
}, "", 0),
|
}, "", 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeApp.Fallback(func(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
NodeApp.Fallback(func(ctx context.Context, cs *corestate.CoreState, x *app.AppX) {
|
||||||
if err := srv.Shutdown(ctxMain); err != nil {
|
if err := srv.Shutdown(ctxMain); err != nil {
|
||||||
x.Log.Printf("%s: Failed to stop the server gracefully: %s", colors.PrintError(), err.Error())
|
x.Log.Printf("%s: Failed to stop the server gracefully: %s", colors.PrintError(), err.Error())
|
||||||
} else {
|
} else {
|
||||||
@@ -171,6 +171,6 @@ func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
<-ctxMain.Done()
|
<-ctxMain.Done()
|
||||||
nodeApp.CallFallback(ctx)
|
NodeApp.CallFallback(ctx)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,6 @@ func (a *App) CallFallback(ctx context.Context) {
|
|||||||
if a.fallback != nil {
|
if a.fallback != nil {
|
||||||
a.fallback(ctx, a.Corestate, a.AppX)
|
a.fallback(ctx, a.Corestate, a.AppX)
|
||||||
}
|
}
|
||||||
os.Exit(3)
|
os.Exit(0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (c *Compositor) LoadConf(path string) error {
|
|||||||
v.SetDefault("updates.check_interval", "2h")
|
v.SetDefault("updates.check_interval", "2h")
|
||||||
v.SetDefault("updates.wanted_version", "latest-stable")
|
v.SetDefault("updates.wanted_version", "latest-stable")
|
||||||
v.SetDefault("log.level", "info")
|
v.SetDefault("log.level", "info")
|
||||||
v.SetDefault("log.out_path", "")
|
v.SetDefault("log.output", "%stdout%")
|
||||||
|
|
||||||
if err := v.ReadInConfig(); err != nil {
|
if err := v.ReadInConfig(); err != nil {
|
||||||
return fmt.Errorf("error reading config: %w", err)
|
return fmt.Errorf("error reading config: %w", err)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ type Updates struct {
|
|||||||
|
|
||||||
type Log struct {
|
type Log struct {
|
||||||
Level *string `mapstructure:"level"`
|
Level *string `mapstructure:"level"`
|
||||||
OutPath *string `mapstructure:"out_path"`
|
OutPath any `mapstructure:"output"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigEnv structure for environment variables
|
// ConfigEnv structure for environment variables
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package logs
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
@@ -57,9 +58,30 @@ func SetupLogger(o *config.Log) (*slog.Logger, error) {
|
|||||||
handlerOpts.Level = slog.LevelInfo
|
handlerOpts.Level = slog.LevelInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
if *o.OutPath != "" {
|
switch o.OutPath{
|
||||||
|
case 1:
|
||||||
|
writer = os.Stdout
|
||||||
|
case 2:
|
||||||
|
writer = os.Stderr
|
||||||
|
case os.Stdout:
|
||||||
|
writer = os.Stdout
|
||||||
|
case os.Stderr:
|
||||||
|
writer = os.Stderr
|
||||||
|
default:
|
||||||
|
var path string
|
||||||
|
switch v := o.OutPath.(type) {
|
||||||
|
case string:
|
||||||
|
path = v
|
||||||
|
case int, int64, float64:
|
||||||
|
path = fmt.Sprint(v)
|
||||||
|
case fmt.Stringer:
|
||||||
|
path = v.String()
|
||||||
|
default:
|
||||||
|
path = fmt.Sprint(v)
|
||||||
|
}
|
||||||
|
|
||||||
logFile := &lumberjack.Logger{
|
logFile := &lumberjack.Logger{
|
||||||
Filename: filepath.Join(*o.OutPath, "event.log"),
|
Filename: filepath.Join(path, "event.log"),
|
||||||
MaxSize: 10,
|
MaxSize: 10,
|
||||||
MaxBackups: 5,
|
MaxBackups: 5,
|
||||||
MaxAge: 28,
|
MaxAge: 28,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package gateway
|
package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
"github.com/akyaiy/GoSally-mvp/internal/core/corestate"
|
||||||
@@ -14,7 +15,7 @@ type serversApiVer string
|
|||||||
|
|
||||||
type ServerApiContract interface {
|
type ServerApiContract interface {
|
||||||
GetVersion() string
|
GetVersion() string
|
||||||
Handle(sid string, r *http.Request, req *rpc.RPCRequest) *rpc.RPCResponse
|
Handle(ctx context.Context, sid string, r *http.Request, req *rpc.RPCRequest) *rpc.RPCResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneralServer implements the GeneralServerApiContract and serves as a router for different API versions.
|
// GeneralServer implements the GeneralServerApiContract and serves as a router for different API versions.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package gateway
|
package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -13,6 +14,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
|
func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context() // TODO
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
sessionUUID := r.Header.Get("X-Session-UUID")
|
sessionUUID := r.Header.Get("X-Session-UUID")
|
||||||
if sessionUUID == "" {
|
if sessionUUID == "" {
|
||||||
@@ -64,7 +67,11 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
gs.x.SLog.Info("invalid request received", slog.String("issue", rpc.ErrParseErrorS))
|
gs.x.SLog.Info("invalid request received", slog.String("issue", rpc.ErrParseErrorS))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp := gs.Route(sessionUUID, r, &single)
|
resp := gs.Route(ctx, sessionUUID, r, &single)
|
||||||
|
if resp == nil {
|
||||||
|
w.Write([]byte(""))
|
||||||
|
return
|
||||||
|
}
|
||||||
rpc.WriteResponse(w, resp)
|
rpc.WriteResponse(w, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -76,7 +83,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(req rpc.RPCRequest) {
|
go func(req rpc.RPCRequest) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
res := gs.Route(sessionUUID, r, &req)
|
res := gs.Route(ctx, sessionUUID, r, &req)
|
||||||
if res != nil {
|
if res != nil {
|
||||||
responses <- *res
|
responses <- *res
|
||||||
}
|
}
|
||||||
@@ -91,10 +98,12 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
if len(result) > 0 {
|
if len(result) > 0 {
|
||||||
json.NewEncoder(w).Encode(result)
|
json.NewEncoder(w).Encode(result)
|
||||||
|
} else {
|
||||||
|
w.Write([]byte("[]"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gs *GatewayServer) Route(sid string, r *http.Request, req *rpc.RPCRequest) (resp *rpc.RPCResponse) {
|
func (gs *GatewayServer) Route(ctx context.Context, sid string, r *http.Request, req *rpc.RPCRequest) (resp *rpc.RPCResponse) {
|
||||||
defer utils.CatchPanicWithFallback(func(rec any) {
|
defer utils.CatchPanicWithFallback(func(rec any) {
|
||||||
gs.x.SLog.Error("panic caught in handler", slog.Any("error", rec))
|
gs.x.SLog.Error("panic caught in handler", slog.Any("error", rec))
|
||||||
resp = rpc.NewError(rpc.ErrInternalError, "Internal server error (panic)", req.ID)
|
resp = rpc.NewError(rpc.ErrInternalError, "Internal server error (panic)", req.ID)
|
||||||
@@ -110,10 +119,10 @@ func (gs *GatewayServer) Route(sid string, r *http.Request, req *rpc.RPCRequest)
|
|||||||
return rpc.NewError(rpc.ErrContextVersion, rpc.ErrContextVersionS, req.ID)
|
return rpc.NewError(rpc.ErrContextVersion, rpc.ErrContextVersionS, req.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = server.Handle(sid, r, req)
|
|
||||||
// checks if request is notification
|
// checks if request is notification
|
||||||
if req.ID == nil {
|
if req.ID == nil {
|
||||||
|
go server.Handle(ctx, sid, r, req)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return resp
|
return server.Handle(ctx, sid, r, req)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package sv1
|
package sv1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *HandlerV1) Handle(sid string, r *http.Request, req *rpc.RPCRequest) *rpc.RPCResponse {
|
func (h *HandlerV1) Handle(_ context.Context, sid string, r *http.Request, req *rpc.RPCRequest) *rpc.RPCResponse {
|
||||||
if req.Method == "" {
|
if req.Method == "" {
|
||||||
h.x.SLog.Info("invalid request received", slog.String("issue", rpc.ErrMethodNotFoundS), slog.String("requested-method", req.Method))
|
h.x.SLog.Info("invalid request received", slog.String("issue", rpc.ErrMethodNotFoundS), slog.String("requested-method", req.Method))
|
||||||
return rpc.NewError(rpc.ErrMethodIsMissing, rpc.ErrMethodIsMissingS, req.ID)
|
return rpc.NewError(rpc.ErrMethodIsMissing, rpc.ErrMethodIsMissingS, req.ID)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package sv1
|
package sv1
|
||||||
|
|
||||||
|
// TODO: make a lua state pool using sync.Pool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|||||||
Reference in New Issue
Block a user