Skip to content

Commit 8237bb6

Browse files
committed
Only create CancellationTokenSource if needed.
This reduces allocations if the user explicitly uses 'ConnectionTimeout=0' in the connection string, or if Open or the non-cancellable OpenAsync is called, or both.
1 parent a59b39d commit 8237bb6

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnection.cs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -377,35 +377,45 @@ private async ValueTask<ServerSession> CreateSessionAsync(IOBehavior? ioBehavior
377377
m_connectionSettings = pool?.ConnectionSettings ?? new ConnectionSettings(new MySqlConnectionStringBuilder(m_connectionString));
378378
var actualIOBehavior = ioBehavior ?? (m_connectionSettings.ForceSynchronous ? IOBehavior.Synchronous : IOBehavior.Asynchronous);
379379

380-
var connectTimeout = m_connectionSettings.ConnectionTimeout == 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromMilliseconds(m_connectionSettings.ConnectionTimeoutMilliseconds);
381-
using (var timeoutSource = new CancellationTokenSource(connectTimeout))
382-
using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutSource.Token))
380+
CancellationTokenSource timeoutSource = null;
381+
CancellationTokenSource linkedSource = null;
382+
try
383383
{
384-
try
384+
// the cancellation token for connection is controlled by 'cancellationToken' (if it can be cancelled), ConnectionTimeout
385+
// (from the connection string, if non-zero), or a combination of both
386+
if (m_connectionSettings.ConnectionTimeout != 0)
387+
timeoutSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(m_connectionSettings.ConnectionTimeoutMilliseconds));
388+
if (cancellationToken.CanBeCanceled && timeoutSource != null)
389+
linkedSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutSource.Token);
390+
var connectToken = linkedSource?.Token ?? timeoutSource?.Token ?? cancellationToken;
391+
392+
// get existing session from the pool if possible
393+
if (pool != null)
385394
{
386-
// get existing session from the pool if possible
387-
if (pool != null)
388-
{
389-
// this returns an open session
390-
return await pool.GetSessionAsync(this, actualIOBehavior, linkedSource.Token).ConfigureAwait(false);
391-
}
392-
else
393-
{
394-
// only "fail over" and "random" load balancers supported without connection pooling
395-
var loadBalancer = m_connectionSettings.LoadBalance == MySqlLoadBalance.Random && m_connectionSettings.HostNames.Count > 1 ?
396-
RandomLoadBalancer.Instance : FailOverLoadBalancer.Instance;
397-
398-
var session = new ServerSession();
399-
Log.Info("Created new non-pooled Session{0}", session.Id);
400-
await session.ConnectAsync(m_connectionSettings, loadBalancer, actualIOBehavior, linkedSource.Token).ConfigureAwait(false);
401-
return session;
402-
}
395+
// this returns an open session
396+
return await pool.GetSessionAsync(this, actualIOBehavior, connectToken).ConfigureAwait(false);
403397
}
404-
catch (OperationCanceledException ex) when (timeoutSource.IsCancellationRequested)
398+
else
405399
{
406-
throw new MySqlException("Connect Timeout expired.", ex);
400+
// only "fail over" and "random" load balancers supported without connection pooling
401+
var loadBalancer = m_connectionSettings.LoadBalance == MySqlLoadBalance.Random && m_connectionSettings.HostNames.Count > 1 ?
402+
RandomLoadBalancer.Instance : FailOverLoadBalancer.Instance;
403+
404+
var session = new ServerSession();
405+
Log.Info("Created new non-pooled Session{0}", session.Id);
406+
await session.ConnectAsync(m_connectionSettings, loadBalancer, actualIOBehavior, connectToken).ConfigureAwait(false);
407+
return session;
407408
}
408409
}
410+
catch (OperationCanceledException ex) when (timeoutSource.IsCancellationRequested)
411+
{
412+
throw new MySqlException("Connect Timeout expired.", ex);
413+
}
414+
finally
415+
{
416+
linkedSource?.Dispose();
417+
timeoutSource?.Dispose();
418+
}
409419
}
410420

411421
internal bool SslIsEncrypted => m_session.SslIsEncrypted;

0 commit comments

Comments
 (0)