如何将应用程序引擎的异步调用移植到龙卷风?

时间:2011-11-09 21:46:58

标签: google-app-engine asynchronous tornado

App-engine异步示例:

from google.appengine.api import urlfetch

rpc = urlfetch.create_rpc()
urlfetch.make_fetch_call(rpc, "http://www.google.com/")

try:
    result = rpc.get_result()
    if result.status_code == 200:
        text = result.content
        # ...
except urlfetch.DownloadError:
    raise
return text

我如何在龙卷风中这样做?我尝试过(使用swirl)类似的东西:

import swirl

http = tornado.httpclient.AsyncHTTPClient()
uri = 'http://www.google.com/'

try:
    response = yield lambda cb: http.fetch(uri, cb)
    if response.code == 200:
        text = result.content
        # ...
except tornado.httpclient.HTTPError:
    raise
return text

但是我得到一个语法错误,因为我在同一个函数中没有返回和收益...

2 个答案:

答案 0 :(得分:0)

似乎漩涡不提供任何从协同程序返回值的工具。使用此模式的其他框架(如NDB)允许您引发特殊的“返回异常”,或者产生返回值,但漩涡似乎不提供此选项。您需要重新构建协程,而不是返回值。

答案 1 :(得分:0)

如果你有一个标有RequestHandler装饰器的龙卷风@gen.coroutine,你可以使用Futureyield关键字来完成你想要的。

对于返回异步HTTP提取结果的简单情况,AsyncHTTPClient.fetch方法就足够了:

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        def handle_response(response):
            if response.error:
                print("Error: %s" % response.error)
            else:
                self.write(response.body)

        http_client = AsyncHTTPClient()
        yield http_client.fetch('http://www.google.com/', handle_response)

要创建一个异步返回任意结果的函数,您需要创建自己的Future对象以返回给调用者。假设您的函数需要在返回自定义值之前进行异步Web提取:

def get_async_result():
    future = Future()

    def handle_response(response):
        if response.error:
            future.set_exception(Exception("Yikes"))
        else:
            future.set_result("I, for one, welcome our new robot overlords.")
    http_client = AsyncHTTPClient()
    http_client.fetch('http://www.google.com/', handle_response)
    return future

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        result = yield get_async_result()
        print result    # "I, for one, welcome our new robot overlords."
        # rest of handler here...

RequestHandler中的yield语句在逻辑上阻塞,直到返回的Future完成,直接为您提供结果(或异常)。

(请注意as explained here你不能在Google App Engine中使用Tornado的异步机制。)