package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "nfeeder/internal/db" "nfeeder/internal/web" "github.com/jackc/pgx/v5/pgxpool" ) func main() { ctx, ctxCancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer ctxCancel() // DB init // ------------------------------------------------------------ connStr := os.Getenv("DATABASE_URL") if connStr == "" { log.Fatal("DATABASE_URL environment variable is not set") } poolConfig, err := pgxpool.ParseConfig(connStr) if err != nil { log.Fatalf("Unable to parse DATABASE_URL: %v", err) } poolConfig.MaxConns = 25 poolConfig.MinConns = 5 poolConfig.MaxConnLifetime = 5 * time.Minute poolConfig.MaxConnIdleTime = 30 * time.Second pool, err := pgxpool.NewWithConfig(ctx, poolConfig) if err != nil { log.Fatalf("Unable to create connection pool: %v", err) } // Verify the connection is alive before proceeding if err := pool.Ping(ctx); err != nil { log.Fatalf("Unable to reach database: %v", err) } fmt.Println("Database connection established") defer func() { pool.Close() fmt.Println("Database pool closed") }() // Create Store sqlc wrapper store := db.NewStore(pool) // Server Init // ------------------------------------------------------------ jwtSecret := os.Getenv("JWT_SECRET") if jwtSecret == "" { log.Fatal("JWT_SECRET environment variable is required") } server := web.NewServer(store, jwtSecret) // We run it in a goroutine so it doesn't block main from reaching the signal listener. go func() { addr := os.Getenv("SERVER_PORT") if connStr == "" { log.Fatal("SERVER_PORT environment variable is not set") } fmt.Printf("Server starting on %s\n", addr) if err := server.Start(addr); err != nil && err != http.ErrServerClosed { log.Fatalf("Server failed: %v", err) } }() // Graceful Shutdown // ------------------------------------------------------------ <-ctx.Done() fmt.Println("\nShutdown signal received. Starting graceful exit...") shutdownCtx, shutdownCtxCancel := context.WithTimeout(context.Background(), 10*time.Second) defer shutdownCtxCancel() if err := server.Shutdown(shutdownCtx); err != nil { log.Fatalf("Graceful shutdown failed: %v", err) } fmt.Println("Server exited properly") }