【发布时间】:2012-02-07 10:07:34
【问题描述】:
我有一个生成文本块的 python 生成器函数。我想为tornado.web.RequestHandler 子类编写一个get 方法,该方法将遍历生成器,将块写入响应中。
因为这是 Tornado,而且生成器可能需要一秒钟的时间来处理,所以我认为最好使处理程序异步,使用这个生成器作为协程并在每个块之后将控制权传递给 IOLoop .但是,我无法确定如何做到这一点。
这是我的示例(阻塞)代码:
class TextHandler(web.RequestHandler):
@web.asynchronous
def get(self, n):
generator = self.generate_text(100000)
# Clearly, this will block. How to make it asynchronous?
for text in generator:
self.write(text)
def generate_text(n):
for x in xrange(n):
if not x % 15:
yield "FizzBuzz\n"
elif not x % 5:
yield "Buzz\n"
elif not x % 3:
yield "Fizz\n"
else:
yield "%s\n" % x
如何使这个处理程序异步工作?
【问题讨论】:
-
目前还不清楚您要实现什么目标。您是否想在迭代所有生成器值之前离开 get(),而不是在新值准备好时返回?如果是这样,那么您就不能这样做。在这个特定的函数中,您的代码是单线程的,如果您退出,那么您将失去上下文。另一方面,标记为异步的方法通常意味着处理程序是从线程池中调用的,所以应该可以在那里阻塞。
-
只要生成器存在,它就有我需要的所有上下文。这就是生成器的美妙之处:单个线程中的协同例程。当然,您必须自己处理调度,这可能是这里真正的问题。
标签: python asynchronous web generator tornado