aio-libs / aiohttp-sse

Server-sent events support for aiohttp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Don't swallow asyncio.CancelledError

Olegt0rr opened this issue · comments

No library should be swallowing CancelledError exceptions unconditionally like that, it will just break other people's applications.

async def wait(self) -> None:
"""EventSourceResponse object is used for streaming data to the client,
this method returns future, so we can wait until connection will
be closed or other task explicitly call ``stop_streaming`` method.
"""
if self._ping_task is None:
raise RuntimeError("Response is not started")
with suppress(asyncio.CancelledError):
await self._ping_task

The problem is that your program won't stop when you explicitly told it to stop.

async def my_task():
    while True:
        ...
        await sse_response.wait()

async def main():
    t = asyncio.create_task(my_task())
    await asyncio.sleep(0.5)
    t.cancel()
    with suppress(asyncio.CancelledError):
        await my_task()

This program will never exit.

Originally posted by @Dreamsorcerer in #456 (comment)

Then we discussed that we need to add something like that:

if asyncio.current_task().cancelling():
            raise asyncio.CancelledError

Workaround for python < 3.11

Use delayed sse.stop_streaming() instead of timeout

loop = asyncio.get_event_loop()
loop.call_later(delay, sse.stop_streaming)
await sse.wait()