package main import ( "context" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "balance-server/internal/config" "balance-server/internal/database" "balance-server/internal/httpapi" ) func main() { logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) cfg, err := config.Load() if err != nil { logger.Error("configuration error", "error", err) os.Exit(1) } db, err := database.Open(cfg.DatabasePath) if err != nil { logger.Error("database error", "error", err) os.Exit(1) } defer db.Close() server := &http.Server{ Addr: cfg.Address, Handler: httpapi.New(cfg, db, logger), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second, } go func() { logger.Info("Balance server started", "address", cfg.Address, "database", cfg.DatabasePath) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Error("server stopped", "error", err) os.Exit(1) } }() stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) <-stop ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { logger.Error("graceful shutdown failed", "error", err) } }