Skip to content

Commit

Permalink
Implement CloseAsync. Fixes #467
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrainger committed Jun 28, 2019
1 parent 32e3695 commit 7cad67e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
41 changes: 35 additions & 6 deletions src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public override void EnlistTransaction(System.Transactions.Transaction transacti
if (existingConnection != null)
{
// can reuse the existing connection
DoClose(changeState: false);
CloseAsync(changeState: false, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
TakeSessionFrom(existingConnection);
return;
}
Expand Down Expand Up @@ -225,7 +225,8 @@ private void TakeSessionFrom(MySqlConnection other)
EnlistedTransactionBase m_enlistedTransaction;
#endif

public override void Close() => DoClose(changeState: true);
public override void Close() => CloseAsync(changeState: true, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
public Task CloseAsync(CancellationToken cancellationToken = default) => CloseAsync(changeState: true, IOBehavior.Asynchronous, cancellationToken);

public override void ChangeDatabase(string databaseName) => ChangeDatabaseAsync(IOBehavior.Synchronous, databaseName, CancellationToken.None).GetAwaiter().GetResult();
public Task ChangeDatabaseAsync(string databaseName) => ChangeDatabaseAsync(IOBehavior.Asynchronous, databaseName, CancellationToken.None);
Expand Down Expand Up @@ -411,7 +412,7 @@ protected override void Dispose(bool disposing)
try
{
if (disposing)
DoClose(changeState: true);
CloseAsync(changeState: true, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
}
finally
{
Expand Down Expand Up @@ -645,12 +646,40 @@ private void VerifyNotDisposed()
throw new ObjectDisposedException(GetType().Name);
}

private void DoClose(bool changeState)
private Task CloseAsync(bool changeState, IOBehavior ioBehavior, CancellationToken cancellationToken)
{
if (m_connectionState == ConnectionState.Closed)
return Utility.CompletedTask;

// check fast path
if (m_activeReader is null &&
CurrentTransaction is null &&
#if !NETSTANDARD1_3
m_enlistedTransaction is null &&
#endif
m_connectionSettings.Pooling)
{
m_cachedProcedures = null;
if (m_session is object)
{
m_session.ReturnToPool();
m_session = null;
}
if (changeState)
SetState(ConnectionState.Closed);

return Utility.CompletedTask;
}

return DoCloseAsync(changeState, ioBehavior, cancellationToken);
}

private async Task DoCloseAsync(bool changeState, IOBehavior ioBehavior, CancellationToken cancellationToken)
{
#if !NETSTANDARD1_3
// If participating in a distributed transaction, keep the connection open so we can commit or rollback.
// This handles the common pattern of disposing a connection before disposing a TransactionScope (e.g., nested using blocks)
if (!(m_enlistedTransaction is null))
if (m_enlistedTransaction is object)
{
// make sure all DB work is done
m_activeReader?.Dispose();
Expand Down Expand Up @@ -701,7 +730,7 @@ private void DoClose(bool changeState)
if (m_connectionSettings.Pooling)
m_session.ReturnToPool();
else
m_session.DisposeAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
await m_session.DisposeAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
m_session = null;
}

Expand Down
19 changes: 19 additions & 0 deletions tests/MySqlConnector.Tests/ConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ public void PooledConnectionIsReturnedToPool()
Assert.Equal(1, m_server.ActiveConnections);
}

[Fact]
public async Task PooledConnectionIsReturnedToPoolAsync()
{
Assert.Equal(0, m_server.ActiveConnections);

m_csb.Pooling = true;
using (var connection = new MySqlConnection(m_csb.ConnectionString))
{
await connection.OpenAsync();
Assert.Equal(1, m_server.ActiveConnections);

Assert.Equal(m_server.ServerVersion, connection.ServerVersion);
await connection.CloseAsync();
Assert.Equal(1, m_server.ActiveConnections);
}

Assert.Equal(1, m_server.ActiveConnections);
}

[Fact]
public async Task UnpooledConnectionIsClosed()
{
Expand Down
2 changes: 2 additions & 0 deletions tests/SideBySide/ConnectAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public async Task State()
Assert.Equal(ConnectionState.Closed, connection.State);
await connection.OpenAsync();
Assert.Equal(ConnectionState.Open, connection.State);
await connection.CloseAsync();
Assert.Equal(ConnectionState.Closed, connection.State);
}
}

Expand Down

0 comments on commit 7cad67e

Please sign in to comment.