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

Add Task-based async API for Socket.SendFile #42591

Closed
geoffkizer opened this issue Sep 22, 2020 · 14 comments · Fixed by #53062
Closed

Add Task-based async API for Socket.SendFile #42591

geoffkizer opened this issue Sep 22, 2020 · 14 comments · Fixed by #53062
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Net.Sockets
Milestone

Comments

@geoffkizer
Copy link
Contributor

Background and Motivation

We have an APM version of this and a SocketAsyncEventArgs version, but no Task-based version.

Current APM:

    public IAsyncResult BeginSendFile(string fileName, AsyncCallback? callback, object? state);
    public IAsyncResult BeginSendFile(string? fileName, byte[]? preBuffer, byte[]? postBuffer, TransmitFileOptions flags, AsyncCallback? callback, object? state); 

Proposed API

    public ValueTask SendFileAsync(string fileName);
    public ValueTask SendFileAsync(string? fileName, byte[]? preBuffer, byte[]? postBuffer, TransmitFileOptions flags);
@geoffkizer geoffkizer added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Sep 22, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net.Sockets untriaged New issue has not been triaged by the area owner labels Sep 22, 2020
@ghost
Copy link

ghost commented Sep 22, 2020

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@geoffkizer geoffkizer added this to the 6.0.0 milestone Sep 22, 2020
@geoffkizer geoffkizer added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Sep 22, 2020
@jeffschwMSFT jeffschwMSFT removed the untriaged New issue has not been triaged by the area owner label Sep 22, 2020
@terrajobst
Copy link
Member

terrajobst commented Sep 22, 2020

Video

  • Makes sense, but we should take a cancellation tokena and memories
namespace System.Net.Sockets
{
    public partial class Socket
    {
        // Existing APM APIs
        // public IAsyncResult BeginSendFile(string fileName, AsyncCallback? callback, object? state);
        // public IAsyncResult BeginSendFile(string? fileName, byte[]? preBuffer, byte[]? postBuffer, TransmitFileOptions flags, AsyncCallback? callback, object? state);
        public ValueTask SendFileAsync(string? fileName, CancellationToken cancellationToken = default);
        public ValueTask SendFileAsync(string? fileName, ReadOnlyMemory<byte> preBuffer, ReadOnlyMemory<byte> postBuffer, TransmitFileOptions flags, CancellationToken cancellationToken = default);
    }
}

@terrajobst terrajobst added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Sep 22, 2020
@stephentoub stephentoub added the help wanted [up-for-grabs] Good issue for external contributors label Sep 22, 2020
@gfoidl
Copy link
Member

gfoidl commented Sep 23, 2020

@stephentoub can you assign this to me?
(Will do a PR in the next couple of days)

@stephentoub
Copy link
Member

Sure :-) Thanks. Cancellation will be the trickiest part; the rest should be very straightforward.

@stephentoub stephentoub assigned stephentoub and gfoidl and unassigned stephentoub Sep 23, 2020
@stephentoub stephentoub removed the help wanted [up-for-grabs] Good issue for external contributors label Sep 23, 2020
@gfoidl
Copy link
Member

gfoidl commented Sep 24, 2020

Note to myself: don't forget to update the ref-assemblies.

@gfoidl
Copy link
Member

gfoidl commented Oct 5, 2020

Can the windows-version actually be cancelled (in a nice way)?

The code goes down to

return Interop.Mswsock.TransmitFile(
socket, fileHandlePtr, 0, 0, overlapped,
needTransmitFileBuffers ? &transmitFileBuffers : null, flags);
which is TransmitFile function (mswsock.h) and I don't see any functionality for cancellation.

For the unix-version existing code can be reused (after tweaking a little bit).

@gfoidl
Copy link
Member

gfoidl commented Oct 5, 2020

Has cancelling on windows be done via

private unsafe void RegisterToCancelPendingIO(NativeOverlapped* overlapped, CancellationToken cancellationToken)
(resp. Interop.Kernel32.CancelIoEx)?

(Now I understand why you wrote tricky).

@stephentoub
Copy link
Member

Interop.Kernel32.CancelIoEx

Yup

Now I understand why you wrote tricky

😉

@geoffkizer
Copy link
Contributor Author

@gfoidl Are you still looking at this?

This is the last issue blocking #43845, which I'd really like to get done for .NET 6.

@gfoidl
Copy link
Member

gfoidl commented Apr 29, 2021

I got lost a bit in all the issue around sockets and especially for SendPacketsAsync...need to revive the branches.

For Unix it's quite straight-forward including cancellation.

For Windows we talked about basing it on SendPacketsAsync which can't be canceled (at least last time I checked). There's #48477 but I don't know the state of that issue. Also SendPacketsAsync has quite some allocations that TransmitFile could avoid, but that's more effort and larger SAEA which we want to avoid.

I'll prepare a PR based on SendPackets, as it's easier to move forward. We can optimize that later on.

Can this issue / PR wait for Mon / Tue next week? (need to find a fix a 🐞 in my code, so can look into this over the weekend)

@geoffkizer
Copy link
Contributor Author

Can this issue / PR wait for Mon / Tue next week? (need to find a fix a 🐞 in my code, so can look into this over the weekend)

Yeah, it's not urgent, I just want to make sure we can get this in for 6.0.

For Unix it's quite straight-forward including cancellation.

For Windows we talked about basing it on SendPacketsAsync which can't be canceled (at least last time I checked).

If we base it on SendPacketsAsync, this would work for both Windows and Unix, which is preferred -- we don't want to have more platform-specific code here if we can avoid it.

SendPacketsAsync can't be cancelled, but the way we have done cancellation for other Task-based APIs is to have an internal version that does support cancellation. You should see this pattern for other APIs like Send, Receive, etc.

That said, cancellation support here is a bit ugly currently. I would be fine with punting cancellation support for a first PR -- we need to address cancellation for a couple different operations anyway, including Accept (see #33418) and Disconnect (see #51452). It probably makes sense to tackle all of these at once. @antonfirsov thoughts?

@antonfirsov
Copy link
Member

I'm fine getting this in with SendPacketsAsync to get the refactoring story done. First I was afraid of regressing Windows perf with those allocations, but today's APM solution is allocating anyways.

I'm wondering if we should also publish SendFileAsync(SocketAsyncEventArgs) for API symmetry?

@geoffkizer
Copy link
Contributor Author

I'm wondering if we should also publish SendFileAsync(SocketAsyncEventArgs) for API symmetry?

We could consider it, but I don't think it's a priority. It doesn't add anything that SendPacketsAsync can't do.

@karelz
Copy link
Member

karelz commented May 13, 2021

Triage: Cancellation implementation is missing. Fine to move to Future.
We should create new issue to track that and close this one.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label May 21, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label May 27, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 26, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Net.Sockets
Projects
None yet
8 participants