From c4ab5063038ac3d66f4aa33337b3d0023c2780c1 Mon Sep 17 00:00:00 2001 From: praxzy <151594398+praxzy@users.noreply.github.com> Date: Sun, 27 Sep 2026 16:29:18 +0530 Subject: [PATCH] fix: restore default idle connection pooling --- internal/storage/dial.go | 8 ++++- internal/storage/dial_test.go | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/internal/storage/dial.go b/internal/storage/dial.go index c296b7af09..f8ce656f67 100644 --- a/internal/storage/dial.go +++ b/internal/storage/dial.go @@ -312,9 +312,15 @@ type ConnLimits struct { } func newConnLimitsFromConfig(dbCfg *conf.DBConfiguration) *ConnLimits { + maxIdleConns := dbCfg.MaxIdlePoolSize + if maxIdleConns == 0 { + // match pop's default when no idle pool size is configured + maxIdleConns = 2 + } + return &ConnLimits{ MaxOpenConns: dbCfg.MaxPoolSize, - MaxIdleConns: dbCfg.MaxIdlePoolSize, + MaxIdleConns: maxIdleConns, ConnMaxLifetime: dbCfg.ConnMaxLifetime, ConnMaxIdleTime: dbCfg.ConnMaxIdleTime, Strategy: connLimitsErrorStrategy, diff --git a/internal/storage/dial_test.go b/internal/storage/dial_test.go index 52b16d1906..f431ca7b86 100644 --- a/internal/storage/dial_test.go +++ b/internal/storage/dial_test.go @@ -135,6 +135,64 @@ func TestConnection(t *testing.T) { }) } +func TestApplyConfigDefaultIdlePoolReusesConnection(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + config := mustConfig(t) + // reset pool limits to defaults + config.DB = conf.DBConfiguration{ + Driver: config.DB.Driver, + URL: config.DB.URL, + Namespace: config.DB.Namespace, + } + + db, err := DialContext(ctx, config) + require.NoError(t, err) + defer db.Close() + require.NotNil(t, db.sqldb) + + backendPID := func() int { + t.Helper() + var pid int + err := db.sqldb.QueryRowContext(ctx, "SELECT pg_backend_pid()").Scan(&pid) + require.NoError(t, err) + return pid + } + + pid := backendPID() + require.Equal(t, pid, backendPID(), "connections should be reused before applying configuration") + + le := observability.GetLogEntryFromContext(ctx).Entry + require.NoError(t, db.ApplyConfig(ctx, config, le)) + + require.Equal(t, pid, backendPID(), "applying the default pool configuration should preserve connection reuse") +} + +func TestNewConnLimitsFromConfigIdlePool(t *testing.T) { + tests := []struct { + name string + configured int + expected int + }{ + {name: "default", configured: 0, expected: 2}, + {name: "explicit", configured: 20, expected: 20}, + {name: "disabled", configured: -1, expected: -1}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := conf.DBConfiguration{ + MaxIdlePoolSize: tt.configured, + } + + limits := newConnLimitsFromConfig(&cfg) + + require.Equal(t, tt.expected, limits.MaxIdleConns) + }) + } +} + func TestConnLimits(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel()