Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -36,7 +36,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Core" />
<PackageReference Include="System.Text.Encodings.Web" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this related to adding stress tests for the connection pool?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the scoop with these package removals? Have the transitive problems been solved somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clean these up. Visual studio was complaining, so I did this to appease it. I think it was just holding on to stale partial build state.

<PackageReference Include="Azure.Security.KeyVault.Keys" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@
<PackageReference Include="Microsoft.SqlServer.Server" />
<PackageReference Include="System.Configuration.ConfigurationManager" />
<PackageReference Include="System.Security.Cryptography.Pkcs" />

<!-- Transitive dependencies that would otherwise bring in older, vulnerable versions. -->
<PackageReference Include="System.Text.Json" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want our ref packages to have the same references as the implementation packages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clean these up as part of DRI this sprint. Had to include them here to get some build errors addressed.

</ItemGroup>

<!-- netstandard dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,6 @@
<PackageReference Include="Microsoft.SqlServer.Server" />
<PackageReference Include="System.Configuration.ConfigurationManager" />
<PackageReference Include="System.Security.Cryptography.Pkcs" />

<!-- Transitive dependencies that would otherwise bring in older, vulnerable versions. -->
<PackageReference Include="System.Text.Json" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These packages were likely removed due to pruning errors in Visual Studio. This issue has been addressed in #3686, so merging this branch with main should resolve it.

</ItemGroup>

<Import Project="$(ToolsDir)targets\GenerateThisAssemblyCs.targets" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ internal ChannelDbConnectionPool(
Identity = identity;
AuthenticationContexts = new();
MaxPoolSize = Convert.ToUInt32(PoolGroupOptions.MaxPoolSize);
TransactedConnectionPool = new(this);

_connectionSlots = new(MaxPoolSize);

Expand Down Expand Up @@ -147,6 +148,9 @@ public ConcurrentDictionary<
/// <inheritdoc />
public DbConnectionPoolState State { get; private set; }

/// <inheritdoc />
public TransactedConnectionPool TransactedConnectionPool { get; }

/// <inheritdoc />
public bool UseLoadBalancing => PoolGroupOptions.UseLoadBalancing;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ bool hasTransactionAffinity
_hasTransactionAffinity = hasTransactionAffinity;
}

/// <summary>
/// The time (in milliseconds) to wait for a connection to be created/returned before terminating the attempt.
/// </summary>
public int CreationTimeout
{
get { return _creationTimeout; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ internal interface IDbConnectionPool
/// </summary>
DbConnectionPoolState State { get; }

/// <summary>
/// Holds connections that are currently enlisted in a transaction.
/// </summary>
TransactedConnectionPool TransactedConnectionPool { get; }

/// <summary>
/// Indicates whether the connection pool is using load balancing.
/// </summary>
Expand All @@ -106,7 +111,7 @@ internal interface IDbConnectionPool
/// <param name="userOptions">The user options to use if a new connection must be opened.</param>
/// <param name="connection">The retrieved connection will be passed out via this parameter.</param>
/// <returns>True if a connection was set in the out parameter, otherwise returns false.</returns>
bool TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal> taskCompletionSource, DbConnectionOptions userOptions, out DbConnectionInternal? connection);
bool TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal>? taskCompletionSource, DbConnectionOptions userOptions, out DbConnectionInternal? connection);

/// <summary>
/// Replaces the internal connection currently associated with owningObject with a new internal connection from the pool.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal class TransactedConnectionPool
/// A specialized list that holds database connections associated with a specific transaction.
/// Maintains a reference to the transaction for proper cleanup when the transaction completes.
/// </summary>
private sealed class TransactedConnectionList : List<DbConnectionInternal>
internal sealed class TransactedConnectionList : List<DbConnectionInternal>
{
private readonly Transaction _transaction;

Expand Down Expand Up @@ -59,9 +59,6 @@ internal void Dispose()
}

#region Fields

private readonly Dictionary<Transaction, TransactedConnectionList> _transactedCxns;

private static int _objectTypeCount;
internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);

Expand All @@ -79,7 +76,7 @@ internal void Dispose()
internal TransactedConnectionPool(IDbConnectionPool pool)
{
Pool = pool;
_transactedCxns = new Dictionary<Transaction, TransactedConnectionList>();
TransactedConnections = new Dictionary<Transaction, TransactedConnectionList>();
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.TransactedConnectionPool.TransactedConnectionPool|RES|CPOOL> {0}, Constructed for connection pool {1}", Id, Pool.Id);
}

Expand All @@ -97,6 +94,8 @@ internal TransactedConnectionPool(IDbConnectionPool pool)
/// <value>The IDbConnectionPool instance that owns this transacted pool.</value>
internal IDbConnectionPool Pool { get; }

