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