Is Django post_save signal asynchronous?

DjangoSignals

Django Problem Overview


I have a like function which is just like social networks like or thumbs up function; the user clicks the star / heart / whatever to mark the content as liked.It is done with ajax and must be fast.

The only problem here is that for some reasons I have to do some tasks for each like and I found out they were coded straight in the like view and it makes it slow.

I am thinking of using signals to make the execution of these tasks asynchronous so the view can send back the json right away to the javascript without waiting for the tasks to finish.

I started creating a signal for the like but then realized that Django's signals were not asynchronous and it would end up the same, the view would have to wait for the signal to finish to send back its response.

So I could try to make that signal asynchronous as it is explained here and there but I would as well use the post_save signal for the like model but now I wonder if the view can finish before the signal gets executed?

Django Solutions


Solution 1 - Django

Also look into celery (or more specifically django-celery). It is an async task scheduler / handler. So your post_save signal handler creates a task, which is picked up and executed through celery. That way you still have your speedy application, while the heavy lifting is performed async, even on a different machine or batch of machines.

Solution 2 - Django

What you want is a thread. They're very easy to use. You just subclass threading.Thread and write a run method:

import threading

class LikeThread(threading.Thread):
    def __init__(self, user, liked, **kwargs):
        self.user = user
        self.liked = liked
        super(LikeThread, self).__init__(**kwargs)

    def run(self):
        # long running code here

Then, when your ready to do the task, you fire it off with:

LikeThread(request.user, something).start()

The rest of your view code or whatever will resume and return the response, and the thread will happily do its work until it's done and then end itself.

See full documentation: http://docs.python.org/library/threading.html

Solution 3 - Django

Hm, first of all signals in Django are not asynchronous. For your particular case I think post_save is the wrong way to go. The most straightforward way is simply to fire an ajax request to view which do your like action and don't wait for the response. Instead modify your view/html directly after you fired the request.

That would of course require that you know beforehand that your user is allowed to like this item and that your request will not fail.

Solution 4 - Django

The async-signals package (https://github.com/nyergler/async-signals) abstracts this issue. You call an async signal function; if Celery is present the package uses it to issue the signal asynchronously from a worker; and if Celery is not available the package sends the signal in the traditional synchronous way.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBastianView Question on Stackoverflow
Solution 1 - DjangoBoukeView Answer on Stackoverflow
Solution 2 - DjangoChris PrattView Answer on Stackoverflow
Solution 3 - DjangoTorsten EngelbrechtView Answer on Stackoverflow
Solution 4 - DjangoChris JohnsonView Answer on Stackoverflow