2014-10-31 64 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

Django信號不是作爲OS信號的異步回調來實現的。當特定的階段/事件完成時,它們一個一個地運行在相同的線程中。所有註冊的信號將在正在處理請求的線程內調用 - 增加處理該請求所需的全部處理。

所以在這個意義上,名稱信號可能會誤導,但它可以仍然有效,因爲信號處理程序將在特定事件觸發(或手動發送某些信號用於自定義信號)時被調用。

0

Django signals不提供任何異步功能。

當發送信號時,所有的接收器都只是在同一個線程中作爲常規函數被觸發。所有說明正在逐步執行。 Django將不會對客戶做出迴應,直到所有接收者完成他們的工作。

Django的信號沒有任何共同之處與socket singals例如,在那裏你可以訂閱一些事件,並聽它不會阻塞線程。

實施例,這裏是模型的django code一部分:

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所有接收器被執行。直到完成後,python纔會繼續下一行。

最受歡迎Django的解決方案是celery,正如你所提到的。 另一種方式是使用非阻塞服務器框架,例如tornado

+1

謝謝@stalk。即使它全部在一個線程上,名稱「request_finished」是否意味着它應該首先發送響應,然後處理該信號?這將允許UI快速,而不需要另一個線程。 – 2014-11-01 15:58:00

相關問題