-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Replace SocketsHttpConnectionFactory with SocketsConnectionFactory #40506
Conversation
Co-authored-by: Cory Nelson <phrosty@gmail.com>
…andler/Connections/SocketConnection.cs add ExceptionDispatchInfo handling Co-authored-by: Cory Nelson <phrosty@gmail.com>
address -> EndPoint in error messages Co-authored-by: Cory Nelson <phrosty@gmail.com>
address -> EndPoint in error messages Co-authored-by: Cory Nelson <phrosty@gmail.com>
…ption.cs Co-authored-by: Cory Nelson <phrosty@gmail.com>
|
||
// On Windows, connection timeout takes 21 seconds. Abusing this behavior to test the cancellation logic | ||
[Fact] | ||
[PlatformSpecific(TestPlatforms.Windows)] |
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.
Does this test not work on other platforms? Seems like it should.
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.
On Linux connection "timeout" comes immediately for the non-existing IP address 1.2.3.4
. It won't even work with the following code:
CancellationTokenSource cts = new CancellationTokenSource();
OperationCanceledException ex = await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => {
await factory.ConnectAsync(doesNotExist, cancellationToken: cts.Token);
cts.Cancel();
});
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.
Ok, we should add a comment explaining this
|
||
public DnsEndPointWithProperties(string host, int port, HttpRequestMessage initialRequest) : base(host, port) | ||
{ | ||
InitialRequest = initialRequest; | ||
_initialRequest = initialRequest; |
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 don't quite understand why this class exists.
I get that we want to pass the HttpRequest through as a property, but why aren't we just doing that directly via SocketsConnectionFactory? Why do we subclass DnsEndPoint?
@scalablecory Thoughts?
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.
It's the property provider (IConnectionProperties
implementation) that is aware of HttpRequestMessage
. SocketsConnectionFactory
does not know about HTTP stuff.
We subclass DnsEndPoint
to reduce allocations. (A DnsEndpoint instance has to be created anyways.)
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.
Ah, okay, I understand now. There's a comment above but it wasn't entirely clear to me.
src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj
Outdated
Show resolved
Hide resolved
Overall this is looking pretty good to me. You should get an approval from @scalablecory before merging, because he understands this stuff better than I do. |
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
@@ -13,34 +13,38 @@ namespace System.Net.Connections | |||
{ | |||
internal sealed class SocketConnection : Connection, IConnectionProperties | |||
{ | |||
private readonly NetworkStream _stream; | |||
private readonly Socket _socket; | |||
private readonly SocketsConnectionFactory _factory; |
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.
_factory
is no longer needed, right?
{ | ||
return ValueTask.FromCanceled(cancellationToken); | ||
} | ||
cancellationToken.ThrowIfCancellationRequested(); |
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.
This should be reverted; it makes the exception come from the method rather than be bundled inside the ValueTask
, which won't be expected by users.
|
||
protected override Stream CreateStream() => _stream ??= new NetworkStream(_socket, true); | ||
|
||
protected override IDuplexPipe CreatePipe() => _pipe ??= new DuplexStreamPipe(CreateStream()); |
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.
No need to override this, this is the default implementation.
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.
looks good.
Test failure is #40436. |
/azp run runtime-libraries outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
Contributes to #40044, resolves #40075, fixes #40361.
To avoid conflicts, this PR builds on top of #40344, which is expected to be merged first. Please ignore the changes coming from that PR.
I was a bit unsure about the requirements for delegating the Stream and Pipe creation logic to
SocketsHttpConnectionFactory
from the connection. Hope my solution meets the expectations./cc @geoffkizer @scalablecory @stephentoub @halter73 @davidfowl @JamesNK