package main import ( "context" "flag" "log/slog" "os" "os/signal" "syscall" "time" "yobbly-gateway-go/internal/config" "yobbly-gateway-go/internal/logger" "yobbly-gateway-go/internal/server" "yobbly-gateway-go/pkg/geoip" ) func main() { var configPath string flag.StringVar(&configPath, "config", "configs/config.yml", "config file path") flag.Parse() if configPath == "" { configPath = os.Getenv("CONFIG_PATH") } logger.InitLogger("info", "text") op := "main.main" log := logger.NewLoggerWithOp(op) cfg, err := config.Load(configPath) if err != nil { log.Error("failed to load configuration", slog.String("path", configPath), slog.Any("error", err)) os.Exit(1) } // Повторно инициализируем логгер с настройками из конфигурации logger.InitLogger(cfg.Logging.Level, cfg.Logging.Format) log = logger.NewLoggerWithOp(op) // Повторно создаем логгер с обновленным уровнем и форматом log.Info("configuration loaded successfully") // Инициализируем сервис GeoIP geoipService, err := geoip.NewGeoIPService(cfg.Gateway.GeoIPDB, cfg.Gateway.BlockedCountries) if err != nil { log.Error("failed to initialize GeoIP service", slog.Any("error", err)) os.Exit(1) } defer geoipService.Close() // Создаем экземпляр сервера srv := server.NewServer(cfg, geoipService) // Запускаем сервер в отдельной горутине done := make(chan struct{}) errChan := srv.Start(cfg.TLS.FullChain, cfg.TLS.PrivateKey) // Настраиваем перехват системных сигналов для graceful shutdown sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) go func() { select { case err := <-errChan: if err != nil { log.Error("server error", slog.Any("error", err)) } case sig := <-sigChan: log.Info("received signal", slog.String("signal", sig.String())) // Создаем контекст с таймаутом для graceful shutdown shutdownCtx, cancel := context.WithTimeout(context.Background(), 35*time.Second) // TODO: Make configurable defer cancel() if err := srv.Shutdown(shutdownCtx); err != nil { log.Error("server graceful shutdown failed", slog.Any("error", err)) os.Exit(1) } } close(done) }() <-done log.Info("application stopped") }