Search code examples
pythonasynchronouswebtornado

How to run Tornado's Future from function instead of yielding


I have something like this:

@coroutine
def foo(): # it can be a http-handler method
    bar()

def bar() # it must be 'next()' of iterator
    # How to run from here foo_2?

@coroutine
def foo_2(): # Something asynchronous
    ....

Actually, I want to make an iterator which operates with REST.


Solution

  • In general, to use a Future in Tornado you must either yield it in a coroutine or use its add_done_callback method to wait for it to finish, and only then can you use the result method to see the result.

    Unfortunately this means it is not really possible to work with Futures in a synchronous context like for loop iteration. Instead, your iterator will have to produce Futures that the caller must yield (and the caller must therefore be a coroutine):

    for future in my_iterator():
        result = yield future
    

    There is more discussion of different patterns for iteration in this blog post. It's slightly outdated now since it was written for Tornado 2.x and uses gen.engine and gen.Task instead of gen.coroutine, but the same general principles still apply.