Python Tornado应用程序中向执行器卸载阻塞功能的通用解决方案
我试图找到一个通用的解决方案,将阻塞任务卸载到Python Tornado应用程序中向执行器卸载阻塞功能的通用解决方案,python,python-3.x,tornado,python-asyncio,Python,Python 3.x,Tornado,Python Asyncio,我试图找到一个通用的解决方案,将阻塞任务卸载到ThreadPoolExecutor 在下面的示例中,我可以使用Tornado的run\u-on\u-executordecorator在NonBlockingHandler中实现所需的非阻塞结果 在asyncifydecorator中,我试图完成同样的事情,但它阻止了其他调用 如何让asyncifydecorator正确工作而不导致修饰函数阻塞 注意:我使用的是Python 3.6.8和Tornado 4.5.3 以下是完整的工作示例: 导入异步I
ThreadPoolExecutor
在下面的示例中,我可以使用Tornado的run\u-on\u-executor
decorator在NonBlockingHandler
中实现所需的非阻塞结果
在asyncify
decorator中,我试图完成同样的事情,但它阻止了其他调用
如何让asyncify
decorator正确工作而不导致修饰函数阻塞
注意:我使用的是Python 3.6.8和Tornado 4.5.3
以下是完整的工作示例:
导入异步IO
从concurrent.futures导入ThreadPoolExecutor
导入功能工具
导入时间
从tornado.concurrent import Future,在执行器上运行
导入tornado.ioloop
导入tornado.web
def异步化(func):
@functools.wrapps(func)
异步def包装(*args,**kwargs):
结果=未来()
执行器(fn)上的def运行:
@functools.wrapps(fn)
def包装(*args,**kwargs):
使用ThreadPoolExecutor(最大工作线程数=1)作为执行器:
返回执行人提交(fn、*args、**kwargs)
返回包装器
@_在执行器上运行
定义函数(*args,**kwargs):
返回函数(*args,**kwargs)
def on_响应(响应):
result.set_result(response.result())
future=_func(*args,**kwargs)
future.add_done_回调(在_响应时)
返回等待结果
返回包装器
类MainHandler(tornado.web.RequestHandler):
def get(自我):
编写(f“Hello,{self.\uuuuuuuu class\uuuuuu.\uuuuuu name\uuuuuuuuu}”)
类AsyncyFifyHandler(tornado.web.RequestHandler):
@异步化
def get(自我):
打印(“睡眠”)
时间。睡眠(5)
编写(f“Hello,{self.\uuuuuuuu class\uuuuuu.\uuuuuu name\uuuuuuuuu}”)
类非阻塞句柄(tornado.web.RequestHandler):
执行器=线程池执行器(最大工作线程数=1)
@在执行器上运行
def阻塞(自):
打印(“睡眠”)
时间。睡眠(5)
编写(f“Hello,{self.\uuuuuuuu class\uuuuuu.\uuuuuu name\uuuuuuuuu}”)
异步def get(自):
结果=未来()
publish=self.blocking()
publish.add\u done\u回调(
lambda response:result.set_result(response.result())
)
返回等待结果
def make_app():
return tornado.web.Application([
(r“/”,主处理器),
(r“/asyncify”,AsyncifyHandler),
(r“/noblock”,非阻塞处理器),
],debug=True)
如果名称=“\uuuuu main\uuuuuuuu”:
app=make_app()
app.listen(8888)
tornado.ioloop.ioloop.current().start()
使用ThreadPoolExecutor退出块等待(同步!)执行器上的所有任务完成。当IOLoop运行时,您不能关闭执行器;只要做一次全球跑步,让它永远跑下去 我通过将包装器更改为:executor=ThreadPoolExecutor(max\u workers=1)使其工作代码>返回执行者。提交(fn,*args,**kwargs)