Uh oh!
There was an error while loading. Please reload this page.
Refactor Task Socket.ConnectAsync methods to use AwaitableSocketAsyncEventArgs - #787
Conversation
tmds
commented
Dec 12, 2019
@dotnet/ncl @stephentoub this PR is not finished but I'd like some early feedback. It seems github doesn't allow me to mark this as Draft and still do a CI run. Can you please mark this as no-merge? |
749388f to
ffcc63aComparestephentoub
commented
Dec 12, 2019
Thanks, @tmds. I'm concerned about doing something like this until https://github.com/dotnet/corefx/issues/39466 is addressed. |
Uh oh!
There was an error while loading. Please reload this page.
stephentoub
commented
Dec 12, 2019
Although, looking at the change in more detail now, it seems you're not reusing the SAEA across sockets, only using it for that one socket? In which case maybe this isn't a big deal, because the SAEA will only be storing the same socket that it's being used with? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
tmds
commented
Dec 12, 2019
Yes, it's on the Socket where it was used to Connect, so not keeping another Socket alive. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
stephentoub
commented
Jan 15, 2020
@tmds, some of these test failures look relevant. |
tmds
commented
Jan 15, 2020
This test is now failing on Windows: [Fact]publicasyncTaskCtor_NotStream_ThrowsIOException(){using(Socketlistener=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp))using(Socketclient=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp)){listener.Bind(newIPEndPoint(IPAddress.Loopback,0));awaitclient.ConnectAsync(newIPEndPoint(IPAddress.Loopback,((IPEndPoint)listener.LocalEndPoint).Port));Assert.Throws<IOException>(()=>newNetworkStream(client));}}Instead of throwing at the expected location, it's throwing on the ConnectAsync call above: I'm missing the fallback for connectionless protocols that is part of BeginConnect: runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs Lines 2057 to 2074 in 3d7fcaf I'll add this and check if there are other things which may be missing. |
stephentoub
commented
Jan 15, 2020
Thanks. |
4745f62 to
6404854Comparetmds
commented
Feb 10, 2020
The latest change was to change if(CanUseConnectEx(endPointSnapshot)){socketError=e.DoOperationConnectEx(this,_handle);}else{// For connectionless protocols, Connect is not an I/O call.socketError=e.DoOperationConnect(this,_handle);}I'm not sure if all parts of the
with stacktrace From the error message I'd guess I don't have a Windows machine to debug. |
tmds
commented
Feb 11, 2020
@karelz can someone help me with this? |
tmds
commented
Feb 27, 2020
@antonfirsov maybe you can have a look? |
antonfirsov
commented
Feb 27, 2020
@tmds your assumption was correct, This is even worse on master, since the original stringpath=Path.Combine(Path.GetTempPath(),Path.GetRandomFileName());varendPoint=newUnixDomainSocketEndPoint(path);usingvarserver=newSocket(AddressFamily.Unix,SocketType.Stream,ProtocolType.Unspecified);usingvarclient=newSocket(AddressFamily.Unix,SocketType.Stream,ProtocolType.Unspecified);server.Bind(endPoint);server.Listen(1);usingvarmre=newManualResetEventSlim(false);usingvarsea=newSocketAsyncEventArgs(){RemoteEndPoint=endPoint};sea.Completed+=(_,__)=>mre.Set();if(client.ConnectAsync(sea))mre.Wait();Assert.Equal(SocketError.Success,sea.SocketError);@stephentoub I wonder if I should create a separate issue for this or should we just add the fix to this PR for the sake of simplicity? |
A possible fix on my branch: I had to change the expected exception for the test case to My branch is also in sync with the current master, fixed two minor conflicts from #32675. @tmds can I update this PR with all these changes? Note that |
My preference would be to keep the bug fix and refactoring separate, ideally two PRs, but it could be two commits we don't squash if necessary. |
tmds
commented
Mar 2, 2020
Thanks for having a look @antonfirsov! I hope Windows CI will now pass.
|
antonfirsov
commented
Mar 2, 2020
@tmds a few points: The Windows build is still failing in
Have you also tried to address this?
This means that we should enable this test now on Windows. Additionally, I was unable to find any confirmation for the old behavior in our docs, which supports my argument that this was simply a bug. Any chance you can create a separate bugfix PR as @stephentoub suggested? |
tmds
commented
Mar 3, 2020
I'll rewrite the PR in 2 commits when it compiles and tests pass.
This is another Windows-specific problem? Can you take a look? I wonder what the SocketError is in |
tmds
commented
Mar 10, 2020
@antonfirsov can you take a look at the remaining Windows issue? |
antonfirsov
commented
Mar 10, 2020
@tmds sure, was planning to do so today. |
tmds
commented
Mar 17, 2020
Thank you @antonfirsov ! I have included these changes. When CI passes, I will put UDP Connect(saea) into a separate PR. |
tmds
commented
Mar 17, 2020
CI shows unrelated test failures in And |
| [InlineData(65536)] | ||
| public async Task ConnectAsync_IPAddresses_InvalidPort_Throws_ArgumentOutOfRange(int port) | ||
| { | ||
| await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => GetSocket().ConnectAsync(new[] { IPAddress.Loopback }, port)); |
There was a problem hiding this comment.
This requires await to throw. The check could be added in the Task ConnectAsync directly.
| socket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); | ||
| socket.Listen(1); | ||
| Assert.Throws<InvalidOperationException>(() => { socket.ConnectAsync(new[] { IPAddress.Loopback }, 1); }); | ||
| await Assert.ThrowsAsync<InvalidOperationException>(() => socket.ConnectAsync(new[] { IPAddress.Loopback }, 1)); |
There was a problem hiding this comment.
This requires await to throw. The check could be added in the Task ConnectAsync directly.
| } | ||
| if (usesApm) | ||
| if (UsesApm) |
There was a problem hiding this comment.
The exception thrown by the Task ConnectAsync methods has changed. The exceptions are now consistent with other Task-returning Socket methods.
tmds
commented
Apr 6, 2020
With #33674 merged, I've rebased this PR. I've added some comments with the test changes that indicate changed behavior. |
No description provided.