2014-10-31 3 views
0

웹 사이트에서 Django View로 ajax를 호출하면 응답을 반환하고 응답이 완료되었다는 신호를 보내길 기대합니다. 나는 이런 식으로 사용할 수도있다 (수면은 요점을 보여주기 위해 사용된다 - 이것은 장기 실행 프로세스 일 수있다).Django의 "request_finished"신호가 응답을 차단하는 이유는 무엇입니까?

from time import sleep 

@receiver(request_finished) 
def comment_added(sender, **kwargs): 
    sleep(5) 
    return 

"잠자기"가 끝날 때까지 AJAX 응답이 차단되어 사용자의 경험이 느려집니다. 신호를 어느 정도 사용하는 목적을 저지하지 않습니까?

저는 이것을 위해 셀러리를 사용할 수 있음을 알고 있습니다. 그러나 신호를 더 잘 이해하고 싶습니다. 감사!

답변

0

장고 신호는 OS 신호처럼 비동기 콜백으로 구현되지 않습니다. 특정 위상/이벤트가 완료 될 때마다 동일한 스레드에서 하나씩 실행됩니다. 모든 등록 된 신호는 요청을 처리하는 스레드 내에서 호출되며 요청을 처리하는 데 필요한 전체 처리가 합산됩니다.

그런 의미에서 신호이 오정렬 일 수 있지만 특정 이벤트가 트리거되거나 (사용자 정의 신호에 대해 일부 신호가 수동으로 전송 될 때) 신호 핸들러가 호출되므로 여전히 유효 할 수 있습니다.

0

Django signals은 비동기 기능을 제공하지 않습니다.

신호가 보내지면 모든 수신기는 같은 스레드에서 일반 기능으로 시작됩니다. 모든 지침이 단계적으로 실행됩니다. Django는 모든 수신자가 작업을 마칠 때까지 클라이언트에 응답하지 않습니다.

장고 신호에는 예를 들어 socket singals과 공통된 것이 없으며 일부 이벤트를 구독하고 스레드를 차단하지 않고 감상 할 수 있습니다.

meta = cls._meta 
    if not meta.auto_created: 
     signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using, 
           update_fields=update_fields) 
    with transaction.commit_on_success_unless_managed(using=using, savepoint=False): 
     if not raw: 
      self._save_parents(cls, using, update_fields) 
     updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) 

singals.pre_save.send는 코드 내의 모든 수신기들이 실행된다 :

실시 예는, 여기에서 모델 django code의 일부이다. 그리고 완료 될 때까지, 파이썬은 다음 줄로 계속되지 않을 것입니다.

django에서 가장 많이 사용되는 솔루션은 언급 한대로 celery입니다. 또 다른 방법은 비 차단 서버 프레임 워크 (예 : tornado)를 사용하는 것입니다.

+1

감사합니다. 비록 그것이 모두 하나의 스레드에 있다고하더라도, "request_finished"라는 이름은 응답을 먼저 보내야한다는 것을 의미하지 않는다. 그러면 다른 스레드를 요구하지 않고도 UI를 빠르게 처리 할 수 ​​있습니다. –