django / daphne

Django Channels HTTP/WebSocket server
BSD 3-Clause "New" or "Revised" License
2.4k stars 267 forks source link

Are there max requests settings for Daphne? #403

Open alamorre opened 2 years ago

alamorre commented 2 years ago

I have this ASGI applicate with Django and Daphne, and I'm using the following command.

daphne -b 0.0.0.0 -p $PORT server.asgi:application

Is there a way to add --max-requests and --max-requests-jitter to actively prevent memory leaks?

Maybe something like: daphne -b 0.0.0.0 -p $PORT --max-requests 1000 --max-requests-jitter 50 server.asgi:application

carltongibson commented 2 years ago

Not currently, but it might be a good addition. 🤔

This is ref:

https://github.com/django/channels/issues/1789

Were you able to investigate why you're seeing a leak there? Also did it stabilise at 4%? (In which case it may be the Python GC rather than a leak per se — for which it'd keep going up.)

alamorre commented 2 years ago

It's really a verbatim implementation of the tutorial project in the docs. In production it leaks in the picture below.

That's why i think --max-requests with daphne would be awesome. We can let an image teardown before consuming too many resources.

Screen Shot 2022-02-01 at 7 36 47 PM
alamorre commented 2 years ago

I created this draft PR https://github.com/django/daphne/pull/405

Please let me know if this is of interest. I'll polish the code and make some unit tests 👍

WellingtonNico commented 2 years ago

hello guys, i'm using gunicorn now, it has an option to choose the class of workers, in my case i use gthreads(green thread), is there an option like this in daphne?

carltongibson commented 2 years ago

@WellingtonNico No. It wouldn't make much sense. ASGI uses asyncio, with multiple requests handled in the single event loop. You can run multiple instances of Daphne (but you should be a while before you'd need to do that...)

carltongibson commented 1 month ago

The PR in #405 adds a shutdown, but it doesn't reload.

For that we'd need something like Django autoreloader's restart_with_reloader():

https://github.com/django/django/blob/747b417a220b0412ed806001a383959449aac6da/django/utils/autoreload.py#L270-L276

If someone wanted to take that on, it would be worth a look.