Skip to content

New pool scaffolding #3352

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

Merged
merged 19 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@
<Compile Include="$(CommonSourceRoot)\Microsoft\Data\ProviderBase\DbConnectionFactory.cs">
<Link>Microsoft\Data\ProviderBase\DbConnectionFactory.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPool.cs</Link>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs</Link>
Expand Down Expand Up @@ -125,8 +125,8 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolState.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolState.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs</Link>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\IDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\IDbConnectionPool.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs</Link>
Expand All @@ -137,6 +137,9 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbMetaDataFactory.cs">
<Link>Microsoft\Data\ProviderBase\DbMetaDataFactory.cs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ override public DbProviderFactory ProviderFactory
}
}

override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, IDbConnectionPool pool, DbConnection owningConnection)
{
return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null);
}

override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, IDbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
{
SqlConnectionString opt = (SqlConnectionString)options;
SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ internal bool IsDNSCachingBeforeRedirectSupported
internal byte _tceVersionSupported;

// The pool that this connection is associated with, if at all it is.
private DbConnectionPool _dbConnectionPool;
private IDbConnectionPool _dbConnectionPool;

// This is used to preserve the authentication context object if we decide to cache it for subsequent connections in the same pool.
// This will finally end up in _dbConnectionPool.AuthenticationContexts, but only after 1 successful login to SQL Server using this context.
Expand Down Expand Up @@ -453,7 +453,7 @@ internal SqlInternalConnectionTds(
SessionData reconnectSessionData = null,
bool applyTransientFaultHandling = false,
string accessToken = null,
DbConnectionPool pool = null,
IDbConnectionPool pool = null,
Func<SqlAuthenticationParameters, CancellationToken,
Task<SqlAuthenticationToken>> accessTokenCallback = null) : base(connectionOptions)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\ProviderBase\DbConnectionInternal.cs">
<Link>Microsoft\Data\ProviderBase\DbConnectionInternal.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPool.cs</Link>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs</Link>
Expand Down Expand Up @@ -312,8 +312,8 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolState.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolState.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs</Link>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\IDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\IDbConnectionPool.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs</Link>
Expand All @@ -324,6 +324,9 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs">
<Link>Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\Diagnostics\SqlClientMetrics.cs">
<Link>Microsoft\Data\SqlClient\Diagnostics\SqlClientMetrics.cs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ override public DbProviderFactory ProviderFactory
}
}

override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, IDbConnectionPool pool, DbConnection owningConnection)
{
return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null);
}

override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, IDbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
{
SqlConnectionString opt = (SqlConnectionString)options;
SqlConnectionPoolKey key = (SqlConnectionPoolKey)poolKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ internal bool IsDNSCachingBeforeRedirectSupported
internal byte _tceVersionSupported;

// The pool that this connection is associated with, if at all it is.
private DbConnectionPool _dbConnectionPool;
private IDbConnectionPool _dbConnectionPool;

// This is used to preserve the authentication context object if we decide to cache it for subsequent connections in the same pool.
// This will finally end up in _dbConnectionPool.AuthenticationContexts, but only after 1 successful login to SQL Server using this context.
Expand Down Expand Up @@ -464,7 +464,7 @@ internal SqlInternalConnectionTds(
SessionData reconnectSessionData = null,
bool applyTransientFaultHandling = false,
string accessToken = null,
DbConnectionPool pool = null,
IDbConnectionPool pool = null,
Func<SqlAuthenticationParameters, CancellationToken,
Task<SqlAuthenticationToken>> accessTokenCallback = null) : base(connectionOptions)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<Reference Include="System.Configuration" Condition="'$(TargetFramework)' == 'net462'"/>
<Reference Include="System.Configuration" Condition="'$(TargetFramework)' == 'net462'" />
<Reference Include="System.Transactions" Condition="'$(TargetFramework)' == 'net462'" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft.Data.ProviderBase
internal abstract class DbConnectionFactory
{
private Dictionary<DbConnectionPoolKey, DbConnectionPoolGroup> _connectionPoolGroups;
private readonly List<DbConnectionPool> _poolsToRelease;
private readonly List<IDbConnectionPool> _poolsToRelease;
private readonly List<DbConnectionPoolGroup> _poolGroupsToRelease;
private readonly Timer _pruningTimer;

Expand All @@ -37,7 +37,7 @@ internal abstract class DbConnectionFactory
protected DbConnectionFactory()
{
_connectionPoolGroups = new Dictionary<DbConnectionPoolKey, DbConnectionPoolGroup>();
_poolsToRelease = new List<DbConnectionPool>();
_poolsToRelease = new List<IDbConnectionPool>();
_poolGroupsToRelease = new List<DbConnectionPoolGroup>();
_pruningTimer = CreatePruningTimer();
}
Expand Down Expand Up @@ -122,7 +122,7 @@ internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConne
return newConnection;
}

internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
internal DbConnectionInternal CreatePooledConnection(IDbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
{
Debug.Assert(pool != null, "null pool?");
DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo;
Expand Down Expand Up @@ -176,7 +176,7 @@ internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSour
Debug.Assert(owningConnection != null, "null owningConnection?");

DbConnectionPoolGroup poolGroup;
DbConnectionPool connectionPool;
IDbConnectionPool connectionPool;
connection = null;

// Work around race condition with clearing the pool between GetConnectionPool obtaining pool
Expand Down Expand Up @@ -371,7 +371,7 @@ private void TryGetConnectionCompletedContinuation(Task<DbConnectionInternal> ta
}
}

private DbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup)
private IDbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup)
{
// if poolgroup is disabled, it will be replaced with a new entry

Expand Down Expand Up @@ -402,7 +402,7 @@ private DbConnectionPool GetConnectionPool(DbConnection owningObject, DbConnecti
Debug.Assert(connectionPoolGroup != null, "null connectionPoolGroup?");
SetConnectionPoolGroup(owningObject, connectionPoolGroup);
}
DbConnectionPool connectionPool = connectionPoolGroup.GetConnectionPool(this);
IDbConnectionPool connectionPool = connectionPoolGroup.GetConnectionPool(this);
return connectionPool;
}

