Skip to content

Commit

Permalink
Avoid Task<MySqlDataReader> allocation on sync path.
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrainger committed Aug 13, 2023
1 parent 3f5b286 commit 016657a
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/MySqlConnector/Core/CommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace MySqlConnector.Core;

internal static class CommandExecutor
{
public static async Task<MySqlDataReader> ExecuteReaderAsync(IReadOnlyList<IMySqlCommand> commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity? activity, IOBehavior ioBehavior, CancellationToken cancellationToken)
public static async ValueTask<MySqlDataReader> ExecuteReaderAsync(IReadOnlyList<IMySqlCommand> commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity? activity, IOBehavior ioBehavior, CancellationToken cancellationToken)
{
try
{
Expand Down
8 changes: 5 additions & 3 deletions src/MySqlConnector/MySqlBatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ private DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
#endif
{
this.ResetCommandTimeout();
return ExecuteReaderAsync(behavior, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
#pragma warning disable CA2012 // OK to read .Result because the ValueTask is completed
return ExecuteReaderAsync(behavior, IOBehavior.Synchronous, CancellationToken.None).Result;
#pragma warning restore CA2012
}

#if NET6_0_OR_GREATER
Expand All @@ -148,10 +150,10 @@ private async Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavi
return await ExecuteReaderAsync(behavior, AsyncIOBehavior, cancellationToken).ConfigureAwait(false);
}

private Task<MySqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
private ValueTask<MySqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
{
if (!IsValid(out var exception))
return Task.FromException<MySqlDataReader>(exception);
return new ValueTask<MySqlDataReader>(Task.FromException<MySqlDataReader>(exception));

CurrentCommandBehavior = behavior;
foreach (MySqlBatchCommand batchCommand in BatchCommands)
Expand Down
22 changes: 15 additions & 7 deletions src/MySqlConnector/MySqlCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ private MySqlCommand(MySqlCommand other)
/// <inheritdoc/>
public override object? ExecuteScalar() => ExecuteScalarAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();

public new MySqlDataReader ExecuteReader() => ExecuteReaderAsync(default, IOBehavior.Synchronous, default).GetAwaiter().GetResult();
#pragma warning disable CA2012 // OK to read .Result because the ValueTask is completed
public new MySqlDataReader ExecuteReader() => ExecuteReaderAsync(default, IOBehavior.Synchronous, default).Result;

public new MySqlDataReader ExecuteReader(CommandBehavior commandBehavior) => ExecuteReaderAsync(commandBehavior, IOBehavior.Synchronous, default).GetAwaiter().GetResult();
#pragma warning restore CA2012

/// <inheritdoc/>
public override void Prepare()
Expand Down Expand Up @@ -278,8 +280,10 @@ protected override DbTransaction? DbTransaction

protected override DbParameter CreateDbParameter() => new MySqlParameter();

#pragma warning disable CA2012 // OK to read .Result because the ValueTask is completed
protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) =>
ExecuteReaderAsync(behavior, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
ExecuteReaderAsync(behavior, IOBehavior.Synchronous, CancellationToken.None).Result;
#pragma warning restore CA2012

/// <summary>
/// Executes this command asynchronously on the associated <see cref="MySqlConnection"/>.
Expand Down Expand Up @@ -332,26 +336,30 @@ internal async Task<int> ExecuteNonQueryAsync(IOBehavior ioBehavior, Cancellatio
}

public new Task<MySqlDataReader> ExecuteReaderAsync(CancellationToken cancellationToken = default) =>
ExecuteReaderAsync(default, AsyncIOBehavior, cancellationToken);
ExecuteReaderAsync(default, AsyncIOBehavior, cancellationToken).AsTask();

public new Task<MySqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken = default) =>
ExecuteReaderAsync(behavior, AsyncIOBehavior, cancellationToken);
ExecuteReaderAsync(behavior, AsyncIOBehavior, cancellationToken).AsTask();

protected override async Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) =>
await ExecuteReaderAsync(behavior, AsyncIOBehavior, cancellationToken).ConfigureAwait(false);

internal async Task<MySqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
internal async ValueTask<MySqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
{
Volatile.Write(ref m_commandTimedOut, false);
this.ResetCommandTimeout();
using var registration = ((ICancellableCommand) this).RegisterCancel(cancellationToken);
return await ExecuteReaderNoResetTimeoutAsync(behavior, ioBehavior, cancellationToken).ConfigureAwait(false);
}

internal Task<MySqlDataReader> ExecuteReaderNoResetTimeoutAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
internal ValueTask<MySqlDataReader> ExecuteReaderNoResetTimeoutAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken)
{
if (!IsValid(out var exception))
return Task.FromException<MySqlDataReader>(exception);
#if NET5_0_OR_GREATER
return ValueTask.FromException<MySqlDataReader>(exception);
#else
return new ValueTask<MySqlDataReader>(Task.FromException<MySqlDataReader>(exception));
#endif

var activity = NoActivity ? null : Connection!.Session.StartActivity(ActivitySourceHelper.ExecuteActivityName,
ActivitySourceHelper.DatabaseStatementTagName, CommandText);
Expand Down

0 comments on commit 016657a

Please sign in to comment.