-
Notifications
You must be signed in to change notification settings - Fork 311
Get/Return pooled connections #3404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Get/Return pooled connections #3404
Conversation
9d95355
to
73a379b
Compare
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
@roji tagging you here if you have any time to review. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, it looks good. A bunch of things I'd like addressed, but you know I'll accept valid arguments against fixing them :)
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...lient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPoolTest.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reviewed the ChannelDbConnectionPool changes. I will look at the tests once we have converged on an implementation. It might be a good idea to host another meeting to walk through the commentary here.
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
@@ -20,52 +25,136 @@ namespace Microsoft.Data.SqlClient.ConnectionPool | |||
/// </summary> | |||
internal sealed class ChannelDbConnectionPool : IDbConnectionPool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
… connection disposal when opening new connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're getting closer!
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3404 +/- ##
==========================================
- Coverage 69.75% 63.78% -5.97%
==========================================
Files 276 201 -75
Lines 62192 44159 -18033
==========================================
- Hits 43381 28169 -15212
+ Misses 18811 15990 -2821
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still looking for some changes from previous reviews. Good changes in these last 4 commits though.
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good. Will look at tests shortly. Going to loop through older comments first.
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look at the slot tests. I'll spin through the pool tests once this set of comments is resolved.
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
...SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements core Get and Return functionality for the new ChannelDbConnectionPool class, establishing the foundation for channel-based connection pooling. The implementation introduces a novel approach using System.Threading.Channels for managing idle connections and a custom ConnectionPoolSlots class for thread-safe connection tracking.
- Adds channel-based connection pooling with Get/Return operations that respect max pool size limits
- Implements ConnectionPoolSlots for thread-safe connection management with reservation-based slot allocation
- Includes comprehensive unit test coverage for both connection pooling logic and slot management
Reviewed Changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
tools/specs/Microsoft.Data.SqlClient.nuspec | Adds System.Threading.Channels dependency for both .NET 6+ and .NET 8+ target frameworks |
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlotsTest.cs | New comprehensive unit tests for ConnectionPoolSlots covering concurrent operations, capacity limits, and edge cases |
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPoolTest.cs | Extensive unit tests for ChannelDbConnectionPool covering sync/async operations, timeout handling, connection reuse, and stress testing |
src/Microsoft.Data.SqlClient/src/System/Runtime/CompilerServices/IsExternalInit.netfx.cs | Adds explanatory comment for C# 9.0 init accessor polyfill |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs | Makes constructor protected and refactors connection creation methods to support pooling scenarios |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs | Updates ReturnInternalConnection signature and removes redundant validation logic |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/IDbConnectionPool.cs | Updates interface signatures for nullable references and standardizes parameter types |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolState.cs | Removes Initializing state from enum |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs | New thread-safe collection with fixed capacity using reservation-based slot allocation |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs | Implements core connection pooling with channel-based idle connection management |
src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs | Exposes CreateTime property and updates PrePush signature for stronger typing |
Various project files | Adds System.Threading.Channels package references across different target frameworks |
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ConnectionPoolSlots.cs
Outdated
Show resolved
Hide resolved
...rosoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delays in unit tests are always a bit of a smell ... but ehhhhhhhhhhhhhh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of new suggestions. I'll look at the remaining tests after 6.1.1 has simmered down.
@@ -545,13 +545,13 @@ private void PrepareConnection(DbConnection owningObject, DbConnectionInternal c | |||
//TODO: pass through transaction | |||
connection.ActivateConnection(null); | |||
} | |||
catch (Exception e) | |||
catch | |||
{ | |||
// At this point, the connection is "out of the pool" (the call to postpop). If we hit a transient | |||
// error anywhere along the way when enlisting the connection in the transaction, we need to get | |||
// the connection back into the pool so that it isn't leaked. | |||
ReturnInternalConnection(connection, owningObject); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this function throw? The docs don't say much, and the code doesn't mention which calls within the function, if any, could throw. It would be bad for this to throw and then we lose the original exception.
@@ -141,7 +141,7 @@ internal ConnectionPoolSlots(uint fixedCapacity) | |||
catch (Exception e) | |||
{ | |||
cleanupCallback(connection, cleanupState); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed this. You can capture the state info directly within the delegate lambda expressions in OpenNewInternalConnection()
:
return _connectionSlots.Add(
createCallback: () =>
{
return ConnectionFactory.CreatePooledConnection(
owningConnection,
this,
PoolGroup.PoolKey,
PoolGroup.ConnectionOptions,
userOptions);
},
cleanupCallback: static (newConnection) =>
{
_idleConnectionWriter.TryWrite(null);
newConnection?.Dispose();
});
This changes the delegates from static to not-static, so that may have performance implications, but I'd be surprised. The old state arguments weren't freezing-in-time any instance values, so there shouldn't be any functionality change in the above.
createState: "test", | ||
cleanupState: "cleanup")); | ||
|
||
Assert.Contains("Failed to create or add connection", exception.Message); | ||
Assert.True(cleanupCalled); | ||
Assert.Equal(1, cleanupCallbackCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate check.
|
||
// Act | ||
var firstRemove = poolSlots.TryRemove(connection!); | ||
var secondRemove = poolSlots.TryRemove(connection2!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you check that ReservationCount is 1 here?
Description
This PR adds
Get
andReturn
functionality to the new ChannelDbConnectionPool class.A channel and corresponding channel reader and writer are added to underpin these operations.
An array is added to hold references to all connections managed by the pool.
Logic is included to respect max pool size in all cases.
Not included: pool warm up (including respecting min pool size), pool pruning, transactions, tracing/logs. These will come in follow-up PRs.
Also includes extensive unit test coverage for the implemented functionality. Integration testing is reserved for a later state when more of the pool functionality is available.
Issues
#3356
Testing
Tests focus on the Get and Return flows with special focus on the following: