Skip to content

Commit 5a7c78c

Browse files
committed
Respect ConnectTimeout when resetting connection. Fixes #1321
When a connection is opened by retrieving it from the pool, the Connect Timeout option should control how long the call to Open waits for a response from the server.
1 parent c318337 commit 5a7c78c

File tree

5 files changed

+30
-2
lines changed

5 files changed

+30
-2
lines changed

src/MySqlConnector/Core/ConnectionPool.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ internal sealed class ConnectionPool : IDisposable
1717

1818
public SslProtocols SslProtocols { get; set; }
1919

20-
public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection, int startTickCount, Activity? activity, IOBehavior ioBehavior, CancellationToken cancellationToken)
20+
public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection, int startTickCount, int timeoutMilliseconds, Activity? activity, IOBehavior ioBehavior, CancellationToken cancellationToken)
2121
{
2222
cancellationToken.ThrowIfCancellationRequested();
2323

@@ -65,9 +65,16 @@ public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection
6565
else
6666
{
6767
if (ConnectionSettings.ConnectionReset || session.DatabaseOverride is not null)
68+
{
69+
if (timeoutMilliseconds != 0)
70+
session.SetTimeout(Math.Max(1, timeoutMilliseconds - (Environment.TickCount - startTickCount)));
6871
reuseSession = await session.TryResetConnectionAsync(ConnectionSettings, connection, ioBehavior, cancellationToken).ConfigureAwait(false);
72+
session.SetTimeout(Constants.InfiniteTimeout);
73+
}
6974
else
75+
{
7076
reuseSession = true;
77+
}
7178
}
7279

7380
if (!reuseSession)

src/MySqlConnector/MySqlConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
926926
if (pool is not null)
927927
{
928928
// this returns an open session
929-
return await pool.GetSessionAsync(this, startTickCount, activity, actualIOBehavior, connectToken).ConfigureAwait(false);
929+
return await pool.GetSessionAsync(this, startTickCount, connectionSettings.ConnectionTimeoutMilliseconds, activity, actualIOBehavior, connectToken).ConfigureAwait(false);
930930
}
931931
else
932932
{

tests/MySqlConnector.Tests/ConnectionTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,21 @@ public void ConnectionTimeout()
203203
}
204204
}
205205

206+
[Fact]
207+
public void ResetConnectionTimeout()
208+
{
209+
var csb = new MySqlConnectionStringBuilder(m_csb.ConnectionString);
210+
csb.ConnectionTimeout = 4;
211+
using var connection = new MySqlConnection(csb.ConnectionString);
212+
connection.Open();
213+
connection.Close();
214+
m_server.ResetDelay = TimeSpan.FromSeconds(10);
215+
var stopwatch = Stopwatch.StartNew();
216+
var ex = Assert.Throws<MySqlException>(() => connection.Open());
217+
Assert.InRange(stopwatch.ElapsedMilliseconds, 3900, 4100);
218+
Assert.Equal(MySqlErrorCode.UnableToConnectToHost, (MySqlErrorCode) ex.Number);
219+
}
220+
206221
[Fact]
207222
public void ReadInfinity()
208223
{

tests/MySqlConnector.Tests/FakeMySqlServer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public void Stop()
5454
public bool SuppressAuthPluginNameTerminatingNull { get; set; }
5555
public bool SendIncompletePostHandshakeResponse { get; set; }
5656
public bool BlockOnConnect { get; set; }
57+
public TimeSpan? ResetDelay { get; set; }
5758

5859
internal void CancelQuery(int connectionId)
5960
{

tests/MySqlConnector.Tests/FakeMySqlServerConnection.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ public async Task RunAsync(TcpClient client, CancellationToken token)
6464
break;
6565

6666
case CommandKind.Ping:
67+
await SendAsync(stream, 1, WriteOk);
68+
break;
69+
6770
case CommandKind.ResetConnection:
71+
if (m_server.ResetDelay is { } resetDelay)
72+
await Task.Delay(resetDelay);
6873
await SendAsync(stream, 1, WriteOk);
6974
break;
7075

0 commit comments

Comments
 (0)