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

Call PipeWriter.CompleteAsync instead of PipeWriter.Complete #12334

Open
halter73 opened this issue Jul 19, 2019 · 11 comments
Open

Call PipeWriter.CompleteAsync instead of PipeWriter.Complete #12334

halter73 opened this issue Jul 19, 2019 · 11 comments
Labels
affected-few This issue impacts only small number of customers area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions severity-nice-to-have This label is used by an internal tool task
Milestone

Comments

@halter73
Copy link
Member

Now that PipeWriter.CompleteAsync() has been added (https://github.com/dotnet/corefx/issues/39241), we should call PipeWriter.CompleteAsync() wherever we call PipeWriter.Complete() today and wouldn't want to to sync-over-async IO. PipeWriter.Complete() can potentially do sync-over-async IO given a non-default PipeWriter. StreamPipeWriter is the big existing example of this since it will flush the stream in PipeWriter.Complete()/CompleteAsync().

@anurse @davidfowl @jkotalik

@analogrelay
Copy link
Contributor

Necessary for 3.0 or could this be done in 3.1?

@jkotalik
Copy link
Contributor

Really should be in 3.0.

@analogrelay
Copy link
Contributor

analogrelay commented Jul 22, 2019

Should be isn't necessary for though ;). I'm not saying I'll punt it out if we say it's not necessary but I'd like to know what it means to not take this in 3.0

@halter73
Copy link
Member Author

I'd like to know what it means to not take this in 3.0

It means there could be sync-over-async flushes if you use the BodyWriter and don't fully flush it. I am fine with punting this in 3.1.

@davidfowl
Copy link
Member

It means there could be sync-over-async flushes if you use the BodyWriter and don't fully flush it. I am fine with punting this in 3.1.

Not really right, if you call Complete after not having flushed data, in the servers we'll just flush once the app func runs. We should look at override CompleteAsync to return the right task to the caller (if @Tratcher didn't already do that in his PR).

@halter73
Copy link
Member Author

I'm not sure I understand the point you're trying to make @davidfowl.

Complete does always "flush" after the app func runs, but even StreamPipeWriter will elide the flush to the inner stream if all the data has already been flushed. DefaultPipeWriter would similarly have no reason to block on IO if all the data has been flushed by the app.

@halter73
Copy link
Member Author

Are we thinking about flushing trailers? That's somewhat interesting. The workaround would be to call CompleteAsync() yourself, but I can see how that's a real problem.

@halter73
Copy link
Member Author

halter73 commented Jul 27, 2019

BTW, calling PipeWriter.Complete() on Kestrel's HttpResponsePipeWriter will never block, so even the trailers shouldn't be a huge deal. Instead, HttpResponsePipeWriter.Complete() calls CompleteAsync() ands stores the task in a field so it can be awaited later in the request processing loop before we start processing the next request.

https://github.com/aspnet/AspNetCore/blob/98abd9e256f5a204d706d91793da950680f41061/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs#L40

That said, a surgical fix to call PipeWriter.CompleteAsync() instead of PipeWriter.Complete() in the OnCompleted() callbacks added by response body wrappers would be very trivial, and probably worthwhile.

@davidfowl
Copy link
Member

Are we thinking about flushing trailers? That's somewhat interesting. The workaround would be to call CompleteAsync() yourself, but I can see how that's a real problem.

Yes.

BTW, calling PipeWriter.Complete() on Kestrel's HttpResponsePipeWriter will never block, so even the trailers shouldn't be a huge deal. Instead, HttpResponsePipeWriter.Complete() calls CompleteAsync() ands stores the task in a field so it can be awaited later in the request processing loop before we start processing the next request.

Sure that's what I was getting at, the caller can't observe it inline but it doesn't cause any problems. Seems like we could override CompleteAsync and expose the task to the caller.

That said, a surgical fix to call PipeWriter.CompleteAsync() instead of PipeWriter.Complete() in the OnCompleted() callbacks added by response body wrappers would be very trivial, and probably worthwhile.

We do that already.

@Tratcher
Copy link
Member

Except flushing in OnCompleted() fails because the response has already been cleaned up. The only thing calling CompleteAsync in OnCompleted accomplishes is returning buffers, and that is always synchronous, right?

@davidfowl
Copy link
Member

Except flushing in OnCompleted() fails because the response has already been cleaned up. The only thing calling CompleteAsync in OnCompleted accomplishes is returning buffers, and that is always synchronous, right?

Pretty much. But we can't know what other implementations will do.

@analogrelay analogrelay modified the milestones: Backlog, 5.0.0-preview1 Sep 17, 2019
@analogrelay analogrelay removed this from the 5.0.0-preview1 milestone Mar 11, 2020
@analogrelay analogrelay added this to the Backlog milestone Mar 23, 2020
@jkotalik jkotalik added affected-few This issue impacts only small number of customers severity-nice-to-have This label is used by an internal tool task labels Nov 12, 2020 — with ASP.NET Core Issue Ranking
@halter73 halter73 removed their assignment Jul 14, 2021
@amcasey amcasey added the area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions label Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affected-few This issue impacts only small number of customers area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions severity-nice-to-have This label is used by an internal tool task
Projects
None yet
Development

No branches or pull requests

7 participants