package app import ( "context" "fmt" "go_oxspeak_server/config" "go_oxspeak_server/database" "go_oxspeak_server/models" "go_oxspeak_server/network/http" "go_oxspeak_server/network/udp" "os" "os/signal" "syscall" "gorm.io/gorm" ) type App struct { cfg *config.Config // DB db *gorm.DB // Serveurs udpServer *udp.Server httpServer *http.Server // Context (to be used for graceful shutdown) ctx context.Context cancel context.CancelFunc sigChan chan os.Signal errChan chan error } func NewApp(cfg *config.Config) *App { ctx, cancel := context.WithCancel(context.Background()) // Channel pour capturer les signaux d'arrêt (Ctrl+c, etc...) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) // Channel pour les erreurs errChan := make(chan error, 1) // database init dbConfig := database.DBConfig{ Driver: cfg.Database.Type, DSN: cfg.GetDSN(), } // 1) Initialiser la DB if err := database.Initialize(dbConfig); err != nil { //return fmt.Errorf("failed to initialize database: %w", err) } // Servers udpServer := udp.NewServer(cfg.Server.BindAddr) httpServer := http.NewServer(cfg.Server.BindAddr) return &App{ cfg: cfg, udpServer: udpServer, httpServer: httpServer, ctx: ctx, cancel: cancel, sigChan: sigChan, errChan: errChan, } } func (app *App) Run() error { // Context pour gérer l'arrêt gracieux defer app.cancel() // (optionnel) garder une référence locale si tu veux utiliser app.db ailleurs app.db = database.DB // 2) Lancer les migrations en utilisant le registry des modèles if err := database.AutoMigrate(models.All()...); err != nil { return fmt.Errorf("failed to auto-migrate database: %w", err) } // 3) Lancer les workers / serveurs go app.runWorkers() fmt.Println("App started, press CTRL+C to stop...") select { case err := <-app.errChan: return fmt.Errorf("error in the app: %w", err) case sig := <-app.sigChan: fmt.Printf("\nSIGTERM received: %v, stopping app...\n", sig) app.cancel() // Annule le context pour arrêter les goroutines return nil } } func (app *App) runDBMigrations() { database.AutoMigrate() } func (app *App) runWorkers() { // lancer le serveur udp go func() { if err := app.udpServer.Run(); err != nil { app.errChan <- err } }() // lancer le serveur http go func() { if err := app.httpServer.Run(); err != nil { app.errChan <- err } }() <-app.ctx.Done() fmt.Println("App stopped") }