Moonshark/moonshark.go
2025-03-19 16:50:39 -05:00

153 lines
4.3 KiB
Go

package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"git.sharkk.net/Sky/Moonshark/core/config"
"git.sharkk.net/Sky/Moonshark/core/http"
"git.sharkk.net/Sky/Moonshark/core/logger"
"git.sharkk.net/Sky/Moonshark/core/routers"
"git.sharkk.net/Sky/Moonshark/core/runner"
"git.sharkk.net/Sky/Moonshark/core/utils"
"git.sharkk.net/Sky/Moonshark/core/watchers"
)
// initRouters sets up the Lua and static routers
func initRouters(routesDir, staticDir string, log *logger.Logger) (*routers.LuaRouter, *routers.StaticRouter, error) {
// Ensure directories exist
if err := utils.EnsureDir(routesDir); err != nil {
return nil, nil, fmt.Errorf("routes directory doesn't exist, and could not create it: %v", err)
}
if err := utils.EnsureDir(staticDir); err != nil {
return nil, nil, fmt.Errorf("static directory doesn't exist, and could not create it: %v", err)
}
// Initialize Lua router for dynamic routes
luaRouter, err := routers.NewLuaRouter(routesDir)
if err != nil {
return nil, nil, fmt.Errorf("failed to initialize Lua router: %v", err)
}
log.Info("Lua router initialized with routes from %s", routesDir)
// Initialize static file router
staticRouter, err := routers.NewStaticRouterWithLogger(staticDir, log)
if err != nil {
return nil, nil, fmt.Errorf("failed to initialize static router: %v", err)
}
log.Info("Static router initialized with files from %s", staticDir)
staticRouter.EnableDebugLog()
return luaRouter, staticRouter, nil
}
func main() {
// Initialize logger
log := logger.New(logger.LevelDebug, true)
log.Server("Starting Moonshark server")
// Load configuration from config.lua
cfg, err := config.Load("config.lua")
if err != nil {
log.Warning("Failed to load config.lua: %v", err)
log.Info("Using default configuration")
cfg = config.New()
}
switch cfg.GetString("log_level", "info") {
case "debug":
log.SetLevel(logger.LevelDebug)
case "warn":
log.SetLevel(logger.LevelWarning)
case "error":
log.SetLevel(logger.LevelError)
case "server":
log.SetLevel(logger.LevelServer)
case "fatal":
log.SetLevel(logger.LevelFatal)
default:
log.SetLevel(logger.LevelInfo)
}
// Get port from config or use default
port := cfg.GetInt("port", 3117)
// Initialize routers
routesDir := cfg.GetString("routes_dir", "./routes")
staticDir := cfg.GetString("static_dir", "./static")
luaRouter, staticRouter, err := initRouters(routesDir, staticDir, log)
if err != nil {
log.Fatal("Router initialization failed: %v", err)
}
if cfg.GetBool("watchers", false) {
// Set up file watchers for automatic reloading
luaWatcher, err := watchers.WatchLuaRouter(luaRouter, routesDir, log)
if err != nil {
log.Warning("Failed to watch routes directory: %v", err)
} else {
defer luaWatcher.Close()
log.Info("File watcher active for Lua routes")
}
staticWatcher, err := watchers.WatchStaticRouter(staticRouter, staticDir, log)
if err != nil {
log.Warning("Failed to watch static directory: %v", err)
} else {
defer staticWatcher.Close()
log.Info("File watcher active for static files")
}
}
// Get buffer size from config or use default (used to be worker pool size)
bufferSize := cfg.GetInt("buffer_size", 20)
// Initialize Lua runner (replacing worker pool)
runner, err := runner.NewRunner(
runner.WithBufferSize(bufferSize),
runner.WithLibDirs("./libs"),
)
if err != nil {
log.Fatal("Failed to initialize Lua runner: %v", err)
}
log.Server("Lua runner initialized with buffer size %d", bufferSize)
defer runner.Close()
// Create HTTP server
server := http.New(luaRouter, staticRouter, runner, log)
// Handle graceful shutdown
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
// Start server in a goroutine
go func() {
if err := server.ListenAndServe(fmt.Sprintf(":%d", port)); err != nil {
if err.Error() != "http: Server closed" {
log.Error("Server error: %v", err)
}
}
}()
log.Server("Server started on port %d", port)
// Wait for interrupt signal
<-stop
log.Server("Shutdown signal received")
// Gracefully shut down the server
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Error("Server shutdown error: %v", err)
}
log.Server("Server stopped")
}