Skip to content
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

Slow with Debug=False #1048

Closed
dragonbone81 opened this issue May 18, 2018 · 23 comments
Closed

Slow with Debug=False #1048

dragonbone81 opened this issue May 18, 2018 · 23 comments

Comments

@dragonbone81
Copy link

So I've set up channels, and it works great in debug with websockets connecting and everything is fast.
However as soon as I turn debug=False the speed for any request goes way down (like 5-10 seconds to load the admin page) And as soon as I remove the channels app from installed_apps, the speed is back to normal.

I'm running the server with just the normal (manage.py runserver) as opposed to daphne or something... not sure yet how that works, and I need to limit the workers to only one for now anyways.

Again, it works great with debug on, and with channels app removed, but slows to a crawl when debug is turned on and channels app is installed.

https://github.com/dragonbone81/bobcat-courses-backend

@andrewgodwin
Copy link
Member

That's strange behaviour indeed. You mention it's slow when "debug is turned on and channels app is installed" - which of these actually causes it? Does it only happen when both are true? Basically, can you fill out the fast/slow for each combination of:

  • Debug on, channels installed
  • Debug off, channels installed
  • Debug on, channels not installed
  • Debug off, channels not installed

@dragonbone81
Copy link
Author

  • Debug on, channels installed -> Works good
  • Debug off, channels installed -> Works bad
  • Debug on, channels not installed -> Works good
  • Debug off, channels not installed -> Works good

So yeah it's installing channels, and running with debug off that causes the slowdown, every other combinations works great.

@andrewgodwin
Copy link
Member

OK.

  • Do you have CHANNEL_LAYERS set? If you do, what happens if you set it to {}?
  • Is it only certain URLs that are slow, or all of them?
  • What does the network panel of your browser show is the slow part of the page load - the page itself or the static resources?

@dragonbone81
Copy link
Author

  • Yeah I'm not using CHANNEL_LAYERS. I set it up to a redis database, but wasn't really sure what it was doing, and it didn't look like i was using it. I ran these tests with it set to {}.
  • It's all as far as I can see (admin, DjangoRestFramwork, and the regular urls for my site)
  • The first two pictures are loading the base page of the admin in cached and uncached, and the last on is DRF root api page that just shows all the endpoints in JSON.
    Looks like static resources take a long time to load, but the page itself also takes like 2 seconds.
    unchached_snip
    cached_snip
    json_snip

@andrewgodwin
Copy link
Member

Hm, I'm a bit stumped then. Nothing in Channels should be impacting the normal URL path at all, and I definitely have never seen this happen. Looks like everything takes ages to load.

Just to check, what are the versions of all the packages you have? And do you have any other apps or middleware that could be interfering?

@dragonbone81
Copy link
Author

I disabled 'whitenoise.middleware.WhiteNoiseMiddleware' and the speed of loading has gone up and is now twice as fast. Not sure if I need this middleware, but will test that. However it's still slow, and that's the only middleware i have that's not django's.
I'm going to try to run your example channels app and see what happens :)

I have the latest version of channels and a lot of other packages that are up to date.

@dragonbone81
Copy link
Author

I have found the reason that this occurs.
django_heroku.settings(locals()) I set this at the bottom of setting.py, and removing this causes everything to work nicely. Although I need this to deploy to heroku.

@andrewgodwin
Copy link
Member

Ah! I would suggest that you have separate local dev settings from deployment settings, in that case, and then you can have it work differently per environment. There should be some articles around for different ways to set that up.

@dragonbone81
Copy link
Author

dragonbone81 commented May 18, 2018

So I've tried to replicate what's causing this my manually specifying the staticfiles and database attrs.
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/') STATICFILES_DIRS = ()
This is what I've seen work on production in Heroku, and it does work, but causes slow loads.
Same slowdowns happen on my dev if I use those settings too.

Is there something that channels does to staticfiles that I need to change or add?

@andrewgodwin
Copy link
Member

It overrides a few things to make it work, but it shouldn't matter (and you shouldn't be using staticfiles in production, just collectstatic).

@dragonbone81
Copy link
Author

I'm not understanding, I was following this ->
https://devcenter.heroku.com/articles/django-assets
Where I set up the directories for static files and whitenoise.
Heroku runs python manage.py collectstatic --noinput but this can't run if I don't set the staticfiles directories.

So I'm not sure what I'm doing wrong, and how using staticfiles causes the slowdowns

@andrewgodwin
Copy link
Member

I don't know what's wrong either, I'm afraid. If the example app serves things quickly it's something else you have installed/configured (since that also uses staticfiles), and I unfortunately don't have the time to help with a detailed dive into why :(

@dragonbone81
Copy link
Author

Ok, so I've tried to use your example app in heroku, and I get the same thing. I deployed it without basically touching it apart from adding heroku config stuff like Whitenoise and django-heroku to set up the environmental variables and DB. I've also disabled the Redis logic so the app doesn't really work, but the admin page takes a considerable time to load just like in my app.

https://github.com/dragonbone81/channels-test
https://channels-test-django.herokuapp.com/admin/chat/room/
user: admin pw: admin -> if you want to check it out.

Sorry for using your time. Maybe if someone else has encountered this they can help out, but I've looked around and I can't find a similar issue.

@dragonbone81
Copy link
Author

Is it ok if the issue is opened again? @andrewgodwin

@andrewgodwin
Copy link
Member

Well, an open issue means it is definitely a problem with Channels that can be solved - as in, someone can actively reproduce a bug on a local dev environment and fix it.

When you were saying things were slow, was that always on Heroku or on a local dev copy as well? If it's something that only happens on Heroku I'm afraid there's not much I can do; I can't act as their support team if their Python environment is somehow slightly different...

@dragonbone81
Copy link
Author

dragonbone81 commented May 19, 2018

No I get the same result on my laptop if I use staticfiles with whitenoise and turn debug off.

I don't know if this is an explicit issue with channels, but it must be interferering somehow with staticfiles with debug off.

If the repo I made with your channels app is run, the issue can be reproduced.

@ericls
Copy link
Contributor

ericls commented Jun 21, 2018

The slowness comes from __init__ of WhiteNoise, which scans the STATIC_ROOT folder (https://github.com/evansd/whitenoise/blob/master/whitenoise/base.py#L105) and ASGI handler instantiates middleware classes for each request, a folder scan is performed on each request.

@sciyoshi
Copy link

@andrewgodwin can we reopen this ticket? Seems like @ericls has found the root cause: Channels is breaking Django's API contract which says that a middleware's __init__ will only get called once at server startup.

@andrewgodwin
Copy link
Member

Best to open it as a new ticket - what channels does is still compatible with the API contract, just slower (technically it internally starts a whole new Django stack with each request). I'd class it as an enhancement that we need for speed rather than a bug.

@sciyoshi
Copy link

Thanks @andrewgodwin, we've worked around this by reimplementing whitenoise's static file handling as an ASGI handler. It still think it would be nice for this behavior to be explicitly documented somewhere.

@SHxKM
Copy link

SHxKM commented Jul 8, 2018

@sciyoshi Care to elaborate more how you guys solved this? I'm experiencing the same thing on Heroku and it's killing my web-app.

@sciyoshi
Copy link

sciyoshi commented Jul 9, 2018

@typistX - we wrote our own ASGI handler that serves middleware (pretty short, under 100 lines of code), @ericls could give more details about that. There's also a PR in Whitenoise that seems to be similar, maybe you can give that a shot as well.

@alsib
Copy link

alsib commented Aug 22, 2018

Woops, sorry about that.

I'm experiencing performance loss on API end-points calls when DEBUG=False as well.

Would you have any idea ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants