Django post_save信号是异步的吗?

Bas*_*ian 35 django signals

我有一个'喜欢'的功能,就像社交网络或赞成功能; 用户点击星标/心脏/任何内容以标记所喜欢的内容.它是用ajax完成的,必须很快.这里唯一的问题是,由于某些原因,我必须为每个'喜欢'做一些任务,我发现它们是在'喜欢'视图中直接编码而且它使它变慢.我正在考虑使用信号来使这些任务的执行异步,因此视图可以立即将json发送回javascript,而无需等待任务完成.我开始为'喜欢'创建一个信号但后来发现Django的信号不是异步的,它最终会一样,视图必须等待信号完成才能发回它的响应.所以我可以尝试使该信号异步,因为它在这里和那里解释但我也会使用post_save信号为'like'模型,但现在我想知道视图是否可以在信号执行之前完成?

Bou*_*uke 39

还要研究芹菜(或更具体地说是django-celery).它是一个异步任务调度程序/处理程序.所以你的post_save信号处理程序创建一个任务,通过芹菜获取并执行.这样,即使在不同的机器或一批机器上,您仍然可以快速应用,同时执行繁重的异步操作.

  • @Symon我很久以前就不再推荐芹菜了。我上次**建议**_研究_芹菜是大约9年前。如果您非常反对这个解决方案,至少与读者分享为什么您认为他们不应该使用芹菜。另外,请_停止_告诉人们该做什么(不该做什么)。你的评论读起来像是对我个人的攻击,而不是提供任何见解。只需提供您的意见并留给读者来确定最适合他们的需求。更好的是,提供一个解决方案并解释为什么它比所提供的其他解决方案更好。 (4认同)
  • 我相信这现在应该是公认的答案!如果其他选项可用,我总是建议不要在代码库中引入多线程,Chris 发布的代码确实显示了“简单”的冰山一角,但在引入多线程时没有提到所有可能的问题。 (2认同)
  • 我有兴趣了解更多是否/为什么芹菜在 2021 年是一个比最初写此答案时明显更糟糕的选择。 (2认同)

Chr*_*att 26

你想要的是一个线程.它们非常容易使用.你只是子类threading.Thread并编写一个run方法:

import threading

class LikeThread(threading.Thread):
    def __init__(self, user, liked, **kwargs):
        self.user = user
        self.liked = liked
        super(LikeThread, self).__init__(**kwargs)

    def run(self):
        # long running code here
Run Code Online (Sandbox Code Playgroud)

然后,当你准备好完成任务时,你用以下方法解雇它:

LikeThread(request.user, something).start()
Run Code Online (Sandbox Code Playgroud)

其余的视图代码或其他任何内容将恢复并返回响应,线程将很乐意完成其工作,直到完成然后结束.

请参阅完整文档:http://docs.python.org/library/threading.html

  • 多处理只是类固醇的线程.您*可以*使用它,但除非您运行的代码值得使用多个核心(提示:您需要使用大型数据集进行一些严格的科学处理以及此类或极其图形密集型工作),使用多处理是浪费时间. (4认同)
  • 这非常有趣; 但我觉得python下的线程受GIL的限制? (2认同)
  • 我知道这是一个较旧的问题/答案,但我相信目前芹菜应该是公认的答案(正如我在芹菜答案中所述)。在代码库中引入多线程可能会带来一系列问题。celery 是专门为解决 OP 的问题而设计的。 (2认同)

Tor*_*cht 7

嗯,首先Django中的信号不是异步的.对于你的特殊情况,我认为post_save是错误的方法.最简单的方法就是触发一个ajax请求来查看你喜欢哪个动作并且不等待响应.而是在您触发请求后直接修改您的view/html.

这当然要求您事先知道您的用户可能喜欢这个项目,并且您的请求不会失败.

  • 在我看来,使用线程是一样的.你将产生线程,继续你的前端处理,不知道线程是否会失败或成功.我在Django中使用线程得到了公平的份额,最后它从来都不是一个好主意(资源方面,从调试的角度来看,等等).如果不好,你的系统中会出现很多僵尸线程.如果您想要异步行为,请使用像芹菜这样的任务处理程序.另一种选择绿色线程与gevent或类似,更便宜. (4认同)
  • 我不是很喜欢将要发生的事情的忠实拥护者,对我来说这是一个肮脏的把戏; (2认同)