You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Disposing a pooled data source does not release pending connection opens #6514
When a pooled NpgsqlDataSource is exhausted and an Open/OpenAsync call is blocked waiting for a connector, disposing the data source does not release that pending open attempt.
Instead, the pending call continues waiting until the pool timeout elapses, and then fails with the normal pool-exhaustion timeout error:
"The connection pool has been exhausted..."
This is misleading because the real cause is that the data source has already been disposed. It also means blocked callers can remain stuck for the full pool timeout during shutdown.
Expected behavior is for pending open attempts to fail promptly when the data source is disposed, ideally with the exception: The connection pool has been shut down
See this minimal repro which shows that connection 2 waits 5 seconds (the configured timeout) even though the data source has already been disposed:
usingSystem.Diagnostics;usingNpgsql;varcsb=newNpgsqlConnectionStringBuilder("Host=localhost;Database=npgsql_tests;Username=postgres;Password=postgres;"){MaxPoolSize=1,Timeout=5};vardataSource=NpgsqlDataSource.Create(csb);varsw=Stopwatch.StartNew();awaitusingvarconnection1=awaitOpenConnectionAsync(1);// Connection pool is exhausted, so opening a second connection will blockvarpending=OpenConnectionAsync(2);Console.WriteLine($"[{sw.ElapsedMilliseconds}] Disposing data source...");awaitdataSource.DisposeAsync().ConfigureAwait(false);Console.WriteLine($"[{sw.ElapsedMilliseconds}] Disposed data source.");// Connection 2 is still trying to connect until it eventually times outtry{awaitusingvarconnection2=awaitpending;}catch{/* ignored */}return;asyncTask<NpgsqlConnection>OpenConnectionAsync(intconnectionNumber){try{Console.WriteLine($"[{sw.ElapsedMilliseconds}] Opening connection {connectionNumber}...");varconnection=awaitdataSource.OpenConnectionAsync().ConfigureAwait(false);Console.WriteLine($"[{sw.ElapsedMilliseconds}] Connection {connectionNumber} opened");returnconnection;}catch(Exceptionex){Console.Error.WriteLine($"[{sw.ElapsedMilliseconds}] Failed to open connection {connectionNumber}: {ex.Message}");throw;}}
[0] Opening connection 1...
[86] Connection 1 opened
[86] Opening connection 2...
[87] Disposing data source...
[89] Disposed data source.
[5090] Failed to open connection 2: The connection pool has been exhausted, either raise 'Max Pool Size' (currently 1) or 'Timeout' (currently 5 seconds) in your connection string.
Activity