Skip to content

Commit

Permalink
Use user-provided callbacks when cancelling. Fixes #1179
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrainger committed Aug 28, 2022
1 parent eb16b3d commit 5a15fc0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/MySqlConnector/MySqlConnection.cs
Expand Up @@ -767,7 +767,12 @@ internal void Cancel(ICancellableCommand command, int commandId, bool isCancel)
var cancellationTimeout = GetConnectionSettings().CancellationTimeout;
csb.ConnectionTimeout = cancellationTimeout < 1 ? 3u : (uint) cancellationTimeout;

using var connection = new MySqlConnection(csb.ConnectionString);
using var connection = new MySqlConnection(csb.ConnectionString)
{
ProvideClientCertificatesCallback = ProvideClientCertificatesCallback,
ProvidePasswordCallback = ProvidePasswordCallback,
RemoteCertificateValidationCallback = RemoteCertificateValidationCallback,
};
connection.Open();
using var killCommand = new MySqlCommand("KILL QUERY {0}".FormatInvariant(command.Connection!.ServerThread), connection);
killCommand.CommandTimeout = cancellationTimeout < 1 ? 3 : cancellationTimeout;
Expand Down
43 changes: 43 additions & 0 deletions tests/SideBySide/CancelTests.cs
Expand Up @@ -38,6 +38,49 @@ public void CancelCommand()
task.Wait(); // shouldn't throw
}

[SkippableFact(ServerFeatures.CancelSleepSuccessfully)]
public async Task CancelCommandWithPasswordCallback()
{
var csb = AppConfig.CreateConnectionStringBuilder();
var password = csb.Password;
csb.Password = null;
using var connection = new MySqlConnection(csb.ConnectionString)
{
ProvidePasswordCallback = _ => password,
};
await connection.OpenAsync();
using var command = new MySqlCommand("SELECT SLEEP(5)", connection);
var task = Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(0.5));
command.Cancel();
});

var stopwatch = Stopwatch.StartNew();
TestUtilities.AssertIsOne(await command.ExecuteScalarAsync());
Assert.InRange(stopwatch.ElapsedMilliseconds, 250, 2500);

task.Wait(); // shouldn't throw
}

[SkippableFact(ServerFeatures.CancelSleepSuccessfully)]
public async Task CancelCommandCancellationTokenWithPasswordCallback()
{
var csb = AppConfig.CreateConnectionStringBuilder();
var password = csb.Password;
csb.Password = null;
using var connection = new MySqlConnection(csb.ConnectionString)
{
ProvidePasswordCallback = _ => password,
};
await connection.OpenAsync();
using var command = new MySqlCommand("SELECT SLEEP(5)", connection);
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(500));
var stopwatch = Stopwatch.StartNew();
TestUtilities.AssertIsOne(await command.ExecuteScalarAsync(cts.Token));
Assert.InRange(stopwatch.ElapsedMilliseconds, 250, 2500);
}

[SkippableFact(ServerFeatures.StreamingResults | ServerFeatures.Timeout)]
public void CancelReaderAsynchronously()
{
Expand Down

0 comments on commit 5a15fc0

Please sign in to comment.