@@ -1282,6 +1282,48 @@ func TestPoolSendBatchBatchCloseTwice(t *testing.T) {
12821282 }
12831283}
12841284
1285+ func TestPoolAcquireDestroysExpiredIdleConn (t * testing.T ) {
1286+ t .Parallel ()
1287+
1288+ ctx , cancel := context .WithTimeout (context .Background (), 120 * time .Second )
1289+ defer cancel ()
1290+
1291+ config , err := pgxpool .ParseConfig (os .Getenv ("PGX_TEST_DATABASE" ))
1292+ require .NoError (t , err )
1293+
1294+ config .MaxConnLifetime = 250 * time .Millisecond
1295+ config .HealthCheckPeriod = 10 * time .Second
1296+
1297+ pool , err := pgxpool .NewWithConfig (ctx , config )
1298+ require .NoError (t , err )
1299+ defer pool .Close ()
1300+
1301+ // Acquire and release before expiry so the connection goes idle while still valid.
1302+ c , err := pool .Acquire (ctx )
1303+ require .NoError (t , err )
1304+ c .Release ()
1305+ waitForReleaseToComplete ()
1306+
1307+ require .EqualValues (t , 1 , pool .Stat ().TotalConns ())
1308+ require .EqualValues (t , 0 , pool .Stat ().MaxLifetimeDestroyCount ())
1309+
1310+ // Wait for the idle connection to expire.
1311+ time .Sleep (config .MaxConnLifetime + 100 * time .Millisecond )
1312+
1313+ // Acquire should pick up the expired idle conn, the new isExpired check in Acquire
1314+ // destroys it, and a fresh connection is created.
1315+ c , err = pool .Acquire (ctx )
1316+ require .NoError (t , err )
1317+ c .Release ()
1318+
1319+ // Give destroy time to settle.
1320+ time .Sleep (500 * time .Millisecond )
1321+
1322+ stats := pool .Stat ()
1323+ require .EqualValues (t , 1 , stats .MaxLifetimeDestroyCount ())
1324+ require .EqualValues (t , 1 , stats .TotalConns ())
1325+ }
1326+
12851327func TestPoolAcquirePingTimeout (t * testing.T ) {
12861328 t .Parallel ()
12871329
0 commit comments