-
-
Notifications
You must be signed in to change notification settings - Fork 932
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 listener task to cancel streaming response in case of an early disconnect #839
Add listener task to cancel streaming response in case of an early disconnect #839
Conversation
Okay, this is looking decent yup! I happened to inroduce a I reckon we ought to use that here, and have |
@tomchristie Sure, I'll adjust the code this evening. Just to be clear, you meant something like this: await run_until_first_complete(self.stream_response(send), self.listen_for_disconnect(receive)) Right? |
@Kamforka Yup, I'll be along these lines... await run_until_first_complete(
(self.stream_response, {"send": send}),
(self.listen_for_disconnect, {"receive": receive})
) |
@tomchristie added the changes. However I have one observation. Is there any particular reason for the signature of async def run_until_first_complete(*args: typing.Tuple[typing.Callable, dict]) -> None I think the following signature would be more intuitive: async def run_until_first_complete(tasks: typing.Sequence[typing.Awaitable]) -> None:
So in our particular case one could call it like: await run_until_first_complete(
[self.stream_response(send), self.listen_for_disconnect(receive)]
) As far as I can tell the functionality is the same, however we get less boilerplate with better typing and auto-completion experience. What do you think? |
starlette/responses.py
Outdated
@@ -1,3 +1,4 @@ | |||
import asyncio |
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.
Looks like we can drop this now, right?
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.
Oh yeah
Good suggestion yup, although I’m also keeping half an eye here on trio compatibility, which it wouldn’t play so well with. |
What do you mean by trio compatibility? |
We might want a future version of Starlette to support being run on Trio https://trio.readthedocs.io/en/stable/ as an alternative to Asyncio. The API that Trio uses for starting tasks doesn't allow passing instantiated coroutines (for some good reasons) so keeping this constraint in our own codebase would make it easier for us support Trio at some point. |
And, great stuff, thank you! |
Got it, thanks for the clarification! |
Related to #20
This one is to fix an ongoing stream to an already disconnected client.
All the existing tests are passed, however I'd like to add one to cover a scenario when a
"http.disconnect"
message is sent via thereceive
channel, @tomchristie maybe you could suggest some sort of setup for such a test?