Q:

Differences between UWSGI and Gunicorn when running async calls

I have a Django app, and in one of my views, I'm actually making an asynchronous call to a function that sends emails. I've both used threading.thread (with start()) as well as a small django package called after_response, which basically does the same.
Here is what I've done:
def my_synchronous_function(instance):
    send_email_asynchronous.after_response(instance.id)
    return "We are done here, but async call will continue."

@after_response.enable
def send_email_asynchronous(instance_id):
    time.sleep(5)
    print "Async has started"
    instance = Instance.objects.get(pk=instance_id)
    subject = "A subject"
    ctx = {'username': instance.username}
    message = get_template("email-template.html").render(ctx)
    msg = EmailMessage(subject, message, to=[instance.email], from_email='loic@example.com')
    print "about to send email"
    time.sleep(5)
    msg.content_subtype = 'html'
    msg.send()
    print "message sent"

This code works great when running django manage.py runserver; it also works just fine when using nginx + gunicorn. However, I've noticed that when using UWSGI and Nginx, the send_email_asynchronous function never gets called. This is true when using after_response as well as the lengthier threading.Thread version:
class SendNotification(threading.Thread):
    """
    Sends notifications async.
    """
    def __init__(self, instance_id):
        """
        Sends notifications asynchronously provided an instance id.
        """
        print "instance id: %s" % instance_id
        self.instance = Instance.objects.get(pk=instance_id)
        super(SendNotification, self).__init__()

    def run (self):
        time.sleep(5)
        print "Async has started"
        subject = "A subject"
        ctx = {'username': self.instance.username}
        message = get_template("email-template.html").render(ctx)
        msg = EmailMessage(subject, message, to=[self.instance.email],                              from_email='loic@example.com')
        print "about to send email"
        time.sleep(5)
        msg.content_subtype = 'html'
        msg.send()
        print "message sent"

This is started in the following manner:
    SendNotification(instance.id).start()
Again, works fine with the dev server "runserver", works also with gunicorn, but not with uwsgi, and I'm a little puzzled as to why this is happening. With uwsgi I actually see the print statement from the init, but not the print statements from the run method, and of course, no email. I've switched to using gunicorn because of this issue, so it is more out of curiosity that I am asking.
Thanks,

A:

You didn't post your uWSGI configuration, but considering this is about background threads not running there's a high chance that you need to add --enable-threads when starting uWSGI:

If you start uWSGI without threads, the Python GIL will not be
  enabled, so threads generated by your application will never run. You
  may not like that choice, but remember that uWSGI is a
  language-independent server, so most of its choices are for
  maintaining it “agnostic”.
But do not worry, there are basically no choices made by the uWSGI
  developers that cannot be changed with an option.
If you want to maintain Python threads support without starting
  multiple threads for your application, just add the --enable-threads
  option (or enable-threads = true in ini style).

