为什么Django的“request_finished”信号会阻止响应?

时间:2014-10-31 06:40:41

标签: python ajax django signals django-signals

如果我有从网站到Django View的ajax调用,我希望它返回一些响应并发送响应已完成的信号。我可能会使用类似的东西(睡眠仅用于演示一点 - 这可能是任何长时间运行的过程)。

from time import sleep

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

AJAX响应将被阻止,直到" sleep"完成后,使用户体验变慢。这不会在某种程度上破坏使用信号的目的吗?

我知道我可以使用Celery,我打算这样做。但我想更好地了解信号。谢谢!

2 个答案:

答案 0 :(得分:0)

Django信号不像OS信号那样实现为异步回调。当特定阶段/事件完成时,它们一个接一个地运行在同一个线程中。所有注册的信号都将在处理请求的线程中被调用 - 累加处理该请求所需的总处理。

因此,在这个意义上,名称​​ signal 可能会误导,但它仍然有效,因为在触发特定事件时会调用信号处理程序(或手动发送一些信号用于自定义信号)。

答案 1 :(得分:0)

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

发送信号时,所有接收器都在同一个线程中作为常规函数触发。所有说明都在逐步执行。 Django不会回复客户,直到所有接收者都完成他们的工作。

Django信号与socket singals没有任何共同之处,例如,您可以订阅某个事件并在不阻塞线程的情况下收听它。

示例,这是Model 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