Search code examples
pythondjangoplotlyload-balancingplotly-dash

django-plotly-dash multi session on CPU intensive pages


Running django-plotly-dash, I have multiple python pages. The issue is that when I am loading one of the pages while it is running some calculations, I can not run the same page or other pages from a different session, and the webserver is not responding for other users. If I look at the runserver output, it is busy rendering the first request only.


Solution

  • If I look at the runserver output, it is busy rendering the first request only.

    If I understand correctly, this means you use Django's development server, and thus that you are in development (if you use django-admin runserver in production, that's a serious issue).

    Now’s a good time to note: don’t use this server in anything resembling a production environment. It’s intended only for use while developing. (We’re in the business of making web frameworks, not web servers.)

    Django's development server is supposed to be multithreaded and support concurrent requests. However, from my experience I also noticed that it can handle only one request at a time. I didn't dig too much into it but I assume it might be caused by an app that overrides the runserver command and disables multithreading.

    In development this shouldn't be too much of an issue. And in production you won't suffer this kind of blocks as real WSGI servers such as gunicorn will be able to handle several concurrent requests (provided it is configured to use the available resources correctly, and the hardware is able to handle the load).

    However if your pages are actually slow to respond, this can be an issue for the user loading the page, and will also require more resources to handle more concurrent requests. It all depends if "slow" means 2 seconds, 5 seconds, 30 seconds or even more. Reducing the response time will depend a lot on the bottleneck of your code and could include:

    • Optimizing the algorithms
    • Reducing and optimizing SQL queries (See Database access optimization)
    • Delaying to Celery the calculations that do not affect the response
    • Using websockets to flow and display the data as they get calculated without blocking the client until the whole page is calculated. (See django-channels)
    • Using asyncio to avoid staying idle while waiting for I/O operations.