Reputation: 43
I've started working with python tornado recently.
I've done a small project using callbacks and now I'm trying to figure out how to use coroutines to make my life a bit easier ( or harder )
I have the following code:
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()
Above code works as intended but I want parallel calls to self.get_repo_issues while catching and treating exceptions.
I was thinking something along the lines of yielding a dictionary of calls but dont know how to catch exceptions.
Is there a way to do this in tornado ?
Upvotes: 2
Views: 2033
Reputation: 712
For blocking functions use tornado way
- http://tornado.readthedocs.org/en/latest/guide/coroutines.html#calling-blocking-functions
Upvotes: 0
Reputation: 24007
Calling sleep
in a Tornado application is forbidden. Tornado apps are usually single-threaded, so sleep
blocks the entire process and no other coroutine or callback can run while sleep
is executing. Test with yield gen.sleep(n_seconds)
instead.
To wait for many operations, something like this (untested) using 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)
Upvotes: 3