Conversation
src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
Show resolved
Hide resolved
src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
Outdated
Show resolved
Hide resolved
| await newConneciton.SendResponseDataAsync(retriedStreamId, new byte[0], endStream: true).ConfigureAwait(false); | ||
|
|
||
| await newConneciton.WriteFrameAsync(goAwayFrame).ConfigureAwait(false); | ||
| var goAwayFrameOnNewConnection = new GoAwayFrame(retriedStreamId, (int)ProtocolErrors.ENHANCE_YOUR_CALM, new byte[0], 0); |
There was a problem hiding this comment.
btw. I have previously sent GOAWAY with 0 but that happened after we have already sent complete response - currently client assumes that server has processed the stream completely but server claimed with GOAWAY that it hasn't - it feels like this is something spec should clarify further as I'm not sure if the client should somehow retroactively thrown in that case.
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
Outdated
Show resolved
Hide resolved
| if (NetEventSource.IsEnabled) Trace(frameHeader.StreamId, $"{nameof(lastValidStream)}={lastValidStream}, {nameof(errorCode)}={errorCode}"); | ||
|
|
||
| AbortStreams(lastValidStream, new Http2ProtocolException(errorCode)); | ||
| StartTerminatingConnection(lastValidStream, new Http2ProtocolException(errorCode)); |
There was a problem hiding this comment.
I'm not sure it's worthwhile passing the Http2ProtocolException through here. The requests are going to be retried, and thus the user should never see this exception. I suppose it doesn't cause any harm, but it is different than how we handle REFUSED_STREAM today.
There was a problem hiding this comment.
@geoffkizer the reason I added that was so that user have a way of distinguishing between NO_ERROR vs other state in case they implement their own retry logic. Also I've noticed the initially written test expected to see that being propagated so it's possible the user might want to have more diagnostic info as well. (also even though retry logic is there after certain amount of tries/time we still bubble up the exception which looks more useful with extra info)
There was a problem hiding this comment.
if the user is seeing this exception, then there's something wrong going on. We should always retry when this exception is thrown. Do you know why this is getting surfaced to the user?
This may be related to the issue below where you are sending a GOAWAY with last valid stream = 0. I.e., the server is lying and telling us that requests which have already been processed actually have not been, and since we've gotten past the point in request processing where we can retry (i.e. response headers have been received) then we're actually ending up aborting this request. I guess that's fine, but at least we should add a comment regarding this...
There was a problem hiding this comment.
Since you are passing this exception in the GOAWAY case, can we also pass it in the REFUSED_STREAM case? Seems like we could have a similar issue with the server incorrectly sending REFUSED_STREAM after it's processed the stream.
There was a problem hiding this comment.
I've noticed this being bubbled when timeout happens which I actually think it makes sense although I do not think the code was designed to do that and likely is a coincidence (i.e. client tried doing request, retried few times but server kept on aborting with some error and eventually you see one of the server sent bubbled up).
I believe this was causing the stack to be printed by the async state machine timer but test eventually passed (test shouldn't pass but exception seems correct)
There was a problem hiding this comment.
That's strange. Do you know which test this was happening during? This was a remote server test, I assume? It seems weird that we'd be getting REFUSED_STREAM at all during remote server tests... would be good to understand why.
There was a problem hiding this comment.
I'll pass it also in the REFUSED_STREAM case. Unfortunately wasn't able to repro bubbling up condition since I got it last time so possibly this was due to some bug I got when I was modifying the code.
src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
Outdated
Show resolved
Hide resolved
|
I'm still flushing out some flakiness in these tests, will update once I feel like this test won't cause random CI failures |
|
|
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
Show resolved
Hide resolved
| /// // test code | ||
| /// } | ||
| /// </summary> | ||
| internal class Watchdog : ICriticalNotifyCompletion |
src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
Outdated
Show resolved
Hide resolved
|
only last commit has changes for the latest feedback. had to rebase because of another merge conflict |
…e on REFUSED_STREAM
|
Ok, per offline conversation with @geoffkizer I've made the retry case more deterministic without having to wait. So far I haven't noticed any non-determinisim or flakiness (running for 30min) will leave it running over the weekend |
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs
Show resolved
Hide resolved
src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
Show resolved
Hide resolved
|
Generally LGTM, a couple minor comments |
|
Just FYI, I've left this running in a loop over a weekend and haven't seen any flakiness |
* Retry on GOAWAY * send correct GOAWAY on retried connection, update comment * Harden against flakiness * Fix: Connection refused error is different on Debian * apply feedback * Make partial body/received headers case deterministic, pass error code on REFUSED_STREAM * apply latest feedback Commit migrated from dotnet/corefx@1841042
Fixes: https://github.com/dotnet/corefx/issues/39013
There is still some behavior which needs to be figured out so until then marking this as draft:
https://github.com/dotnet/corefx/issues/39013#issuecomment-507820160
More tests will be added in:
https://github.com/dotnet/corefx/issues/34638
Regardless of above there seem to be some flakiness in the test now which I'm investigating