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

Fix Stream Callback never being called in close #2905

Merged
merged 9 commits into from Nov 15, 2022
Merged

Conversation

0xTim
Copy link
Member

@0xTim 0xTim commented Nov 8, 2022

Fixes a bug where abandoned requests mean that the stream callback is never invoked. This happens when a client sends a request, the server starts processing it but hasn't constructed the Response and then the client closes early. The response is discarded, as is the stream callback so it never gets invoked. This fixes that issue

@0xTim 0xTim added the semver-patch Internal changes only label Nov 8, 2022
@0xTim 0xTim requested a review from gwynne November 8, 2022 10:16
@@ -50,13 +50,17 @@ final class HTTPServerHandler: ChannelInboundHandler, RemovableChannelHandler {
if !keepAlive {
context.close(mode: .output, promise: nil)
}
case .failure(ChannelError.ioOnClosedChannel):
Copy link
Contributor

Choose a reason for hiding this comment

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

quick question: why only when .ioOnClosedChannel? I would've thought that this needs to be done on any write error. And even if there's no write error but the connection goes away we should notify the user, right?

CC @Lukasa

Copy link
Member Author

Choose a reason for hiding this comment

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

Shouldn't errorCaught(context:error:) function be triggered in all cases as well so the error can be bubbled up and handled?

Copy link
Contributor

Choose a reason for hiding this comment

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

@0xTim the problem at hand isn't that Vapor doesn't know about the error, it's that the user doesn't learn about it, right? So I'm not sure why other errors aren't handled similarly. Not saying it's wrong, just don't quite follow

Comment on lines +54 to +56
if case .stream(let stream) = response.body.storage {
stream.callback(ErrorBodyStreamWriter(eventLoop: request.eventLoop, error: error))
}
Copy link
Member Author

Choose a reason for hiding this comment

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

@weissi can you see any problem with this? I've taken a look at it and it seems to make sense we should call call errorCaught and trigger the stream callback if we have them

Copy link
Member

@gwynne gwynne left a comment

Choose a reason for hiding this comment

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

LGTM... I think 😅

@0xTim 0xTim merged commit e227a63 into main Nov 15, 2022
@0xTim 0xTim deleted the channel-close-error branch November 15, 2022 18:46
@VaporBot
Copy link
Contributor

These changes are now available in 4.67.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-patch Internal changes only
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants