2

Tornado アプリには、次のようなコードがたくさんあります。

@tornado.web.asynchronous
def get(self):
    ...
    some_async_call(..., callback=self._step1)

def _step1(self, response):
    ...
    some_async_call(..., callback=self._step2)

def _step2(self, response):
    ...
    some_async_call(..., callback=self._finish_request)


def _finish_request(self, response):
    ...
    self.write(something)
    self.finish()

明らかに、インライン コールバックはそのコードを大幅に簡素化します。次のようになります。

@inlineCallbacks
@tornado.web.asynchronous
def get(self):
    ...
    response = yield some_async_call(...)
    ...
    response = yield some_async_call(...)
    ...
    response = yield some_async_call(...)
    ...
    self.write(something)
    self.finish()

インライン コールバックを使用する方法や、Tornado のコードを単純化する方法はありますか?

4

3 に答える 3

4

呼び出しを因数分解することもできます。

あなたがしていることは、非同期呼び出しを次々と呼び出すため、最大のレイテンシーの改善は得られないと思います。

呼び出しに依存関係がない場合 (たとえば、1 つの呼び出しの結果を取得して 2 番目の呼び出しを行うなど)、すべての呼び出しを同時に開始できます。

@tornado.web.asynchronous
@gen.engine
def get(self):
    responses = yield [ gen.Task(call) for call in required_calls ]

このように、すべての呼び出しが同時に開始されるため、全体的なレイテンシは合計 (すべての呼び出し) ではなく最大 (すべての呼び出し) になります。

多くのサードパーティの WS またはデータベース呼び出しを集約する必要があるアプリでこれを使用したところ、全体的なレイテンシが大幅に改善されました。

もちろん、呼び出し間に依存関係がある場合は機能しません (上記のとおり)。

于 2012-06-27T15:16:41.487 に答える
2

それを見つけた。Tornado では、インライン コールバックではなく、「ジェネレーター ベースのインターフェイス」と呼ばれていますtornado.gen。したがって、私のコードは次のようになります。

@tornado.web.asynchronous
@gen.engine
def get(self):
    ...
    response = yield gen.Task(some_async_call(...))
    ...
    response = yield gen.Task(some_async_call(...))
    ...
    response = yield gen.Task(some_async_call(...))
    ...
    self.write(something)
    self.finish()
于 2012-06-27T12:54:37.877 に答える
2

Cycloneを使用することを検討することもできます。これにより、@inlineCallbacks(および必要な他の Twisted コードを) 直接使用できるようになります。

于 2012-06-27T22:45:09.800 に答える