package db import ( "context" "fmt" "log/slog" "time" "github.com/jackc/pgx/v5/pgxpool" ) func Connect(ctx context.Context, dsn string) (*pgxpool.Pool, error) { cfg, err := pgxpool.ParseConfig(dsn) if err != nil { return nil, fmt.Errorf("parse dsn: %w", err) } cfg.MaxConns = 10 cfg.MinConns = 1 cfg.MaxConnLifetime = time.Hour cfg.HealthCheckPeriod = time.Minute var pool *pgxpool.Pool var lastErr error backoff := time.Second for attempt := 1; attempt <= 10; attempt++ { pool, err = pgxpool.NewWithConfig(ctx, cfg) if err == nil { pingCtx, cancel := context.WithTimeout(ctx, 5*time.Second) err = pool.Ping(pingCtx) cancel() if err == nil { return pool, nil } pool.Close() } lastErr = err slog.Warn("db connect attempt failed", "attempt", attempt, "error", err) select { case <-ctx.Done(): return nil, ctx.Err() case <-time.After(backoff): } if backoff < 15*time.Second { backoff *= 2 } } return nil, fmt.Errorf("connect to database after retries: %w", lastErr) }