-
Notifications
You must be signed in to change notification settings - Fork 23
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
Support stream cancellation #142
Support stream cancellation #142
Conversation
We now support stream cancellation via the `OutBodyIface` API's `outBodyCancel` function. Some care was taken to ensure that cancelling idle streams does not result in protocol errors. In particular, `outBodyCancel` will wait until either the headers have been sent successfully or an exception occurs. If we aren't totally sure that the headers are sent, we won't send `RST_STREAM`.
@kazu-yamamoto Could you please request a review from @edsko on this as well? Thank you! |
This depends on kazu-yamamoto/http-semantics#11 . |
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.
We realized this is not quite right. We will change the PR.
The 'outputQ' invariant is what guarantees we won't send @RST_STREAM@ frames ahead of some still-enqueued data frames for a stream. Additionally, the previous commit was unnecessarily tracking whether headers had been sent on a stream to deal with a bug which we have now *actually* fixed, so we no longer track whether headers are sent per-stream as we were.
Track whether a stream is finished or cancelled in a `TVar` rather than an `IORef`, and update that `TVar` in a single transaction which also writes the appropriate http-semantics `StreamingChunk` to the queue.
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 looks good to me now, and I think we could merge this now as-is, but I think we can make a two minor improvements (as well as remove that redundant constructor, mentioned above):
- I wonder what should happen with
outBodyPush
etc once the stream is finished. This should be considered a user bug, I think, but it might be good to detect these cases and throw an exception. - Let's try and avoid the redundancy between the two
outBodyIface
constructions (all the more important after we also implement (1).
Network/HTTP2/H2/Types.hs
Outdated
@@ -208,6 +214,7 @@ data HTTP2Error | |||
| StreamErrorIsSent ErrorCode StreamId ReasonPhrase | |||
| BadThingHappen E.SomeException | |||
| GoAwayIsSent | |||
| RSTStreamIsSent |
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.
Is this a leftover from a previous attempt? Doesn't seem to be used anywhere?
There was duplicated code in `Network.HTTP2.Client.Run` and `Network.HTTP2.Server.Worker` to construct a `OutBodyIface`. We have moved that to a dedicated module. We also now throw exceptions when a push or flush is attempted on a concluded stream.
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! @kazu-yamamoto , this PR and kazu-yamamoto/http-semantics#11 and now ready for your review.
I have released |
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
- added http-semantics >= 0.2.1
- formatted with fourmolu
A new version has been released. |
We now support stream cancellation via the
OutBodyIface
API'soutBodyCancel
function. Some care was taken to ensure that cancelling idle streams does not result in protocol errors. In particular,outBodyCancel
will wait until either the headers have been sent successfully or an exception occurs. If we aren't totally sure that the headers are sent, we won't sendRST_STREAM
.