I have a bunch of Django requests which executes some mathematical computations ( written in C and executed via a Cython module ) which may take an indeterminate amount ( on the order of 1 second ) of time to execute. Also the requests don't need to access the database and are all independent of each other and Django.
Right now everything is synchronous ( using Gunicorn with sync
worker types ) but I'd like to make this asynchronous and nonblocking. In short I'd like to do something:
I am very new to asynchronous Django, and so my question is what is the best stack for doing this.
Is this sort of process something a task queue is well suited for? Would anyone recommend Tornado + Celery + RabbitMQ, or perhaps something else?
Thanks in advance!
Django has support for writing asynchronous (“async”) views, along with an entirely async-enabled request stack if you are running under ASGI. Async views will still work under WSGI, but with performance penalties, and without the ability to have efficient long-running requests.
Latest version of the popular Python web framework also provides an asynchronous interface for all data access operations. Django 4.1, a new version of the major Python-based web framework, adds capabilities such as asynchronous handlers and an ORM interface but also makes some backward-incompatible changes.
The ORM is undoubtedly one of the most complex parts of Django and now it is capable of running async queries with the new QuerySet APIs without any major breaking backwards-incompatible changes!
An async view function in Django is detected by the annotation async def , which then runs the async view in a thread within its own event loop. This gives the benefit of being able to do and run tasks concurrently inside the async views.
Celery would be perfect for this.
Since what you're doing is relatively simple (read: you don't need complex rules about how tasks should be routed), you could probably get away with using the Redis backend, which means you don't need to setup/configure RabbitMQ (which, in my experience, is more difficult).
I use Redis with the most a dev build of Celery, and here are the relevant bits of my config:
# Use redis as a queue BROKER_BACKEND = "kombu.transport.pyredis.Transport" BROKER_HOST = "localhost" BROKER_PORT = 6379 BROKER_VHOST = "0" # Store results in redis CELERY_RESULT_BACKEND = "redis" REDIS_HOST = "localhost" REDIS_PORT = 6379 REDIS_DB = "0"
I'm also using django-celery
, which makes the integration with Django happy.
Comment if you need any more specific advice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With