-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Assert in _drain_helper when sending websocket message #2934
Comments
Let's bump this topic. I faced the same problem and found some related issues. |
I'm getting exactly the same on a websocket client using aiohttp 3.6.1.
The issue is triggered by having 50+ concurrent asyncio tasks invoke send_bytes in parallel on the same websocket (the documentation states this should be OK to do). The workaround is to wrap send_bytes in an asyncio.Lock that is shared among all the tasks that operate on the same websocket. |
I also just saw this, and the same fix worked for me. I believe what's happening here is that when messages are large enough to need to be fragmented the exact order of frames on the wire matter (since the CONTINUATION frame needs to directly follow the previous); hence the need for locking so you don't have competing writers. IMHO aiohttp should handle this locking itself as it is required for correctness here. |
aiohttp does not support concurrent ws.send_bytes() so guarding that code with a lock. aio-libs/aiohttp#2934
FYI I have this fixed in CPython upstream python/cpython#94705 and is backported to 3.11 and 3.10. |
Looks like we can probably close this issue then. If nobody has implemented a fix here for 4.5 years, I assume we can just live with the issue in Python 3.7-3.9 for a little longer. |
Does the upstream fix actually... fix this, though? From my understanding of the Websocket protocol, a fragmented message must be contiguous in the TCP stream. I think the situation here is that if I have multiple async tasks trying to write out a message, and a message fragments, only that task must write all its fragments until complete. If any other task writes out anything in between fragments, there will be a protocol error. AFAIK, unless I'm either dramatically misunderstanding the websocket protocol or the upstream change, you will still get occasionally wrong results unless there's some mutexing in aiohttp. |
Think it's possible for you to create a reproducer/test for this? |
Long story short
We see bursts of the following exception on our websocket server.
(paths censored at client's request)
I'm guessing its a flow control issue? We're essentially copying data from one websocket to another and rely on back pressure to keep things running.
I can't reproduce it easily, but happy to investigate if it would help.
Your environment
A websocket server running aiohttp==3.1.0 on Linux
The text was updated successfully, but these errors were encountered: