Python tornado并行请求使用协同程序和处理异常

时间:2015-07-01 13:26:31

标签: python asynchronous exception-handling tornado coroutine

我最近开始使用python tornado。

我现在使用回调做了一个小项目 我试图找出如何使用协同程序 让我的生活更容易(或更难)

我有以下代码:

from tornado import gen

import random
import time

class App(object):

    @gen.coroutine
    def get_repo_issues(self, repo):
        sleep_time = random.randint(1, 5)
        time.sleep(sleep_time)

        if sleep_time in (2, 4):
            raise Exception('There is a disturbance in the force... %d' % sleep_time)

        raise gen.Return(sleep_time)


    @gen.coroutine
    def get_all_repo_issues(self, repo_list):

        for i in repo_list:
            repo = 'repo_' + str(i)
            try:
                items = yield self.get_repo_issues(repo)
                print 'Got %d items for %s' % (items, repo)
            except Exception as e:
                print 'Got exception for %s: %s' % (repo, str(e))


    @gen.coroutine
    def main(self):
        yield gen.Task(self.get_all_repo_issues, range(5))


def main():
    App().main()

上面的代码按预期工作,但我希望在捕获和处理异常时并行调用self.get_repo_issues。

我正在思考一些产生调用字典但却不知道如何捕获异常的内容。

有没有办法在龙卷风中这样做?

2 个答案:

答案 0 :(得分:2)

禁止在Tornado应用程序中调用sleep。 Tornado应用程序通常是单线程的,因此sleep会阻止整个过程,并且sleep执行时不能运行其他协同程序或回调。请改为使用yield gen.sleep(n_seconds)进行测试。

等待许多操作,使用WaitIterator

这样的(未经测试)
futures = {}
for i in repo_list:
    repo = 'repo_' + str(i)
    futures[repo] = self.get_repo_issues(repo)

wait_iterator = gen.WaitIterator(**futures)
while not wait_iterator.done():
    try:
        items = yield wait_iterator.next()
    except Exception as e:
        print 'Got exception for %s: %s' % (
            wait_iterator.current_index, str(e))
    else:
        repo = wait_iterator.current_index
        print 'Got %d items for %s' % (items, repo)

答案 1 :(得分:0)