Expand Down Expand Up @@ -530,8 +530,8 @@ private void PruneConnectionPoolGroups(object state)
{
if (0 != _poolsToRelease.Count)
{
DbConnectionPool[] poolsToRelease = _poolsToRelease.ToArray();
foreach (DbConnectionPool pool in poolsToRelease)
IDbConnectionPool[] poolsToRelease = _poolsToRelease.ToArray();
foreach (IDbConnectionPool pool in poolsToRelease)
{
if (pool != null)
{
Expand Down Expand Up @@ -607,7 +607,7 @@ private void PruneConnectionPoolGroups(object state)
}
}

internal void QueuePoolForRelease(DbConnectionPool pool, bool clearing)
internal void QueuePoolForRelease(IDbConnectionPool pool, bool clearing)
{
// Queue the pool up for release -- we'll clear it out and dispose
// of it as the last part of the pruning timer callback so we don't
Expand Down Expand Up @@ -645,12 +645,12 @@ internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup)
SqlClientEventSource.Metrics.ExitActiveConnectionPoolGroup();
}

virtual protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
virtual protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, IDbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
{
return CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection);
}

abstract protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection);
abstract protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, IDbConnectionPool pool, DbConnection owningConnection);

abstract protected DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ internal bool IsEmancipated
{
// NOTE: There are race conditions between PrePush, PostPop and this
// property getter -- only use this while this object is locked;
// (DbConnectionPool.Clear and ReclaimEmancipatedObjects
// (IDbConnectionPool.Clear and ReclaimEmancipatedObjects
// do this for us)

// The functionality is as follows:
Expand Down Expand Up @@ -157,7 +157,7 @@ internal bool IsInPool
/// <summary>
/// The pooler that the connection came from (Pooled connections only)
/// </summary>
internal DbConnectionPool Pool { get; private set; }
internal IDbConnectionPool Pool { get; private set; }

public abstract string ServerVersion { get; }

Expand Down Expand Up @@ -393,7 +393,7 @@ internal void CleanupConnectionOnTransactionCompletion(Transaction transaction)
{
DetachTransaction(transaction, false);

DbConnectionPool pool = Pool;
IDbConnectionPool pool = Pool;
pool?.TransactionEnded(transaction, this);
}

Expand Down Expand Up @@ -454,7 +454,7 @@ internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFac
{
PrepareForCloseConnection();

DbConnectionPool connectionPool = Pool;
IDbConnectionPool connectionPool = Pool;

// Detach from enlisted transactions that are no longer active on close
DetachCurrentTransactionIfEnded();
Expand All @@ -464,10 +464,10 @@ internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFac
// into the pool.
if (connectionPool is not null)
{
// PutObject calls Deactivate for us...
connectionPool.PutObject(this, owningObject);
// ReturnInternalConnection calls Deactivate for us...
connectionPool.ReturnInternalConnection(this, owningObject);

// NOTE: Before we leave the PutObject call, another thread may have
// NOTE: Before we leave the ReturnInternalConnection call, another thread may have
// already popped the connection from the pool, so don't expect to be
// able to verify it.
}
Expand Down Expand Up @@ -558,7 +558,7 @@ internal virtual void DelegatedTransactionEnded()

Deactivate(); // call it one more time just in case

DbConnectionPool pool = Pool;
IDbConnectionPool pool = Pool;

if (pool == null)
{
Expand Down Expand Up @@ -698,7 +698,7 @@ internal void MakeNonPooledObject(DbConnection owningObject)
/// Used by DbConnectionFactory to indicate that this object IS part of a connection pool.
/// </summary>
/// <param name="connectionPool"></param>
internal void MakePooledConnection(DbConnectionPool connectionPool)
internal void MakePooledConnection(IDbConnectionPool connectionPool)
{
_createTime = DateTime.UtcNow;
Pool = connectionPool;
Expand All @@ -717,7 +717,7 @@ internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionF

internal void PostPop(DbConnection newOwner)
{
// Called by DbConnectionPool right after it pulls this from its pool, we take this
// Called by IDbConnectionPool right after it pulls this from its pool, we take this
// opportunity to ensure ownership and pool counts are legit.
Debug.Assert(!IsEmancipated, "pooled object not in pool");

Expand Down Expand Up @@ -757,7 +757,7 @@ internal virtual void PrepareForReplaceConnection()

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

// IMPORTANT NOTE: You must have taken a lock on the object before you call this method
Expand Down
Loading
Loading