почему моя сопрограмма блокирует весь экземпляр торнадо?
from tornado import web, gen
import tornado, time
class CoroutineFactorialHandler(web.RequestHandler):
@web.asynchronous
@gen.coroutine
def get(self, n, *args, **kwargs):
n = int(n)
def callbacker(iterator, callback):
try:
value = next(iterator)
except StopIteration:
value = StopIteration
callback(value)
def factorial(n):
x = 1
for i in range(1, n+1):
x *= i
yield
yield x
iterator = factorial(n)
t = time.time()
self.set_header("Content-Type", "text/plain")
while True:
response = yield gen.Task(callbacker, iterator)
#log.debug("response: %r" %response)
if response is StopIteration:
break
elif response:
self.write("took : %f sec" %(time.time() - t))
self.write("\n")
self.write("f(%d) = %d" %(n, response))
self.finish()
application = tornado.web.Application([
(r"^/coroutine/factorial/(?P\d+)", CoroutineFactorialHandler),
#http://localhost:8888/coroutine/factorial/
])
if __name__ == "__main__":
application.listen(8888)
ioloop = tornado.ioloop.IOLoop.instance()
ioloop.start()
21 строчка выдернута выше - это простой факторный калькулятор. он зацикливается N раз, в генераторной форме.
проблема в том, что когда этот код выполняется, он блокирует весь торнадо.
я хочу написать помощника для торнадо, который рассматривает генераторы как сопрограммы и, следовательно, может обслуживать запросы асинхронно. (Я прочиталИспользование простого генератора Python в качестве подпрограммы в асинхронном обработчике Tornado?)
почему простая петля увеличения и умножения на n блокирует весь торнадо?
редактировать: я отредактировал код, включив в него все приложение, которое вы можете запустить и протестировать. Я'бегущий торнадо 3.1.1 на питоне 2.7