package main import ( "context" "fmt" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "github.com/llamalink/llamalink/internal/api" "github.com/llamalink/llamalink/internal/config" "github.com/llamalink/llamalink/internal/db" "github.com/llamalink/llamalink/internal/llama" ) var ( Version = "dev" BuildTime = "unknown" ) func main() { cfg := config.Load() logger := cfg.Logger() slog.SetDefault(logger) logger.Info("starting llamalink", "version", Version, "build_time", BuildTime, "env", cfg.LlamalinkEnv, ) // Initialize database database, err := db.Open(cfg) if err != nil { logger.Error("failed to open database", "error", err) os.Exit(1) } defer func() { sqlDB, _ := database.DB() if sqlDB != nil { sqlDB.Close() } }() // Run migrations if err := db.Migrate(database); err != nil { logger.Error("failed to run migrations", "error", err) os.Exit(1) } logger.Info("database migrations complete") // Seed admin key if needed if err := db.SeedAdminKey(database, cfg.AdminToken); err != nil { logger.Error("failed to seed admin key", "error", err) os.Exit(1) } // Initialize llama manager var llamaManager *llama.Manager if cfg.ManageLlamaServer { llamaManager = llama.NewManager(cfg, database) if err := llamaManager.Start(); err != nil { logger.Warn("failed to start llama manager", "error", err) } defer llamaManager.Stop() } // Setup router router := api.New(cfg, database, llamaManager) // Server addr := fmt.Sprintf("%s:%d", cfg.LlamalinkHost, cfg.LlamalinkPort) srv := &http.Server{ Addr: addr, Handler: router, ReadTimeout: 30 * time.Second, WriteTimeout: 60 * time.Second, IdleTimeout: 120 * time.Second, } // Graceful shutdown quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) go func() { logger.Info("server listening", "addr", addr) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Error("server error", "error", err) os.Exit(1) } }() <-quit logger.Info("shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { logger.Error("server forced to shutdown", "error", err) } logger.Info("server stopped") }