2016-06-20 2 views
0

장고 앱이 있고 제 견해 중 하나에서 실제로 이메일을 보내는 함수에 비동기 호출을하고 있습니다. 나는 threading.thread (start()로)와 after_response라는 작은 django 패키지를 사용했다. 기본적으로는 동일하다. 여기 비동기 호출을 실행할 때 UWSGI와 Gunicorn의 차이점

내가 무슨 짓을했는지이다 : 장고 manage.py의 runserver를 실행하는 경우

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='[email protected]') 
    print "about to send email" 
    time.sleep(5) 
    msg.content_subtype = 'html' 
    msg.send() 
    print "message sent" 

이 코드는 잘 작동합니다; nginx + gunicorn을 사용할 때도 잘 작동합니다. 그러나, 나는 UWSGI와 Nginx를 사용할 때 send_email_asynchronous 함수가 결코 호출되지 않는다는 것을 알아 차렸다. 이것은 다음과 같은 방식으로 시작

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='[email protected]') 
     print "about to send email" 
     time.sleep(5) 
     msg.content_subtype = 'html' 
     msg.send() 
     print "message sent" 

:

다시 sendNotification에 (instance.id) .start(), 잘 작동 after_response뿐만 아니라 더 긴 threading.Thread 버전을 사용하는 경우 마찬가지입니다 dev 서버 "runserver"는 gunicorn에서도 작동하지만 uwsgi에서는 작동하지 않습니다. 왜 이런 일이 일어나고 있는지에 대해 약간 당황 스럽습니다. uwsgi을 사용하면 실제로 의 print 문을 볼 수 있지만 run 메서드의 print 문은 물론 전자 메일도 표시되지 않습니다. 나는이 문제로 인해 gunicorn을 사용하기로 바꿨으므로 내가 묻는 것은 더 이상 호기심에서 벗어난다.

감사합니다,

답변

1

당신은 당신의 uWSGI 구성을 게시하지 않았지만, 생각이 당신 need to add --enable-threads이 uWSGI를 시작 높은 기회가있어 실행되지 백그라운드 스레드에 관한 것입니다 :

당신은없이 uWSGI를 시작하는 경우 스레드를 사용하는 경우 Python GIL은 이 아니므로 응용 프로그램에서 생성 된 스레드가 실행되지 않습니다. 은 그 선택을 좋아하지 않을 수 있지만 uWSGI는 언어 독립적 서버 이므로 대부분의 선택은 에 대해 "불가지론 적"으로 유지됩니다.

하지만 기본적으로 uWSGI 개발자가 옵션으로 변경할 수없는 선택 항목이 없습니다.

응용 프로그램에 다중 스레드를 시작하지 않고 파이썬 스레드 지원을 유지하려면 --enable-threads 옵션을 추가하거나 ini 스타일에서 enable-threads = true를 추가하십시오.

+0

답변 해 주셔서 감사합니다. 이것이 내가 uWSGI에서 겪었던 문제라고 생각합니다. --enable-threads를 추가하는 것이 트릭을하는 것처럼 보입니다. –