98 lines
2.0 KiB
Go
98 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"go-server/internal/config"
|
|
"go-server/internal/database"
|
|
"go-server/internal/models"
|
|
"go-server/internal/routes"
|
|
"go-server/internal/server"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("Starting server...")
|
|
|
|
// Load configuration
|
|
cfg, err := config.LoadConfig()
|
|
if err != nil {
|
|
log.Fatalf("Failed to load config: %v", err)
|
|
}
|
|
|
|
// init dbs
|
|
_ = database.InitDatabases(database.NewPostgresConfig(), database.RedisConfig(cfg.Redis))
|
|
|
|
// Initialize PostgreSQL
|
|
db := database.GetPostgres()
|
|
sqlDb, err := db.DB()
|
|
if err != nil {
|
|
log.Fatalf("Failed to get DB connection: %v", err)
|
|
}
|
|
defer sqlDb.Close()
|
|
|
|
// Auto-migrate models to ensure GORM knows about table structures
|
|
err = migrateModels(db)
|
|
if err != nil {
|
|
log.Fatalf("Failed to migrate models: %v", err)
|
|
}
|
|
|
|
// Initialize Redis
|
|
redisClient := database.GetRedis()
|
|
defer redisClient.Close()
|
|
|
|
// Setup router
|
|
router := routes.SetupRouter(db)
|
|
|
|
// Use the server abstraction
|
|
srv := server.NewServer(router)
|
|
|
|
// Handle graceful shutdown
|
|
quit := make(chan os.Signal, 1)
|
|
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
|
|
go func() {
|
|
<-quit
|
|
fmt.Println("Shutting down server...")
|
|
|
|
// Create shutdown context with a timeout
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
// Shutdown services gracefully
|
|
if err := srv.Shutdown(ctx); err != nil {
|
|
log.Fatalf("Server shutdown failed: %v", err)
|
|
}
|
|
|
|
redisClient.Close()
|
|
sqlDb.Close()
|
|
fmt.Println("Server gracefully stopped")
|
|
}()
|
|
|
|
// Start server
|
|
port := cfg.Server.Port
|
|
if err := srv.Start(port); err != nil {
|
|
log.Fatalf("Failed to start server: %v", err)
|
|
}
|
|
}
|
|
|
|
// migrateModels auto-migrates all models to ensure GORM knows about table structures
|
|
func migrateModels(db *gorm.DB) error {
|
|
return db.AutoMigrate(
|
|
models.User{},
|
|
models.Supplement{},
|
|
models.Nutrient{},
|
|
models.Category{},
|
|
models.NutrientCategory{},
|
|
models.SupplementNutrient{},
|
|
models.Todo{},
|
|
models.TodoCompletion{},
|
|
)
|
|
}
|