pythonTornado使POST立即返回而异步函数继续工作

2024-06-28 14:46:28 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我下面有一个处理程序:

class PublishHandler(BaseHandler):

    def post(self):
        message = self.get_argument("message")
        some_function(message)
        self.write("success")

我面临的问题是,有些函数需要一些时间来执行,我希望post请求在被调用时立即返回,如果可能的话,一些_function()将在另一个线程/进程中执行。在

我使用伯克利数据库作为数据库,我要做的是相对简单的。在

我有一个用户数据库,每个用户都有一个过滤器。如果过滤器与消息匹配,服务器将向用户发送消息。目前,我正在使用数千个用户进行测试,因此每次通过post请求发布消息时,它都会遍历数千个用户以找到匹配项。这是我对做事的天真实现,因此我提出了问题。我怎样才能做得更好?在


Tags: 用户self数据库消息处理程序过滤器messageget
2条回答

您可以使用IOLoopadd_callback方法来完成此操作,如下所示:

loop.add_callback(lambda: some_function(message))

Tornado将在下一个IOLoop过程中执行回调,这可能会使请求在代码执行之前完成(我必须深入研究Tornado的勇气才能确定,或者测试它)。在

缺点是您编写的长时间运行的代码仍然需要时间来执行,这可能最终会阻止另一个请求。如果你同时收到很多这样的请求,那就不太理想了。在

更简单的解决方案是在单独的线程或进程中运行它。Python最好的方法是使用进程,因为GIL(如果您不熟悉,我强烈建议您阅读一下)。但是,在单处理器机器上,线程实现也可以很好地工作,并且可能更容易实现。在

如果你要走线程化的路线,你可以用互斥体、线程和队列构建一个漂亮的“异步执行器”模块。如果您想使用单独的进程,请查看multiprocessing模块。在

我已经尝试过了,我相信在调用回调之前请求不会完成。在

我认为一个肮脏的黑客会调用两个级别的add\u回调,例如:

  def get(self):
    ...
    def _defered():
      ioloop.add_callback(<whatever you want>)
    ioloop.add_callback(_defered)
    ...

但这些充其量只是黑客。我正在寻找一个更好的解决方案,可能会以一些消息队列或简单线程解决方案结束。在

相关问题 更多 >