Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@geoffkizer
Copy link

No description provided.

@geoffkizer geoffkizer added the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Feb 12, 2018
@geoffkizer geoffkizer self-assigned this Feb 12, 2018
Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

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

Generally looks fine. Thanks.

{
try
{
s.Shutdown(SocketShutdown.Send);
Copy link
Member

Choose a reason for hiding this comment

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

Why did you remove this shutdown call? It was added specifically to help with test reliability.

Copy link
Author

Choose a reason for hiding this comment

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

Because it shouldn't be necessary. To the extent that it seems to help with test reliability, it appears to mask actual test issues by causing timing delays. This doesn't seem like a good thing.

There was at least one test case where problems cropped up because the server was not sending Content-Length: 0, even though there was no response body. Fixing the test made this problem go away.

Copy link
Member

Choose a reason for hiding this comment

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

Because it shouldn't be necessary

Without it, the client isn't guaranteed to receive all sent data, no?

Copy link
Author

@geoffkizer geoffkizer Feb 12, 2018

Choose a reason for hiding this comment

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

Without it, the client isn't guaranteed to receive all sent data, no?

Calling Close on the socket does not cause the buffered data to be discarded. The socket will continue to send and retry any buffered data, up to the linger timeout, in the background.

See https://msdn.microsoft.com/en-us/library/windows/desktop/ms738547(v=vs.85).aspx for example, though this isn't the most lucid writeup.

Shutdown is really only useful if you want to do a half-close, i.e. stop sending data but continue to read it. In the HTTP server case, when the server decides to disconnect, it's not interested in any more data from the client, so shutdown is not useful.

At least, that's my understanding.

Copy link
Author

Choose a reason for hiding this comment

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

(That said, shutdown may have local-only effects that are useful, like causing a pending operation to cancel. My point is that in these scenarios, it shouldn't affect what happens on the wire.)

Copy link
Member

Choose a reason for hiding this comment

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

You may very well be right, but there are lots of comments on the web about how this is observably not the case (maybe just due to OS bugs). And from what we've observed, especially in CI, it's also suspect. I suggest don't remove it as part of this refactoring change, as I would not be at all surprised if we saw a resulting increase in spurious test failures. At least submit it as its own dedicated change, maybe a bit after this change guess through and is shown stable.

Linger

Maybe it's the interaction of these that was an issue, with linger timeout set to 0 in some places IIRC.

Copy link
Author

Choose a reason for hiding this comment

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

Ok, I can leave it in.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks :)

// CONSIDER: Should this create the HttpClient as well?
// Look at usage patterns and see if this makes sense.

public static Task CreateServerAndClientAsync(Func<Uri, Task> clientFunc, Func<LoopbackServer, Task> serverFunc)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: can you search the order of the parameters, to match the order in the method naming?

Copy link
Author

Choose a reason for hiding this comment

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

I think I'd rather change the method name :)

}
}

// Compatibility methods
Copy link
Member

Choose a reason for hiding this comment

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

Compat with what? This is staging as part of the refactoring?

Copy link
Author

Choose a reason for hiding this comment

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

Yep

$"Date: {DateTimeOffset.UtcNow:R}\r\n" +
$"Location: {redirectUrl}\r\n" +
"Content-Length: 0\r\n" +
"\r\n"));
Copy link
Member

Choose a reason for hiding this comment

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

Is this meant to be part of this change? Seems like the main impact of this is that the connection could be pooled.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, it's intentional; see comment above.

Though, now I'm wondering exactly why we see errors without the Content-Length. I believe these only happened with WinHttpHandler. Maybe I need to understand this better...

@davidsh davidsh added test enhancement Improvements of test source code area-System.Net.Http labels Feb 12, 2018
@davidsh
Copy link
Contributor

davidsh commented Feb 12, 2018

I'm confused as to the purpose of this refactoring. Can you explain a little more about the motivation for this? Will it make future tests easier to write? Will it improve stability of the current tests? Thx.

cc: @karelz

@geoffkizer
Copy link
Author

My intent was mostly to make the test code easier to read and understand, and hopefully to make the usage of LoopbackServer more consistent today and moving forward. I started making a few tweaks and then ended up doing more than I expected.

There are several related changes here, including:
(1) Move nonessential code out of LoopbackServer itself. E.g. the websocket code and the "transfer" code. These are only used by a couple very specific tests, and don't actually need to be in LoopbackServer.
(2) Simplify a few things that are awkward today. For example, the Options object gets passed in to several different places and used in different ways. I changed it to only be passed in to CreateServerAsync. Another example: the callback you pass to AcceptSocketAsync always has to return a Task<List>, even though many uses don't care about this and just pass null.
(3) Add the Connection object, which makes the callback from AcceptSocketAsync cleaner. Today you have to have four params on the callback, even though you often only care about one or two. Connection just encapsulates these args into a single object, and allows you to easily discover and call instance methods on this object.
(4) Rename some core methods to make them more descriptive. "ReadWriteAcceptedAsync" is not entirely obvious.

@stephentoub
Copy link
Member

Replaced by #27088

@karelz karelz added this to the 2.1.0 milestone Mar 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Http * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) test enhancement Improvements of test source code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants