Python 使用协程和处理异常的龙卷风并行请求
Python tornado parallel requests using coroutines and handling exceptions
我最近开始使用 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。
我在想生成调用字典的思路,但不知道如何捕获异常。
有没有办法在龙卷风中做到这一点?
禁止在 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)
对于阻塞函数使用 tornado way
- http://tornado.readthedocs.org/en/latest/guide/coroutines.html#calling-blocking-functions
我最近开始使用 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。
我在想生成调用字典的思路,但不知道如何捕获异常。
有没有办法在龙卷风中做到这一点?
禁止在 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)
对于阻塞函数使用 tornado way
- http://tornado.readthedocs.org/en/latest/guide/coroutines.html#calling-blocking-functions