I have a Django website, and one page has a button (or link) that when clicked will launch a somewhat long running task. Obviously I want to launch this task as a background task and immediately return a result to the user. I want to implement this using a simple approach that will not require me to install and learn a whole new messaging architecture like Celery for example. I do not want to use Celery! I just want to use a simple approach that I can set up and get running over the next half hour or so. Isn't there a simple way to do this in Django without having to add (yet another) 3rd party package?
41
votes
You could just have the server return a Request Received type of response. Then if polling or websockets aren't an option, just have the server update a percent complete value maybe every 10% or 25%. And have a designated area for the user to check any running processes, and display the percent complete. This way the browser is only hitting the server when the user goes to or refreshes the running process page. Then if a process has 100% completion have a link to the results. Just some ideas.
- Ryan G
Note: The server updating the percent complete value is only on the server [eg a DB value]. This can be queried if the user goes to the given page. Also this will depend on how your infrastructure can handle concurrent connections. The running process may block, so you may need to look into something like tornado.
- Ryan G
I doubt very much that anything you write yourself is going to be simpler than just installing Celery and having done with it.
- Daniel Roseman
"I doubt very much that anything you write yourself is going to be simpler than just installing Celery and having done with it." - let's see - I can think of a lot of things simpler than Celery. It's a great bit of software but it's a large glob of code that can handle large scale, high-volume distributed tasks. It requires separate installs of a key-value store, a broker and god knows what else. If you just want to run a background task then I would look for something else.
- Andy Baker
3 Answers
6
votes
If you're willing to install a 3rd party library, but you want something a whole lot simpler than Celery, check out Redis Queue. It does require Redis, which is pretty easy in itself, but that can provide a lot of other benefits as well.
RQ itself has almost zero configuration. It's startlingly simple.
References:
51
votes
Just use a thread.
import threading
t = threading.Thread(target=long_process,
args=args,
kwargs=kwargs)
t.setDaemon(True)
t.start()
return HttpResponse()
See this question for more details: Can Django do multi-thread works?
16
votes
Have a look at django-background-tasks - it does exactly what you need and doesn't need any additional services to be running like RabbitMQ or Redis. It manages a task queue in the database and has a Django management command which you can run once or as a cron job.