私は、テキストの塊を生成するpythonジェネレータ関数を持っています。私はtornado.web.RequestHandler
サブクラスに対して、get
メソッドを記述してジェネレータを反復し、チャンクをレスポンスに書き出します。単純なpythonジェネレータをTornado非同期ハンドラのコルーチンとして使用しますか?
ジェネレータが処理に1秒以上かかる場合があるので、このジェネレータをコルーチンとして使用して、すべての後に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()を終了し、新しい値が準備完了したときに戻ることを希望しますか?もしそうなら、そうすることはできません。この特定の関数では、コードはシングルスレッドであり、終了するとコンテキストが緩やかになります。一方、非同期としてマークされたメソッドは、通常ハンドラを意味し、スレッドプールを形成するので、そこをブロックするのは問題ありません。 – real4x
ジェネレータが存在する限り、必要なすべてのコンテキストを持っています。それはジェネレーターの美しさです。一つのスレッドでの共同作業です。もちろん、自分でスケジューリングを処理する必要がありますが、これはおそらくここでは本当の問題です。 –