Skip to content

Commit

Permalink
Various improvements.
Browse files Browse the repository at this point in the history
Rename type to 'Context'; this matches the existing UsePeriodicPasswordProvider.
Add CancellationToken; the user might execute commands against the server that might need to be cancelled.
Remove sync overload; it could be unnecessary.
Move types to their own files.
Allow multiple callbacks to be added.

Signed-off-by: Bradley Grainger <[email protected]>
  • Loading branch information
bgrainger committed Oct 13, 2024
1 parent 3a5254b commit b3b3eaa
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 78 deletions.
5 changes: 4 additions & 1 deletion src/MySqlConnector/MySqlConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,10 @@ internal async Task OpenAsync(IOBehavior? ioBehavior, CancellationToken cancella
EnlistTransaction(System.Transactions.Transaction.Current);

if (ConnectionOpenedCallback is { } connectionOpenedCallback)
await connectionOpenedCallback(new(this, m_session.Conditions)).ConfigureAwait(false);
{
cancellationToken.ThrowIfCancellationRequested();
await connectionOpenedCallback(new(this, m_session.Conditions), cancellationToken).ConfigureAwait(false);
}
}
catch (Exception ex) when (activity is { IsAllDataRequested: true })
{
Expand Down
46 changes: 3 additions & 43 deletions src/MySqlConnector/MySqlConnectionOpenedCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,7 @@ namespace MySqlConnector;
/// <summary>
/// A callback that is invoked when a new <see cref="MySqlConnection"/> is opened.
/// </summary>
/// <param name="data">A <see cref="MySqlConnectionOpenedData"/> giving information about the connection being opened.</param>
/// <param name="context">A <see cref="MySqlConnectionOpenedContext"/> giving information about the connection being opened.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the asynchronous operation.</param>
/// <returns>A <see cref="ValueTask"/> representing the result of the possibly-asynchronous operation.</returns>
public delegate ValueTask MySqlConnectionOpenedCallback(MySqlConnectionOpenedData data);

public sealed class MySqlConnectionOpenedData
{
/// <summary>
/// The <see cref="MySqlConnection"/> that was opened.
/// </summary>
public MySqlConnection Connection { get; }

/// <summary>
/// Bitflags giving the conditions under which a connection was opened.
/// </summary>
public MySqlConnectionOpenedConditions Conditions { get; }

internal MySqlConnectionOpenedData(MySqlConnection connection, MySqlConnectionOpenedConditions conditions)
{
Connection = connection;
Conditions = conditions;
}
}

/// <summary>
/// Bitflags giving the conditions under which a connection was opened.
/// </summary>
[Flags]
public enum MySqlConnectionOpenedConditions
{
/// <summary>
/// No specific conditions apply. This value may be used when an existing pooled connection is reused without being reset.
/// </summary>
None = 0,

/// <summary>
/// A new physical connection to a MySQL Server was opened. This value is mutually exclusive with <see cref="Reset"/>.
/// </summary>
New = 1,

/// <summary>
/// An existing pooled connection to a MySQL Server was reset. This value is mutually exclusive with <see cref="New"/>.
/// </summary>
Reset = 2,
}
public delegate ValueTask MySqlConnectionOpenedCallback(MySqlConnectionOpenedContext context, CancellationToken cancellationToken);
23 changes: 23 additions & 0 deletions src/MySqlConnector/MySqlConnectionOpenedConditions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace MySqlConnector;

/// <summary>
/// Bitflags giving the conditions under which a connection was opened.
/// </summary>
[Flags]
public enum MySqlConnectionOpenedConditions
{
/// <summary>
/// No specific conditions apply. This value may be used when an existing pooled connection is reused without being reset.
/// </summary>
None = 0,

/// <summary>
/// A new physical connection to a MySQL Server was opened. This value is mutually exclusive with <see cref="Reset"/>.
/// </summary>
New = 1,

/// <summary>
/// An existing pooled connection to a MySQL Server was reset. This value is mutually exclusive with <see cref="New"/>.
/// </summary>
Reset = 2,
}
23 changes: 23 additions & 0 deletions src/MySqlConnector/MySqlConnectionOpenedContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace MySqlConnector;

/// <summary>
/// Contains information passed to <see cref="MySqlConnectionOpenedCallback"/> when a new <see cref="MySqlConnection"/> is opened.
/// </summary>
public sealed class MySqlConnectionOpenedContext
{
/// <summary>
/// The <see cref="MySqlConnection"/> that was opened.
/// </summary>
public MySqlConnection Connection { get; }

/// <summary>
/// Bitflags giving the conditions under which a connection was opened.
/// </summary>
public MySqlConnectionOpenedConditions Conditions { get; }

internal MySqlConnectionOpenedContext(MySqlConnection connection, MySqlConnectionOpenedConditions conditions)
{
Connection = connection;
Conditions = conditions;
}
}
17 changes: 6 additions & 11 deletions src/MySqlConnector/MySqlDataSourceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,14 @@ public MySqlDataSourceBuilder UseRemoteCertificateValidationCallback(RemoteCerti
return this;
}

/// <summary>
/// Adds a callback that is invoked when a new <see cref="MySqlConnection"/> is opened.
/// </summary>
/// <param name="callback">The callback to invoke.</param>
/// <returns>This builder, so that method calls can be chained.</returns>
public MySqlDataSourceBuilder UseConnectionOpenedCallback(MySqlConnectionOpenedCallback callback)
{
m_connectionOpenedCallback = callback;
return this;
}

public MySqlDataSourceBuilder UseConnectionOpenedCallback(Action<MySqlConnectionOpenedData> callback)
{
m_connectionOpenedCallback = data =>
{
callback(data);
return default;
};
m_connectionOpenedCallback += callback;
return this;
}

Expand Down
24 changes: 1 addition & 23 deletions tests/MySqlConnector.Tests/ConnectionOpenedCallbackTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,6 @@ public void CallbackIsInvoked()
}
}

[Fact]
public void SyncCallbackIsInvoked()
{
var dataSource = new MySqlDataSourceBuilder(m_csb.ConnectionString)
.UseConnectionOpenedCallback(data =>
{
m_connectionOpenedCount++;
m_connectionOpenedConditions = data.Conditions;
})
.Build();
using (var connection = dataSource.CreateConnection())
{
Assert.Equal(0, m_connectionOpenedCount);
Assert.Equal(MySqlConnectionOpenedConditions.None, m_connectionOpenedConditions);

connection.Open();

Assert.Equal(1, m_connectionOpenedCount);
Assert.Equal(MySqlConnectionOpenedConditions.New, m_connectionOpenedConditions);
}
}

[Fact]
public void CallbackIsInvokedForPooledConnection()
{
Expand Down Expand Up @@ -146,7 +124,7 @@ public void ConditionsForNonResetConnection()
}
}

private ValueTask OnConnectionOpenedAsync(MySqlConnectionOpenedData data)
private ValueTask OnConnectionOpenedAsync(MySqlConnectionOpenedContext data, CancellationToken cancellationToken)
{
m_connectionOpenedCount++;
m_connectionOpenedConditions = data.Conditions;
Expand Down

0 comments on commit b3b3eaa

Please sign in to comment.