package main import ( "context" "flag" "fmt" "os" "os/signal" "syscall" "time" "github.com/rs/zerolog/log" "tss-rocks-be/internal/config" "tss-rocks-be/internal/server" "tss-rocks-be/pkg/logger" ) func main() { // Parse command line flags configPath := flag.String("config", "config/config.yaml", "path to config file") flag.Parse() // Load configuration cfg, err := config.Load(*configPath) if err != nil { fmt.Printf("Error loading config: %v\n", err) os.Exit(1) } // Setup logger logger.Setup(cfg) // Create a context that can be cancelled ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Set up signal handling sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // Create ent client client := server.NewEntClient(cfg) if client == nil { log.Fatal().Msg("Failed to create database client") } defer client.Close() // Run the auto migration tool if err := client.Schema.Create(ctx); err != nil { log.Fatal().Err(err).Msg("Failed to create schema resources") } // Create and start server srv, err := server.New(cfg, client) if err != nil { log.Fatal().Err(err).Msg("Failed to create server") } // Start server in a goroutine go func() { if err := srv.Start(); err != nil { log.Fatal().Err(err).Msg("Failed to start server") } }() // Wait for interrupt signal sig := <-sigChan log.Info().Msgf("Received signal: %v", sig) // Attempt graceful shutdown with timeout log.Info().Msg("Shutting down server...") shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := srv.Shutdown(shutdownCtx); err != nil { log.Error().Err(err).Msg("Server forced to shutdown") os.Exit(1) } }