Suppose a library has two functions, the first function takes a url and returns a Future
of a Connection
:
def create_connection(url)
"""
:return tornado.gen.Future containing connection
"""
And a second function which takes a Connection, not a Future of Connection, and returns a Future of a Channel
:
def create_channel(connection):
"""
:return tornado.gen.Future containing channel
"""
How do I bind those two functions together to create a Future of a Channel given a url (without using await
)?
Something of the form:
url = "doesn't matter"
channel_future = create_connection(url).bind(lambda c: create_channel(c))
Thank you in advance for your consideration and response.
You can create a coroutine (decorated with gen.coroutine
) and yield the futures returned by create_connection
and create_channel
.
@gen.coroutine
def bind_things_together():
connection = yield create_connection(url)
channel = yield create_channel(connection)
# do something else ...
In the code example above, the connection
and channel
variables are not futures, but actual connection and channel objects, because yielding a Future returns it's result.
When you set the result on the connection future, Tornado will call bind_things_together.next()
to move the coroutine forward. Then in the next line, you pass connection
to create_channel
. When you set the result on channel future, Tornado will again call .next()
to move the coroutine forward. At which point you can do other things.
EDIT: On reading your question again, it seems that you want to access the future for channel. In that case, you don't have to yield create_channel()
:
@gen.coroutine
def bind_things...():
...
channel_future = create_channel(connection)
# if later you want the channel object, just yield channel_future
NOTE: If you call bind_things_together()
from another function, you will need to decorate that function with gen.coroutine
as well. Also, any function decorated with gen.coroutine
will automatically return a Future. So, you have to use yield
keyword in the caller to get the result of bind_things_together()
.