-
Notifications
You must be signed in to change notification settings - Fork 270
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
TCP bufferbloat if WebSocket server keeps pushing data quickly to a slow client #170
Comments
Could you flesh this out a bit more with how you detected this? That would be valuable for whoever picks this up, so they can verify a fix. |
I just managed to produce this issue.
I observed that daphne's memory usage kept growing (by MB). Reducing ping timeout may help? But that assumes memory usage won't go too high during the timeout. |
also, the ping timeout won't work. because it updates "last_data" even for server side send! I think that's another bug. When server is sending data, it doesn't mean the client/connection is good. |
I tried to install push producer, and captured pauseProducing call from twisted. A trick is I have to unregister the previous producer (HTTPChannel)
Ideally, daphne should forward pauseProducing and resumeProducing to worker |
I've had what I think is a similar/same problem when testing django/django#16384 if generating lots of data from Django (which in a project we do, generating files on-the-fly). Carlton had some code: Having something a view such as: async def generate():
gb_to_send = 5
chunk_size = 5 * 1024 * 1024
total_sent = 0
count = 0
while total_sent < gb_to_send * 1024 * 1024 * 1024:
data = f"{count % 10}" * chunk_size
total_sent += len(data)
count += 1
await asyncio.sleep(0.000001) # change it to make slower / faster
yield data
async def a_streaming_view(request):
return StreamingHttpResponse(generate()) And then using curl and then stopping curl (Control+Z on Linux/Mac shells) or even quitting (Control+C): data is generated using lots of RAM. I can provide a better example if needed / useful. |
Hey @cpina - yes please. If you're able to focus in on what's happening here that would be amazing. (Current plan is to swing back here after Django 4.2a1, so any work before then would be extra handy 🎁) |
👍 I will prepare a self-contained example and write my findings in daphne-Twisted code that might help, hopefully! |
Self contained example to see memory increase: It is the first time that I dive into daphne and Twisted so take the next hypothesis with a pinch of salt! It's possible to see what I think is the size of what needs to be sent to the client in Daphne via (horrible): Also, it seems that Twisted would like to stop the producer since Hopefully this helps somehow! I'm happy to test any possible changes or try to fix it (I need to familiarise myself with the related code first). |
This may be able to be solved by registering a twisted producer and when twisted calls pauseProducing, daphne can just disconnect the client.
Autobahn exports this interface through WebSocket protocols.
The text was updated successfully, but these errors were encountered: