Skip to content

Commit 22b233b

Browse files
authored
Get/Return pooled connections (#3404)
* Add get flow and basic tests. * Add tests. Clean up diff. * Add additional tests. Refactor to test error behavior. * Implement return flow and add return/reuse tests. * Clean up comments and todos. * Add test cases. * Enable init property accessor in netfx. * Switch to auto properties. * Reorder class members. * Address review comments. * Fix channels package resolution. * Review changes. * Set CreateTime in constructor. This makes sense becuase CreateTime cannot be modified and should be set regardless of pooling status. * Naming * Fix potential connection leak when setting TaskCompletionSource result. * Fix package reference for central package management. * Fix formatting. Refactor get connection loop. * Move concurrent data structures out to dedicated class. * Refactor data structure to remove generics, revert to previous logic. * Cleanup * Fix timeout exception handling for async path. * Review comments. Fix merge conflict. * Change object reference to full type. Fix tab. * cleanup * Add link to github issue for async pathways. * Remove side effects from IsLiveConnection. Fix exception handling and connection disposal when opening new connection. * Minor review feedback. Make tests more reliable. * Fix compilation * Make reservation disposable. * Fix tests * Make async request order test more reliable. * Avoid confusing double reservation release. Use params in callbacks to avoid closures. * Doc comment cleanup. Add unit tests for ConnectionPoolSlots. * Fix up tests * Clean up unit test proj file. * Make disposal safer. Clean up exception documentation. * Improve tests. * Clean up wrapped exceptions. Fix param nullability. * Clean up tests based on new editorconfig settings. * Review changes. * Fix tests to expect unwrapped exception.
1 parent c68da22 commit 22b233b

18 files changed

+2020
-97
lines changed

src/Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<PackageVersion Include="System.Memory" Version="4.6.3" />
101101
<PackageVersion Include="System.Text.Encodings.Web" Version="8.0.0" />
102102
<PackageVersion Include="System.ValueTuple" Version="4.6.1" />
103+
<PackageVersion Include="System.Threading.Channels" Version="8.0.0" />
103104
</ItemGroup>
104105

105106
<!-- =================================================================== -->

src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
<!-- Transitive dependencies that would otherwise bring in older, vulnerable versions. -->
4747
<PackageReference Include="System.Text.Json" />
4848
</ItemGroup>
49+
50+
<!-- netstandard dependencies -->
51+
<ItemGroup Condition="'$(TargetGroup)' != 'netcoreapp'">
52+
<PackageReference Include="System.Threading.Channels" />
53+
</ItemGroup>
4954

5055
<Import Project="$(ToolsDir)targets\ResolveContract.targets" Condition="'$(OSGroup)' == 'AnyOS' AND '$(TargetGroup)' != 'netcoreapp'" />
5156
<Import Project="$(ToolsDir)targets\NotSupported.targets" Condition="'$(OSGroup)' == 'AnyOS' AND '$(TargetGroup)' != 'netcoreapp'" />

src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@
108108
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs">
109109
<Link>Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs</Link>
110110
</Compile>
111+
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\ConnectionPoolSlots.cs">
112+
<Link>Microsoft\Data\SqlClient\ConnectionPool\ConnectionPoolSlots.cs</Link>
113+
</Compile>
111114
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs">
112115
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs</Link>
113116
</Compile>

src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<PackageReference Include="System.Security.Cryptography.Pkcs" />
4949
<PackageReference Include="System.Text.Encodings.Web" />
5050
<PackageReference Include="System.Text.Json" />
51+
<PackageReference Include="System.Threading.Channels" />
5152
</ItemGroup>
5253
<Import Project="$(ToolsDir)targets\TrimDocsForIntelliSense.targets" />
5354
</Project>

src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@
300300
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs">
301301
<Link>Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs</Link>
302302
</Compile>
303+
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\ConnectionPoolSlots.cs">
304+
<Link>Microsoft\Data\SqlClient\ConnectionPool\ConnectionPoolSlots.cs</Link>
305+
</Compile>
303306
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs">
304307
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs</Link>
305308
</Compile>
@@ -1058,6 +1061,7 @@
10581061
<PackageReference Include="System.Text.Encodings.Web" />
10591062
<PackageReference Include="System.Text.Json" />
10601063
<PackageReference Include="System.ValueTuple" />
1064+
<PackageReference Include="System.Threading.Channels" />
10611065
</ItemGroup>
10621066
<Import Project="$(CommonSourceRoot)tools\targets\GenerateResourceStringsSource.targets" />
10631067
<Import Project="$(NetFxSource)tools\targets\GenerateThisAssemblyCs.targets" />

src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@
2626
<Reference Include="System.Transactions" />
2727
<PackageReference Include="System.Data.Common" />
2828
<PackageReference Include="System.ValueTuple" />
29-
</ItemGroup>
29+
<PackageReference Include="System.Threading.Channels" />
30+
</ItemGroup>
3031
</Project>

src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ internal abstract class DbConnectionInternal
4646
/// </summary>
4747
private bool _cannotBePooled;
4848

49-
/// <summary>
50-
/// When the connection was created.
51-
/// </summary>
52-
private DateTime _createTime;
53-
5449
/// <summary>
5550
/// [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically.
5651
/// </summary>
@@ -93,10 +88,16 @@ internal DbConnectionInternal(ConnectionState state, bool hidePassword, bool all
9388
AllowSetConnectionString = allowSetConnectionString;
9489
ShouldHidePassword = hidePassword;
9590
State = state;
91+
CreateTime = DateTime.UtcNow;
9692
}
9793

9894
#region Properties
9995

96+
/// <summary>
97+
/// When the connection was created.
98+
/// </summary>
99+
internal DateTime CreateTime { get; }
100+
100101
internal bool AllowSetConnectionString { get; }
101102

102103
internal bool CanBePooled => !IsConnectionDoomed && !_cannotBePooled && !_owningObject.TryGetTarget(out _);
@@ -542,7 +543,7 @@ internal void DeactivateConnection()
542543
// If we're not already doomed, check the connection's lifetime and
543544
// doom it if it's lifetime has elapsed.
544545
DateTime now = DateTime.UtcNow;
545-
if (now.Ticks - _createTime.Ticks > Pool.LoadBalanceTimeout.Ticks)
546+
if (now.Ticks - CreateTime.Ticks > Pool.LoadBalanceTimeout.Ticks)
546547
{
547548
DoNotPoolThisConnection();
548549
}
@@ -712,7 +713,6 @@ internal void MakeNonPooledObject(DbConnection owningObject)
712713
/// <param name="connectionPool"></param>
713714
internal void MakePooledConnection(IDbConnectionPool connectionPool)
714715
{
715-
_createTime = DateTime.UtcNow;
716716
Pool = connectionPool;
717717
}
718718

@@ -767,7 +767,7 @@ internal virtual void PrepareForReplaceConnection()
767767
// By default, there is no preparation required
768768
}
769769

770-
internal void PrePush(object expectedOwner)
770+
internal void PrePush(DbConnection expectedOwner)
771771
{
772772
// Called by IDbConnectionPool when we're about to be put into it's pool, we take this
773773
// opportunity to ensure ownership and pool counts are legit.

0 commit comments

Comments
 (0)