Skip to content
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] Notify quic streams on connection abort #52665

Closed
wants to merge 1 commit into from

Conversation

CarnaViire
Copy link
Member

Algorithm and thoughts:

The only one who knows the Connection was aborted is the Connection itself. Connection's SHUTDOWN_INITIATED_BY_PEER will be immediately followed by Stream's SHUTDOWN_COMPLETED -- which we treat as EndOfStream, hence the issue #32050. As soon as we get Connection's SHUTDOWN_INITIATED_BY_PEER, we want to notify all the Connection's Streams that the Connection was aborted, so the Streams would abort all outstanding operations with the correct exception, and throw on subsequent ones, and ignore Stream's SHUTDOWN_COMPLETED.

This can be done by maintaining a list of Streams inside Connection. There are two problems I see with that: allowing Streams be garbage collected and removing Streams from the list on Stream's Dispose and/or garbage collection.

The first one I solved with WeakReferences.

For the second one I see two possible solutions:

  • having a timer inside the Connection that would periodically clean up garbage collected and/or disposed Streams from the list (which I didn't like)
  • making Stream to add itself in ctor and remove itself on Dispose. That is what I implemented, but it still is not pretty - because this way Stream also has a link back to Connection. But HTTP/2 also seems to have similar two-way links.

I'm opening that as I already have the working code, but I would be happy to hear other ideas.

Fixes #32050

@ghost
Copy link

ghost commented May 12, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Algorithm and thoughts:

The only one who knows the Connection was aborted is the Connection itself. Connection's SHUTDOWN_INITIATED_BY_PEER will be immediately followed by Stream's SHUTDOWN_COMPLETED -- which we treat as EndOfStream, hence the issue #32050. As soon as we get Connection's SHUTDOWN_INITIATED_BY_PEER, we want to notify all the Connection's Streams that the Connection was aborted, so the Streams would abort all outstanding operations with the correct exception, and throw on subsequent ones, and ignore Stream's SHUTDOWN_COMPLETED.

This can be done by maintaining a list of Streams inside Connection. There are two problems I see with that: allowing Streams be garbage collected and removing Streams from the list on Stream's Dispose and/or garbage collection.

The first one I solved with WeakReferences.

For the second one I see two possible solutions:

  • having a timer inside the Connection that would periodically clean up garbage collected and/or disposed Streams from the list (which I didn't like)
  • making Stream to add itself in ctor and remove itself on Dispose. That is what I implemented, but it still is not pretty - because this way Stream also has a link back to Connection. But HTTP/2 also seems to have similar two-way links.

I'm opening that as I already have the working code, but I would be happy to hear other ideas.

Fixes #32050

Author: CarnaViire
Assignees: -
Labels:

area-System.Net

Milestone: -

@CarnaViire CarnaViire changed the title [QUIC] Add notifying quic streams on connection abort [QUIC] Notify quic streams on connection abort May 12, 2021
@geoffkizer
Copy link
Contributor

Couldn't we do something like this:

(1) When we get SHUTDOWN_INITIATED_BY_PEER on the connection, set a flag on the connection (we may already do this?)
(2) When we get SHUTDOWN_COMPLETED on the stream, check the flag from (1) and if it's true, abort the stream

I assume we'll get SHUTDOWN_COMPLETED for all open streams promptly after we get SHUTDOWN_INITIATED_BY_PEER...

@CarnaViire
Copy link
Member Author

Closing for now as this may be solved in a better way using microsoft/msquic#1581

@CarnaViire CarnaViire closed this May 13, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
@CarnaViire CarnaViire deleted the quic-connection-abort branch May 26, 2021 16:58
@ghost ghost locked as resolved and limited conversation to collaborators Jun 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[QUIC] QuicStream.ReadAsync against an aborted connection returns End Of Stream
3 participants