Python Tornado-在异步函数继续工作时立即进行后返回
题
所以我有一个处理程序:
class PublishHandler(BaseHandler):
def post(self):
message = self.get_argument("message")
some_function(message)
self.write("success")
我面临的问题是some_function()需要一些时间来执行,我希望post请求在调用时立即返回,并在可能的情况下在另一个线程/进程中执行some_function()。
我正在使用伯克利DB作为数据库,而我要做的事情相对简单。
我有一个带有过滤器的用户数据库。如果过滤器与消息匹配,则服务器将向用户发送消息。目前,我正在与数千个用户进行测试,因此,在每本消息出版物中,通过邮政请求的每次出版物都会通过数千名用户进行迭代以找到匹配项。这是我对做事的天真实施,因此我的问题。我该怎么做得更好?
解决方案
您可能可以通过使用您的 IOLoop
' add_callback
这样的方法:
loop.add_callback(lambda: some_function(message))
龙卷风将在下一个ioloop通行证中执行回调, 可能 (我必须深入研究龙卷风的胆量,或者对其进行测试)允许在执行该代码之前完成请求。
缺点是,您编写的长期运行代码仍然需要时间来执行,这可能最终阻止了另一个请求。如果您立即提出很多这些请求,那并不理想。
更万无一失的解决方案是在单独的线程或过程中运行它。这 最好的 python的方法是由于GIL而使用一个过程(如果您不熟悉它,我强烈建议您阅读)。但是,在单处理器机器上,螺纹实现将同样良好,并且可能更容易实现。
如果您要去螺纹路线,则可以使用静音,线程和队列构建一个不错的“异步执行器”模块。查看 multiprocessing
如果要使用单独的过程的路由,则模块。
其他提示
我已经尝试过,我相信在调用回调之前,该请求还没有完成。
我认为一个肮脏的黑客是致电两个级别的add_callback,例如:
def get(self):
...
def _defered():
ioloop.add_callback(<whatever you want>)
ioloop.add_callback(_defered)
...
但是这些充其量是骇客。我现在正在寻找一个更好的解决方案,可能最终会得到一些消息队列或简单的线程解决方案。
不隶属于 StackOverflow