120 lines
2.5 KiB
Go
120 lines
2.5 KiB
Go
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")
|
|
}
|