等待Tornado中的AsyncHTTPClient完成的请求

时间:2017-05-15 23:53:32

标签: python tornado

我正在尝试使用PeriodicCallback每X秒调用一次我的函数,但似乎因为AsyncHTTPClient有自己的ioloop它不会阻止它再次运行而不等待以前的结果。

示例:

import os, json, time, tornado.ioloop, tornado.web
from tornado import gen
from tornado.ioloop import PeriodicCallback
from tornado.httpclient import AsyncHTTPClient, HTTPClient, HTTPRequest, HTTPError

http_client = AsyncHTTPClient()
index = 0

@gen.coroutine
def loop():
    global index
    print "ENTER", index
    try:
        response = yield http_client.fetch("https://httpbin.org/delay/5")
        result = json.loads(response.body)
    except HTTPError as e:
        print("Error: " + str(e))
        raise
    finally:
        print "EXIT", index
        index += 1
        raise gen.Return(result)

def ready():
    global index
    index = 0
    print "START"
    callback = PeriodicCallback(loop, 1000) # every second
    callback.start()

if __name__ == "__main__":
    app = tornado.web.Application([])
    app.listen(8888)

    current_ioloop = tornado.ioloop.IOLoop.current()
    current_ioloop.spawn_callback(ready)
    tornado.ioloop.IOLoop.instance().start()

我的期望:

START
ENTER 0
EXIT 0
ENTER 1
EXIT 1
...

我得到了什么:

START
ENTER 0
ENTER 0
ENTER 0
ENTER 0
ENTER 0
ENTER 0
EXIT 0
ENTER 1
EXIT 1
ENTER 2
EXIT 2
ENTER 3
EXIT 3
ENTER 4
EXIT 4
ENTER 5

1 个答案:

答案 0 :(得分:1)

正如您所观察到的,PeriodicCallback和协同程序不能很好地协同工作。最好使用PeriodicCallback并直接用协程实现循环:

@gen.coroutine
def ready():
    global index
    index = 0
    print "START"
    while True:
        result = yield loop()
        # Do something with the result
        print result

请参阅有关此主题的龙卷风文档:

http://www.tornadoweb.org/en/stable/guide/coroutines.html?highlight=periodiccallback#running-in-the-background