-
Notifications
You must be signed in to change notification settings - Fork 286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix where diagnostic listener SqlDiagnosticsListener.OnAfterCommand runs to avoid implict concurrent execution #1634
Comments
System.Data.SqlClient is in maintenance mode. Microsoft.Data.SqlClient should be used instead (unsure if it makes any difference for the repro) |
If I understand this correctly then the equivalent code for netcore in this library is: SqlClient/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs Lines 2542 to 2577 in 9b1996a
It creates a TCS and then passes the task from it to If that is the problem then the obvious, and probably breaking/wrong fix would be to keep the unwrap the internal task from the async invocation and return that to the caller instead, then they'd be awaiting our cleanup task and there can't be an ordering problem. Without a reliable replication I'd be really worried about making any changes to this. The async in this library is older than langauge support and can have really complicated interactions with any mistakes capable of breaking or regressing customers easily. @okolvik-avento have you observed this bug since you moved to Microsoft.Date.SqlClient at all? Is there a contractual obligation for event ordering here? The issue it's causing seem to be that the telemetry client is trying to access an HttpContext object which has already been cleaned up in response to the query diagnistic being sent but is that a behaviour that's defined or is it just hopeful and works because of close timing? Does sqlclient have a defined obligation to raise the event before returning to the customer? |
@Wraith2 i'm still seeing the get_Cookies exception after transitioning to Microsoft.Data.SqlClient |
@Wraith2 I think there are 2 fixes I can think of:
I'm confident I can make a reliable repro now that the problem is understood. If there's fear this is too breaking we can always add an app context switch. This ends up breaking ASP.NET Core + AppInsights (which is a very common combination) so it's important we figure out how to solve this. cc @noahfalk for this take on the reordering of events here. |
Moving the diagnostics call before setting result/exception is easy and relatively safe in terms of changes in this library. I'm not going to worry about a replication for that one since we're not logically changing the async composition. I did eventually think of this but only after I'd turned my computer off. My only worry is whether it would expose similar problems to calling late if we call too early and people expect late, what happens if someone relies on knowing a result has been user-handled and it now hasn't been? The other path through continuation calls before setting the exception so users have already been exposed to that situation in a limited way. I'll try and audit the library later and move all diagnostics calls before tcs outcome setting methods are called. |
@davidfowl thanks for opening the issue here. @Wraith2 thank you for the support. We will review the PR. |
How's that for a quick fix :) |
Describe the bug
See dotnet/aspnetcore#41924 for more background and dotnet/aspnetcore#41924 (comment) for the context.
When you run an async sql SqlCommand (via ExecuteReaderAsync), the implementation fires the diagnostics listener callback after running the user's continuation. This allows the code to run concurrently with the user code, which can introduce accidental parallelism and break in various ways. The linked issues explain how this breaks in a very common app insights scenario.
To reproduce
TBD (this is a race condition)
Expected behavior
The diagnostics listener should not run concurrently with code executing after the query is completed.
Further technical details
Microsoft.Data.SqlClient version: 4.8.3
.NET target: 6.0
SQL Server version: LocalDb
Operating system: Windows 11
The text was updated successfully, but these errors were encountered: