NewPostgreSQL creates a new instance of the PostgreSQL database
(ctx context.Context, connectionURI string)
| 39 | |
| 40 | // NewPostgreSQL creates a new instance of the PostgreSQL database |
| 41 | func NewPostgreSQL(ctx context.Context, connectionURI string) (*PostgreSQL, error) { |
| 42 | // Parse connection config for pool settings |
| 43 | config, err := pgxpool.ParseConfig(connectionURI) |
| 44 | if err != nil { |
| 45 | return nil, fmt.Errorf("failed to parse PostgreSQL config: %w", err) |
| 46 | } |
| 47 | |
| 48 | // Configure pool for stability-focused defaults. |
| 49 | // MaxConns was 30 per pod (60 total across 2 replicas) which saturated under |
| 50 | // the 2026-04-28 scraper bursts (15 req/s on /v0/servers caused queue blowup |
| 51 | // even though individual queries were fast). 60 per pod gives 120 total, |
| 52 | // leaving 80 of PG max_connections=200 for autovacuum/admin/headroom. |
| 53 | config.MaxConns = 60 // Handle scraper-burst concurrent load |
| 54 | config.MinConns = 10 // Keep connections warm for fast response |
| 55 | config.MaxConnIdleTime = 30 * time.Minute // Keep connections available for bursts |
| 56 | config.MaxConnLifetime = 2 * time.Hour // Refresh connections regularly for stability |
| 57 | |
| 58 | // Create connection pool with configured settings |
| 59 | pool, err := pgxpool.NewWithConfig(ctx, config) |
| 60 | if err != nil { |
| 61 | return nil, fmt.Errorf("failed to create PostgreSQL pool: %w", err) |
| 62 | } |
| 63 | |
| 64 | // Test the connection |
| 65 | if err = pool.Ping(ctx); err != nil { |
| 66 | return nil, fmt.Errorf("failed to ping PostgreSQL: %w", err) |
| 67 | } |
| 68 | |
| 69 | // Run migrations using a single connection from the pool |
| 70 | conn, err := pool.Acquire(ctx) |
| 71 | if err != nil { |
| 72 | return nil, fmt.Errorf("failed to acquire connection for migrations: %w", err) |
| 73 | } |
| 74 | defer conn.Release() |
| 75 | |
| 76 | migrator := NewMigrator(conn.Conn()) |
| 77 | if err := migrator.Migrate(ctx); err != nil { |
| 78 | return nil, fmt.Errorf("failed to run database migrations: %w", err) |
| 79 | } |
| 80 | |
| 81 | return &PostgreSQL{ |
| 82 | pool: pool, |
| 83 | }, nil |
| 84 | } |
| 85 | |
| 86 | // buildFilterConditions constructs WHERE clause conditions from a ServerFilter |
| 87 | // |
no test coverage detected
searching dependent graphs…