fixed logs and config locations, updated connection closure handling

This commit is contained in:
2025-12-10 11:22:09 +01:00
parent 709abb30fa
commit 27609dba2b
7 changed files with 75 additions and 24 deletions

View File

@@ -1,8 +1,6 @@
package controller package controller
import ( import "homestead/homestead_gateway/ws"
"homestead/homestead_gateway/ws"
)
type GatewayController struct { type GatewayController struct {
Websocket *ws.WebsocketGateway Websocket *ws.WebsocketGateway

13
main.go
View File

@@ -3,11 +3,20 @@ package main
import ( import (
"flag" "flag"
"homestead/homestead_gateway/controller" "homestead/homestead_gateway/controller"
"homestead/homestead_gateway/util"
"homestead/homestead_gateway/util/config" "homestead/homestead_gateway/util/config"
"os"
"path"
) )
func main() { func main() {
cfgPath := flag.String("config", "config.toml", "configuration file") dir := util.GetPath()
if dir == "" {
dir, _ = os.Getwd()
}
file := path.Join(dir, "config.toml")
cfgPath := flag.String("config", file, "configuration file")
cfg, err := config.LoadConfig(*cfgPath) cfg, err := config.LoadConfig(*cfgPath)
if err != nil { if err != nil {
panic(err) panic(err)
@@ -19,3 +28,5 @@ func main() {
panic(err) panic(err)
} }
} }
// todo logs from exe not cwd

2
sim.go
View File

@@ -23,7 +23,7 @@ const (
apiKey = "gateway" apiKey = "gateway"
serverID = "test-server-001" serverID = "test-server-001"
// THE CHANNEL ID the mod says it serves. Must match gateway expectation. // THE CHANNEL ID the mod says it serves. Must match gateway expectation.
channelID = "123456789" channelID = "1444253682777587804"
) )
// send interval range (random between minInterval and maxInterval) // send interval range (random between minInterval and maxInterval)

View File

@@ -3,6 +3,7 @@ package logger
import ( import (
"context" "context"
"fmt" "fmt"
"homestead/homestead_gateway/util"
"homestead/homestead_gateway/util/config" "homestead/homestead_gateway/util/config"
"log/slog" "log/slog"
"os" "os"
@@ -23,6 +24,7 @@ func New(id string, cfg config.LogConfig) (*slog.Logger, func() error, error) {
cfg.Rotation = 7 cfg.Rotation = 7
} }
cfg.Directory = util.NormalizeLogPath(cfg.Directory)
console := slog.NewTextHandler(&prefixWriter{inner: os.Stderr, prefix: []byte("[" + id + "] "), startLine: true}, &slog.HandlerOptions{AddSource: true, Level: cfg.Level}) console := slog.NewTextHandler(&prefixWriter{inner: os.Stderr, prefix: []byte("[" + id + "] "), startLine: true}, &slog.HandlerOptions{AddSource: true, Level: cfg.Level})
router := newFileRouter(cfg.Directory, cfg.Rotation, id) router := newFileRouter(cfg.Directory, cfg.Rotation, id)
root := slogmulti.Fanout(console, router) root := slogmulti.Fanout(console, router)

51
util/util.go Normal file
View File

@@ -0,0 +1,51 @@
package util
import (
"os"
"path/filepath"
"time"
"github.com/gorilla/websocket"
)
func GetPath() string {
exe, err := os.Executable()
if err != nil {
return ""
}
exe, err = filepath.EvalSymlinks(exe)
if err != nil {
}
return filepath.Dir(exe)
}
func NormalizePath(path string) string {
return filepath.Clean(filepath.FromSlash(path))
}
func NormalizeLogPath(path string) string {
if filepath.IsAbs(path) {
return path
}
return NormalizePath(filepath.Join(GetPath(), path))
}
//
func CloseConnWithControlMessage(conn *websocket.Conn, typ int, text string) {
_ = conn.SetWriteDeadline(time.Now().Add(time.Second))
_ = conn.WriteControl(
typ, websocket.FormatCloseMessage(typ, text), time.Now().Add(time.Second),
)
_ = conn.Close()
}
func CloseConn(conn *websocket.Conn) {
CloseConnWithControlMessage(
conn, websocket.CloseNormalClosure,
"Disconnecting.",
)
}

View File

@@ -2,6 +2,7 @@ package ws
import ( import (
"fmt" "fmt"
"homestead/homestead_gateway/util"
"time" "time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
@@ -92,8 +93,7 @@ func (r *Registry) RegisterMod(channelID, serverID string, conn *websocket.Conn)
defer e.mu.Unlock() defer e.mu.Unlock()
if e.Mod != nil && e.Mod.Conn != nil { if e.Mod != nil && e.Mod.Conn != nil {
util.CloseConn(e.Mod.Conn)
_ = e.Mod.Conn.Close()
} }
e.Mod = &ConnWrapper{Conn: conn, ServerID: serverID, LastSeen: time.Now()} e.Mod = &ConnWrapper{Conn: conn, ServerID: serverID, LastSeen: time.Now()}
@@ -106,7 +106,7 @@ func (r *Registry) RegisterBot(conn *websocket.Conn) {
r.botMu.Lock() r.botMu.Lock()
if r.bot != nil && r.bot.Conn != nil { if r.bot != nil && r.bot.Conn != nil {
_ = r.bot.Conn.Close() r.UnregisterBot()
} }
r.bot = &ConnWrapper{Conn: conn, LastSeen: time.Now()} r.bot = &ConnWrapper{Conn: conn, LastSeen: time.Now()}
@@ -127,7 +127,7 @@ func (r *Registry) UnregisterMod(channelID string) {
e.mu.Unlock() e.mu.Unlock()
if modConn != nil && modConn.Conn != nil { if modConn != nil && modConn.Conn != nil {
closeConn(modConn.Conn) util.CloseConn(modConn.Conn)
} }
} }
@@ -138,7 +138,7 @@ func (r *Registry) UnregisterBot() {
r.botMu.Unlock() r.botMu.Unlock()
if botConn != nil && botConn.Conn != nil { if botConn != nil && botConn.Conn != nil {
closeConn(botConn.Conn) util.CloseConn(botConn.Conn)
} }
} }
@@ -152,7 +152,6 @@ func (r *Registry) Send(channelID string, out GatewayMessageOut, sendOverConn fu
if err := sendOverConn(b.Conn, out); err == nil { if err := sendOverConn(b.Conn, out); err == nil {
return true, false, nil return true, false, nil
} }
_ = b.Conn.Close()
r.UnregisterBot() r.UnregisterBot()
} }
@@ -176,7 +175,6 @@ func (r *Registry) Send(channelID string, out GatewayMessageOut, sendOverConn fu
if err := sendOverConn(mod.Conn, out); err == nil { if err := sendOverConn(mod.Conn, out); err == nil {
return true, false, nil return true, false, nil
} }
_ = mod.Conn.Close()
r.UnregisterMod(channelID) r.UnregisterMod(channelID)
} }

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"homestead/homestead_gateway/util"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@@ -55,7 +56,7 @@ func (wsg *WebsocketGateway) sendWebsocketError(conn *websocket.Conn, message st
_ = conn.SetWriteDeadline(time.Now().Add(5 * time.Second)) _ = conn.SetWriteDeadline(time.Now().Add(5 * time.Second))
_ = conn.WriteJSON(map[string]interface{}{"message": message, "code": code}) _ = conn.WriteJSON(map[string]interface{}{"message": message, "code": code})
if close { if close {
_ = conn.Close() util.CloseConn(conn)
} }
} }
@@ -64,7 +65,7 @@ func (wsg *WebsocketGateway) sendWebsocketResponse(conn *websocket.Conn, content
if err := conn.WriteJSON(content); err != nil { if err := conn.WriteJSON(content); err != nil {
wsg.logger.Error("Failed to respond to connection.", "remote", conn.RemoteAddr().String(), "err", err) wsg.logger.Error("Failed to respond to connection.", "remote", conn.RemoteAddr().String(), "err", err)
_ = conn.Close() util.CloseConnWithControlMessage(conn, websocket.CloseAbnormalClosure, "Connection error.")
return err return err
} }
@@ -108,16 +109,6 @@ func (wsg *WebsocketGateway) loggingMiddleware(next http.Handler) http.Handler {
// connections // connections
func closeConn(conn *websocket.Conn) {
_ = conn.SetWriteDeadline(time.Now().Add(time.Second))
_ = conn.WriteControl(
websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, "Disconnecting."),
time.Now().Add(time.Second),
)
_ = conn.Close()
}
func (wsg *WebsocketGateway) registerConn(conn *websocket.Conn, typ, channelId, serverId string) bool { func (wsg *WebsocketGateway) registerConn(conn *websocket.Conn, typ, channelId, serverId string) bool {
if typ == "bot" { if typ == "bot" {
wsg.registry.botMu.Lock() wsg.registry.botMu.Lock()