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

Implement QUIC abort exceptions, fix channel usage, and implement some tests. #32051

Merged
merged 2 commits into from
Feb 11, 2020

Conversation

scalablecory
Copy link
Contributor

@scalablecory scalablecory commented Feb 10, 2020

New: implement QuicStreamAbortedException, QuicConnectionAbortedException, QuicOperationAbortedException.
Fix: MsQuic returning null implementation when completing listener/connection channels.
Fix: some flags types being defined as 8-bit when they are 32-bit in msquic.h
Reorganize tests a little bit and avoid a shared listener creating variability.
Add some additional tests demonstrating failures seen in HttpClient. Issues created for those: #32050 #32049 #32048

@scalablecory scalablecory added this to the 5.0 milestone Feb 10, 2020
@scalablecory scalablecory requested review from jkotalik and a team February 10, 2020 21:15
@scalablecory scalablecory added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) NO-REVIEW Experimental/testing PR, do NOT review it labels Feb 10, 2020
@jkotalik
Copy link
Contributor

Fix: MsQuic returning null implementation when completing listener/connection channels.

I was just about to do this 😄

Reorganize tests a little bit and avoid a shared listener creating variability.

I thought the listener was created once per test still. Did you see this variability?

…tion, QuicOperationAbortedException.

Fix: MsQuic returning null implementation when completing listener/connection channels.
Fix: some flags types being defined as 8-bit when they are 32-bit in msquic.h
Add some additional tests demonstrating failures seen in HttpClient.
@scalablecory scalablecory removed NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) NO-REVIEW Experimental/testing PR, do NOT review it labels Feb 10, 2020
@scalablecory
Copy link
Contributor Author

some http3 code snuck into the commit; fixed now :)

@scalablecory
Copy link
Contributor Author

I thought the listener was created once per test still. Did you see this variability?

Yes, xunit test classes are newed up once per test so it wasn't like a race condition. More for organization purposes (I'm worried about unintentionally using it in a way that exercises race conditions VS a specific test -- this is more explicit and in line with how most of our other tests function)

shouldComplete = true;
}
_sendState = SendState.Aborted;
_sendErrorCode = evt.Data.PeerSendAbort.ErrorCode;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sendErrorCode a local variable. I don't believe it is used elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used to throw a QuicStreamAbortedException on the other side of the ValueTask

@@ -21,11 +21,13 @@ public class MsQuicTests : MsQuicTestBase
[Fact]
public async Task BasicTest()
{
using QuicListener listener = CreateQuicListener();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is more of a style thing. I personally prefer initialization of the listener in the constructor, but I'm not strongly opposed to making it explicit

@scalablecory scalablecory self-assigned this Feb 11, 2020
}

if (NetEventSource.IsEnabled) NetEventSource.Exit(this);

return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to continue returning null than to throw an exception from AcceptStreamAsync when the connection is closing. The connection being closed is a common enough that throwing an exception feels noisy. I know this will make the QuicConnection.AcceptStreamAsync() wrapper a little more complicated, but I think it's worth it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, looking back on this, I agree as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that anyone familiar with sockets will expect consistency with that, which is why I went that direction, but I also think most everyone else might expect it will return null. The question becomes who is the more likely user. It's trouble to merge Stream and Socket 🙃.

I don't feel strongly about it. We can change it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep it with the "current" behavior of returning null, but fix it in QuicConnection.AcceptStreamAsync.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think this needs some more thought now. We should consider how consistent the APIs between QuicStream, QuicConnection, QuicListener need to be in how they behave on disposal. QuicStream.ReadAsync() etc. do not return a nullable type and will need to throw an exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to commit this for now to unblock things (the APIs are currently broken, returning null triggers a bug) but will open an issue to figure this out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: #32142


return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should continue returning null here too.

@@ -95,4 +95,8 @@ public class QuicStreamAbortedException : QuicException
public QuicStreamAbortedException(string message, long errorCode) : base(message) { }
public long ErrorCode { get; }
}
public class QuicOperationAbortedException : QuicException
Copy link
Member

@halter73 halter73 Feb 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that QuicException derives directly from Exception. Would it be better to have it derive from IOException or possibly OperationCanceledException if it's always user-initiated?

I would lean towards IOException given how it's currently used. I see it's being triggered by stuff like "HandleEventShutdownInitiatedByPeer" which feels really IOExceptiony to me (if it needs to be an exception at all).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea that seems reasonable. Open up an issue for it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't know if QuicOperationAbortedException will be necessary now if we start returning null.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at SocketException, and it doesn't derive from IOException, so I'm no longer convinced this is the way to go. Maybe it should derive from SystemException (which SocketException does indirectly), but I'm not sure what the guidance there is. Is this supposed to be the base class for all Exceptions in a System.* namespace?

@maryamariyan
Copy link
Member

Note regarding the new-api-needs-documentation label:
This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@karelz
Copy link
Member

karelz commented Feb 12, 2020

@maryamariyan this will be an interesting case as the API is in new library that we intentionally don't ship yet. The API has to go through API iterations and then API review. Then it will be good time to document it once we have final shape.
How does that fit our API documentation flow?

@scalablecory scalablecory deleted the quic-aborts branch July 29, 2020 16:06
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
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.

5 participants