internal Dictionary<Transaction, TransactedConnectionList> TransactedConnections { get; private set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need private set here.


#endregion

#region Methods
Expand All @@ -122,9 +121,9 @@ internal TransactedConnectionPool(IDbConnectionPool pool)
TransactedConnectionList? connections;
bool txnFound = false;

lock (_transactedCxns)
lock (TransactedConnections)
{
txnFound = _transactedCxns.TryGetValue(transaction, out connections);
txnFound = TransactedConnections.TryGetValue(transaction, out connections);
}

// NOTE: GetTransactedObject is only used when AutoEnlist = True and the ambient transaction
Expand Down Expand Up @@ -181,10 +180,10 @@ internal void PutTransactedObject(Transaction transaction, DbConnectionInternal
// NOTE: because TransactionEnded is an asynchronous notification, there's no guarantee
// around the order in which PutTransactionObject and TransactionEnded are called.

lock (_transactedCxns)
lock (TransactedConnections)
{
// Check if a transacted pool has been created for this transaction
if ((txnFound = _transactedCxns.TryGetValue(transaction, out connections))
if ((txnFound = TransactedConnections.TryGetValue(transaction, out connections))
&& connections is not null)
{
// synchronize multi-threaded access with GetTransactedObject
Expand Down Expand Up @@ -212,14 +211,14 @@ internal void PutTransactedObject(Transaction transaction, DbConnectionInternal
transactionClone = transaction.Clone();
newConnections = new TransactedConnectionList(2, transactionClone); // start with only two connections in the list; most times we won't need that many.

lock (_transactedCxns)
lock (TransactedConnections)
{
// NOTE: in the interim between the locks on the transacted pool (this) during
// execution of this method, another thread (threadB) may have attempted to
// add a different connection to the transacted pool under the same
// transaction. As a result, threadB may have completed creating the
// transacted pool while threadA was processing the above instructions.
if (_transactedCxns.TryGetValue(transaction, out connections)
if (TransactedConnections.TryGetValue(transaction, out connections)
&& connections is not null)
{
// synchronize multi-threaded access with GetTransactedObject
Expand All @@ -237,7 +236,7 @@ internal void PutTransactedObject(Transaction transaction, DbConnectionInternal
// add the connection/transacted object to the list
newConnections.Add(transactedObject);

_transactedCxns.Add(transactionClone, newConnections);
TransactedConnections.Add(transactionClone, newConnections);
transactionClone = null; // we've used it -- don't throw it or the TransactedConnectionList that references it away.
}
}
Expand Down Expand Up @@ -296,9 +295,9 @@ internal void TransactionEnded(Transaction transaction, DbConnectionInternal tra
// TODO: that the pending creation of a transacted pool for this transaction is aborted when
// TODO: PutTransactedObject finally gets some CPU time?

lock (_transactedCxns)
lock (TransactedConnections)
{
if (_transactedCxns.TryGetValue(transaction, out connections)
if (TransactedConnections.TryGetValue(transaction, out connections)
&& connections is not null)
{
bool shouldDisposeConnections = false;
Expand All @@ -318,7 +317,7 @@ internal void TransactionEnded(Transaction transaction, DbConnectionInternal tra
if (0 >= connections.Count)
{
SqlClientEventSource.Log.TryPoolerTraceEvent("<prov.DbConnectionPool.TransactedConnectionPool.TransactionEnded|RES|CPOOL> {0}, Transaction {1}, Removing List from transacted pool.", Id, transaction.GetHashCode());
_transactedCxns.Remove(transaction);
TransactedConnections.Remove(transaction);

// we really need to dispose our connection list; it may have
// native resources via the tx and GC may not happen soon enough.
Expand Down Expand Up @@ -350,4 +349,4 @@ internal void TransactionEnded(Transaction transaction, DbConnectionInternal tra
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,9 @@ public bool IsRunning
get { return State is Running; }
}

private int MaxPoolSize => PoolGroupOptions.MaxPoolSize;
internal int MaxPoolSize => PoolGroupOptions.MaxPoolSize;

private int MinPoolSize => PoolGroupOptions.MinPoolSize;
internal int MinPoolSize => PoolGroupOptions.MinPoolSize;

public DbConnectionPoolGroup PoolGroup => _connectionPoolGroup;

Expand All @@ -328,6 +328,8 @@ public bool IsRunning

private bool UsingIntegrateSecurity => _identity != null && DbConnectionPoolIdentity.NoIdentity != _identity;

public TransactedConnectionPool TransactedConnectionPool => _transactedConnectionPool;

private void CleanupCallback(object state)
{
// Called when the cleanup-timer ticks over.
Expand Down Expand Up @@ -946,6 +948,8 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj

// If automatic transaction enlistment is required, then we try to
// get the connection from the transacted connection pool first.
// If automatic enlistment is not enabled, then we cannot vend connections
// from the transacted pool.
if (HasTransactionAffinity)
{
obj = GetFromTransactedPool(out transaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,13 +668,14 @@ internal class MockDbConnectionPool : IDbConnectionPool
public DbConnectionPoolGroupOptions PoolGroupOptions => throw new NotImplementedException();
public DbConnectionPoolProviderInfo ProviderInfo => throw new NotImplementedException();
public DbConnectionPoolState State => throw new NotImplementedException();
public TransactedConnectionPool TransactedConnectionPool => throw new NotImplementedException();
public bool UseLoadBalancing => throw new NotImplementedException();

public ConcurrentBag<DbConnectionInternal> ReturnedConnections { get; } = new();

public void Clear() => throw new NotImplementedException();

public bool TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal> taskCompletionSource, DbConnectionOptions userOptions, out DbConnectionInternal? connection)
public bool TryGetConnection(DbConnection owningObject, TaskCompletionSource<DbConnectionInternal>? taskCompletionSource, DbConnectionOptions userOptions, out DbConnectionInternal? connection)
{
throw new NotImplementedException();
}
Expand Down Expand Up @@ -739,4 +740,4 @@ internal override void ResetConnection()
}

#endregion
}
}
Loading
Loading