【发布时间】:2015-02-28 23:12:28
【问题描述】:
单个 Tornado RequestHandler 类可以处理新请求,同时等待 Future 在其中一个实例中完成吗?
我正在调试一个调用 ThreadPoolExecutor 的 Tornado 协程,我注意到,在协程等待执行程序完成时,RequestHandler 被阻塞了。因此,对这个处理程序的任何新请求都在等待协程完成。
这是我为重现我的观察而编写的代码:
from time import sleep
from concurrent.futures import ThreadPoolExecutor
from tornado.ioloop import IOLoop, PeriodicCallback
from tornado.web import Application, RequestHandler
from tornado.gen import coroutine
class Handler1(RequestHandler):
@coroutine
def get(self):
print('Setting up executor ...')
thread_pool = ThreadPoolExecutor(1)
print('Yielding ...')
yield thread_pool.submit(sleep, 30)
self.write('Ready!')
print('Finished!')
app = Application([('/1$', Handler1)])
app.listen(8888)
PeriodicCallback(lambda: print('##'), 10000).start()
IOLoop.instance().start()
现在,如果我访问 localhost:8888/1 两次,我会得到以下输出:
##
Setting up executor ...
Yielding ...
##
##
##
Finished!
Setting up executor ...
Yielding ...
##
##
##
Finished!
##
但我预计会发生以下情况:
##
Setting up executor ...
Yielding ...
Setting up executor ...
Yielding ...
##
##
##
Finished!
Finished!
##
请注意,似乎只有 RequestHandler 被阻止,因为我们仍然每 10 秒获得一次 ##。实际上,如果您添加另一个相同的 RequestHandler (Handler2) 并访问 localhost:8888/1 和 localhost:8888/2,这将产生预期的输出。
这正常吗?这是预期的行为吗?
对不起,我的英语不好。
【问题讨论】:
标签: tornado nonblocking coroutine requesthandler concurrent.futures