-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[QUIC] Handle connection abort in streams #52776
Conversation
Tagging subscribers to this area: @dotnet/ncl Issue DetailsThis leverages newly added flag to SHUTDOWN_COMPLETED event, which means that's not a user-initiated stream shutdown, but a connection abort microsoft/msquic#1581 Fixes #32050 cc @JamesNK: after this PR msquic version should be updated
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused, I thought that the whole goal of adding the flag to the stream SHUTDOWN_COMPLETE event was to avoid extra link between stream and a connection. Yet, the MsQuicConnection.State
reference is added to MsQuicStream
. And if I understand the change right, it's only used to retrieve the connection close error code. Couldn't msquic passed code in the SHUTDOWN_COMPLETE event? And do we really need the code?
@nibanks how hard it will be to add connection's error code to stream's shutdown event?
It is a part of QuicConnectionAbortedException. Unless we want to use another exception type for some reason - I think peer's error code should be delivered to user in this situation also. |
Why do we want to avoid this? It's not obvious to me why that's bad... |
We asked msquic to change the API (adding the flag to SHUTDOWN_COMPLETE) so that we don't have to hold the link between stream and connection since they have it and can leverage it (or at least that's what I thought was the motivation). With the way the change is done here, we don't actually need the flag, we could just use the connection as we do now for the errorCode: runtime/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs Line 1068 in 104a1be
So that's why I'm asking. Why did we requested change from msquic? What did we wanted to achieve with it? Because I thought that the goal was to get rid of the link and rely on msquic notification data instead.
I never said it's bad. |
I originally asked for that so we wouldn't have two-way link (so connection wouldn't have list of streams inside to notify, which was in my first PR). While it will be great to remove stream->connection link too, #52800 brings it again for another reason... |
I don't think you're going to be able to completely remove the interdependency. As you say, #52800 tracks the requirement that you must keep the connection alive at least as long as the streams. I don't want to keep having one-off changes in MsQuic to facilitate "it'd be a little easier if MsQuic did this so I didn't have to go to the connection for this..." |
I definitely agree that having to maintain a list of streams on the connection would be painful and messy and I hope we never have to do it. So far, it seems we haven't needed to, which is good. Having a link from the stream to the connection that it's part of seems reasonable, though. |
Am I missing something when I think that the microsoft/msquic#1581 change was not necessary to achieve the solution in this PR? Edit: I'm not saying that it should be reverted or anything. I'm just trying to understand it all. |
No it was not strictly necessary. The state could have been inferred by the fact that the connection had been shutdown already. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, pending the decision about connection-stream link.
Comments are mostly code-styling nits, nothing serious.
Thanks!
|
||
if (NetEventSource.Log.IsEnabled()) | ||
{ | ||
NetEventSource.Info(_state, $"[Connection#{_state.GetHashCode()}] inbound connection created"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, this is a prime example where could actually log the handle to be able to easily map it to the msquic logs, see #53224:
on the .NET side I'm wondering if we should show (or log) the handle so it easier to correlate to the native logs.
But that's absolutely not the goal of this PR and you shouldn't worry about it here, just good to be aware of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's indeed is a good example. But let's update it separately, I'd love this PR to be merged sooner to stop blocking others
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs
Outdated
Show resolved
Hide resolved
@@ -383,6 +412,14 @@ internal override async ValueTask ShutdownWriteCompleted(CancellationToken cance | |||
{ | |||
ThrowIfDisposed(); | |||
|
|||
lock (_state) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm. not sure if this needs to be under lock since we are not modifying the state.
For the check there is IMHO race condition anyway e.g. the state can be changed immediately after the lock before other code executes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You technically still need the lock to make visible changes from other threads. We could make access to that one field use Volatile.Read
/Volatile.Write
as an alternative to avoid the lock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. but even with that there is still race to this really becomes best effort IMHO.
I'm Im not sure if this makes any measurable impact so I feel it is ok to keep it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
This leverages newly added flag to SHUTDOWN_COMPLETED event, which means that's not a user-initiated stream shutdown, but a connection abort microsoft/msquic#1581
Fixes #32050
cc @JamesNK: after this PR msquic version should be updated