Skip to content

Commit

Permalink
Add creation and disposal to connection interception (#27920)
Browse files Browse the repository at this point in the history
Co-authored-by: Andriy Svyryd <[email protected]>
  • Loading branch information
ajcvickers and AndriySvyryd authored May 4, 2022
1 parent 8d80ea9 commit 7ad294c
Show file tree
Hide file tree
Showing 18 changed files with 1,550 additions and 73 deletions.
59 changes: 59 additions & 0 deletions src/EFCore.Relational/Diagnostics/ConnectionCreatedEventData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Diagnostics;

/// <summary>
/// The <see cref="DiagnosticSource" /> event payload for <see cref="RelationalEventId.ConnectionCreated"/> events.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-diagnostics">Logging, events, and diagnostics</see> for more information and examples.
/// </remarks>
public class ConnectionCreatedEventData : DbContextEventData
{
/// <summary>
/// Constructs the event payload.
/// </summary>
/// <param name="eventDefinition">The event definition.</param>
/// <param name="messageGenerator">A delegate that generates a log message for this event.</param>
/// <param name="connection">The <see cref="DbConnection" />.</param>
/// <param name="context">The <see cref="DbContext" /> currently being used, to null if not known.</param>
/// <param name="connectionId">A correlation ID that identifies the <see cref="DbConnection" /> instance being used.</param>
/// <param name="startTime">The start time of this event.</param>
/// <param name="duration">The duration this event.</param>
public ConnectionCreatedEventData(
EventDefinitionBase eventDefinition,
Func<EventDefinitionBase, EventData, string> messageGenerator,
DbConnection connection,
DbContext? context,
Guid connectionId,
DateTimeOffset startTime,
TimeSpan duration)
: base(eventDefinition, messageGenerator, context)
{
Connection = connection;
ConnectionId = connectionId;
StartTime = startTime;
Duration = duration;
}

/// <summary>
/// The <see cref="DbConnection" />.
/// </summary>
public virtual DbConnection Connection { get; }

/// <summary>
/// A correlation ID that identifies the <see cref="DbConnection" /> instance being used.
/// </summary>
public virtual Guid ConnectionId { get; }

/// <summary>
/// The start time of this event.
/// </summary>
public virtual DateTimeOffset StartTime { get; }

/// <summary>
/// The duration of this event.
/// </summary>
public virtual TimeSpan Duration { get; }
}
43 changes: 43 additions & 0 deletions src/EFCore.Relational/Diagnostics/ConnectionCreatingEventData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Diagnostics;

/// <summary>
/// The <see cref="DiagnosticSource" /> event payload for <see cref="RelationalEventId.ConnectionCreating"/> events.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-diagnostics">Logging, events, and diagnostics</see> for more information and examples.
/// </remarks>
public class ConnectionCreatingEventData : DbContextEventData
{
/// <summary>
/// Constructs the event payload.
/// </summary>
/// <param name="eventDefinition">The event definition.</param>
/// <param name="messageGenerator">A delegate that generates a log message for this event.</param>
/// <param name="context">The <see cref="DbContext" /> currently being used, to null if not known.</param>
/// <param name="connectionId">A correlation ID that identifies the <see cref="DbConnection" /> instance being used.</param>
/// <param name="startTime">The start time of this event.</param>
public ConnectionCreatingEventData(
EventDefinitionBase eventDefinition,
Func<EventDefinitionBase, EventData, string> messageGenerator,
DbContext? context,
Guid connectionId,
DateTimeOffset startTime)
: base(eventDefinition, messageGenerator, context)
{
ConnectionId = connectionId;
StartTime = startTime;
}

/// <summary>
/// A correlation ID that identifies the <see cref="DbConnection" /> instance being used.
/// </summary>
public virtual Guid ConnectionId { get; }

/// <summary>
/// The start time of this event.
/// </summary>
public virtual DateTimeOffset StartTime { get; }
}
32 changes: 16 additions & 16 deletions src/EFCore.Relational/Diagnostics/IDbCommandInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public interface IDbCommandInterceptor : IInterceptor
/// If <see cref="InterceptionResult{DbCommand}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{DbCommand}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{DbCommand}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult<DbCommand> CommandCreating(CommandCorrelatedEventData eventData, InterceptionResult<DbCommand> result)
Expand All @@ -63,7 +63,7 @@ InterceptionResult<DbCommand> CommandCreating(CommandCorrelatedEventData eventDa
/// </param>
/// <returns>
/// The result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
DbCommand CommandCreated(CommandEndEventData eventData, DbCommand result)
Expand All @@ -78,7 +78,7 @@ DbCommand CommandCreated(CommandEndEventData eventData, DbCommand result)
/// </param>
/// <returns>
/// The result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
DbCommand CommandInitialized(CommandEndEventData eventData, DbCommand result)
Expand All @@ -99,7 +99,7 @@ DbCommand CommandInitialized(CommandEndEventData eventData, DbCommand result)
/// If <see cref="InterceptionResult{DbDataReader}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{DbDataReader}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{DbDataReader}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command,CommandEventData eventData, InterceptionResult<DbDataReader> result)
Expand All @@ -120,7 +120,7 @@ InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command,CommandEventD
/// If <see cref="InterceptionResult{Object}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{Object}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{Object}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult<object> ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<object> result)
Expand All @@ -141,7 +141,7 @@ InterceptionResult<object> ScalarExecuting(DbCommand command, CommandEventData e
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{Int32}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult<int> NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<int> result)
Expand All @@ -163,7 +163,7 @@ InterceptionResult<int> NonQueryExecuting(DbCommand command, CommandEventData ev
/// If <see cref="InterceptionResult{DbDataReader}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{DbDataReader}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{DbDataReader}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in, often using <see cref="Task.FromResult{TResult}" />
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Expand All @@ -190,7 +190,7 @@ ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
/// If <see cref="InterceptionResult{Object}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{Object}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{Object}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in, often using <see cref="Task.FromResult{TResult}" />
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Expand All @@ -217,7 +217,7 @@ ValueTask<InterceptionResult<object>> ScalarExecutingAsync(
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{Int32}.Result" /> instead.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in, often using <see cref="Task.FromResult{TResult}" />
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Expand All @@ -243,7 +243,7 @@ ValueTask<InterceptionResult<int>> NonQueryExecutingAsync(
/// </param>
/// <returns>
/// The result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result)
Expand All @@ -264,7 +264,7 @@ DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventDat
/// </param>
/// <returns>
/// The result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
object? ScalarExecuted(DbCommand command, CommandExecutedEventData eventData, object? result)
Expand All @@ -285,7 +285,7 @@ DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventDat
/// </param>
/// <returns>
/// The result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result)
Expand All @@ -307,7 +307,7 @@ int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// A <see cref="Task" /> providing the result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in, often using <see cref="Task.FromResult{TResult}" />
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Expand All @@ -334,7 +334,7 @@ ValueTask<DbDataReader> ReaderExecutedAsync(
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// A <see cref="Task" /> providing the result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in, often using <see cref="Task.FromResult{TResult}" />
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Expand All @@ -361,7 +361,7 @@ ValueTask<DbDataReader> ReaderExecutedAsync(
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// A <see cref="Task" /> providing the result that EF will use.
/// A normal implementation of this method for any interceptor that is not attempting to change the result
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in, often using <see cref="Task.FromResult{TResult}" />
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Expand Down Expand Up @@ -427,7 +427,7 @@ Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, Canc
/// If <see cref="InterceptionResult.IsSuppressed" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult.IsSuppressed" /> is true, then EF will suppress the operation
/// it was about to perform.
/// A normal implementation of this method for any interceptor that is not attempting to suppress
/// An implementation of this method for any interceptor that is not attempting to suppress
/// the operation is to return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult DataReaderDisposing(DbCommand command, DataReaderDisposingEventData eventData, InterceptionResult result)
Expand Down
Loading

0 comments on commit 7ad294c

Please sign in to comment.