websocket.disconnect events are not sent to applications when clients don’t close connections properly (wsproto only)
Checklist
- [x] The bug is reproducible against the latest release and/or
master. - [x] There are no similar issues or pull requests to fix it yet.
Describe the bug
When WebSocket connections are not properly closed by clients, uvicorn + wsproto leaves one zombie asyncio tasks running per connection and do not emit disconnect events to applications.
To reproduce
- Start any application with uvicorn using wsproto;
- Create a websocket connection;
- Do not close the websocket properly;
- Observe that no
websocket.disconnectevents have been sent to your application; - Check for all asyncio tasks (
asyncio.all_tasks()): there should be a zombierun_asgitask for each non properly closed connection.
I’ve setup this repo with instructions to make it easier to reproduce this issue: https://github.com/sephioh/uvicorn-wsproto-issue
Expected behavior
A disconnect event should be sent to applications.
Actual behavior
Disconnect event are not being sent to apps when client socket loss happens.
Environment
Running uvicorn 0.13.4 with CPython 3.9.0 on Linux Must be executed with wsproto (—ws wsproto).
Additional context
https://docs.python.org/3/library/asyncio-protocol.html#asyncio.BaseProtocol.connection_lost
No problems are found when running with websockets impl (—ws websockets).
I’ve opened a PR with a possible fix: https://github.com/encode/uvicorn/pull/996