facebook/tornado — pull request #1041 by BeholdMyGlory (2014-05-02 13:36:15+00:00)
Title: Improve asyncio integration

These changes make it easier to use asyncio features from Tornado applications. The additions include:

* The `wrap_asyncio_future` and `wrap_tornado_future` functions for wrapping an `asyncio.Future` in a `tornado.concurrent.Future` and the other way around
* A `@task` decorator that makes it possible to use asyncio coroutines with for example `tornado.web.RequestHandler`.
* An `__iter__` method in `tornado.concurrent.Future` that makes it possible to use `yield from` with Tornado futures from asyncio coroutines. The future will be automatically wrapped in an `asyncio.Future`.
* A `get_asyncio_loop` method in `BaseAsyncIOLoop` to explicitly expose the asyncio event loop used by the Tornado IOLoop. This is especially useful with `AsyncIOLoop` since it creates a new event loop object otherwise not accessible outside the IOLoop object.

The most intrusive change here is probably the addition of the `__iter__` method in `tornado.concurrent.Future`. The reasoning here is that you wouldn't normally try to iterate over futures and that the `yield from` syntax is sufficiently associated with `asyncio` that it makes sense to reserve it for use with `asyncio`.

Caveat: Since asyncio futures can be cancelled, `wrap_tornado_future` tries to account for this by running `set_exception` with a `CancelledError` when the `asyncio.Future` that wraps the Tornado Future is cancelled. This will however probably not work as expected seeing as the standard Tornado Future doesn't support being cancelled, so I would recommend avoiding trying to cancel any futures returned by `wrap_tornado_future`.