Skip to content

Commit 5313c56

Browse files
committed
defer awaiting connection reset
1 parent 56ccf87 commit 5313c56

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

src/MySqlConnector/MySqlClient/ConnectionPool.cs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,14 @@ public async Task<MySqlSession> GetSessionAsync(IOBehavior ioBehavior, Cancellat
2626
// check for a pooled session
2727
if (m_sessions.TryDequeue(out session))
2828
{
29-
if (session.PoolGeneration != m_generation || !await session.TryPingAsync(ioBehavior, cancellationToken).ConfigureAwait(false))
30-
{
31-
// session is either old or cannot communicate with the server
32-
await session.DisposeAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
33-
}
34-
else
29+
if (session.PoolGeneration == m_generation && await session.MakeActiveAsync(ioBehavior, cancellationToken).ConfigureAwait(false))
3530
{
3631
// pooled session is ready to be used; return it
3732
return session;
3833
}
34+
35+
// session is either old, failed to reset connection (if enabled), or cannot communicate with the server
36+
await session.DisposeAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
3937
}
4038

4139
session = new MySqlSession(this, m_generation);
@@ -51,28 +49,18 @@ public async Task<MySqlSession> GetSessionAsync(IOBehavior ioBehavior, Cancellat
5149

5250
public void Return(MySqlSession session)
5351
{
52+
// IO in this method MUST be synchronous, since it is triggered by MySqlConnection.Dispose. Async IO will cause lock-ups
5453
try
5554
{
56-
var success = false;
57-
5855
if (session.PoolGeneration == m_generation)
5956
{
60-
try
61-
{
62-
// reset the connection upon returning it to the pool
63-
if (m_connectionSettings.ConnectionReset)
64-
session.ResetConnectionAsync(m_connectionSettings, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
65-
success = true;
66-
}
67-
catch (MySqlException)
68-
{
69-
}
70-
}
71-
72-
if (success)
57+
session.MakeIdle(m_connectionSettings, IOBehavior.Synchronous, CancellationToken.None);
7358
m_sessions.Enqueue(session);
59+
}
7460
else
61+
{
7562
session.DisposeAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
63+
}
7664
}
7765
finally
7866
{

src/MySqlConnector/Serialization/MySqlSession.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,30 @@ public async Task ConnectAsync(ConnectionSettings cs, IOBehavior ioBehavior, Can
107107
m_payloadHandler = new CompressedPayloadHandler(m_payloadHandler.ByteHandler);
108108
}
109109

110-
public async Task ResetConnectionAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken)
110+
public void MakeIdle(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken)
111+
{
112+
if (cs.ConnectionReset)
113+
m_resetConnectionTask = ResetConnectionAsync(cs, ioBehavior, cancellationToken);
114+
}
115+
116+
public async Task<bool> MakeActiveAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
117+
{
118+
if (m_resetConnectionTask != null)
119+
{
120+
try
121+
{
122+
await m_resetConnectionTask.ConfigureAwait(false);
123+
}
124+
catch (MySqlException)
125+
{
126+
return false;
127+
}
128+
}
129+
130+
return await TryPingAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
131+
}
132+
133+
private async Task ResetConnectionAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken)
111134
{
112135
if (ServerVersion.Version.CompareTo(ServerVersions.SupportsResetConnection) >= 0)
113136
{
@@ -143,7 +166,7 @@ public async Task ResetConnectionAsync(ConnectionSettings cs, IOBehavior ioBehav
143166
}
144167
}
145168

146-
public async Task<bool> TryPingAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
169+
private async Task<bool> TryPingAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
147170
{
148171
// check if client socket is still connected
149172
// http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c
@@ -510,5 +533,6 @@ private enum State
510533
Socket m_socket;
511534
NetworkStream m_networkStream;
512535
IPayloadHandler m_payloadHandler;
536+
Task m_resetConnectionTask;
513537
}
514538
}

0 commit comments

Comments
 (0)