package main import ( "context" "fmt" "net/http" "os" "os/signal" "syscall" "DanceLessonsCoach/pkg/config" "DanceLessonsCoach/pkg/server" "github.com/rs/zerolog/log" ) func main() { // Load configuration cfg, err := config.LoadConfig() if err != nil { log.Fatal().Err(err).Msg("Failed to load configuration") } // Create root context with cancellation ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Set up graceful shutdown sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // Start server in goroutine server := server.NewServer() serverCtx, serverStop := context.WithCancel(ctx) go func() { fmt.Printf("Server running on %s\n", cfg.GetServerAddress()) log.Info().Str("address", cfg.GetServerAddress()).Msg("Starting HTTP server") srv := &http.Server{ Addr: cfg.GetServerAddress(), Handler: server.Router(), } // Listen for shutdown signal go func() { <-sigChan log.Info().Msg("Shutdown signal received") // Create shutdown context with timeout from config shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), cfg.Shutdown.Timeout) defer shutdownCancel() if err := srv.Shutdown(shutdownCtx); err != nil { log.Error().Err(err).Msg("Server shutdown failed") } else { log.Info().Msg("Server shutdown complete") } cancel() serverStop() }() if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Error().Err(err).Msg("Server error") } }() // Wait for shutdown <-serverCtx.Done() log.Info().Msg("Server exited") }