简体   繁体   English

相当于龙卷风中的@inlineCallbacks?

[英]equivalent of @inlineCallbacks in Tornado?

I have lot of code in my Tornado app which looks like this: 我的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()

Obviously inline callbacks would simplify that code a lot, it would look something like: 显然内联回调会简化代码,看起来像:

@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()

Is there a way of having inline callbacks or otherwise simplifying the code in Tornado? 有没有办法在Tornado中进行内联回调或以其他方式简化代码?

You could even factorize the calls. 你甚至可以将呼叫分解。

I think what you do calls one async call after the other, thus not giving a maximum latency improvement. 我认为你所做的就是在另一个之后调用一个异步调用,因此不能提供最大的延迟改进。

If the calls don't have any dependencies (like eg taking the result of one call to do the second call) you could start all calls simultaneously: 如果呼叫没有任何依赖关系(例如,将一个呼叫的结果用于进行第二次呼叫),则可以同时启动所有呼叫:

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

This way, all calls start at the same time and thus your overall latency is the max(all calls) instead of the sum(all calls). 这样,所有呼叫都会同时启动,因此您的总体延迟是最大(所有呼叫)而不是总和(所有呼叫)。

I've used this in an app that need to aggregate many third-party WS or database calls and it improves the overall latency a lot. 我在一个需要聚合许多第三方WS或数据库调用的应用程序中使用它,并且它大大改善了整体延迟。

Of course it doesn't work if there are dependencies between the calls (as mentionned above) 当然,如果调用之间存在依赖关系,则它不起作用(如上所述)

Found it. 找到了。 In Tornado it's not called inline callbacks, but rather "a generator-based interface" — tornado.gen . 在Tornado中,它不是内联回调,而是“基于发电机的接口” - tornado.gen Thus my code should look something like: 因此我的代码应该类似于:

@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()

您也可以考虑使用Cyclone ,它允许您直接使用@inlineCallbacks (以及您想要的任何其他Twisted代码)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM