[tornado] Using futures

1,103 views
Skip to first unread message

Frank Smit

unread,
Apr 1, 2013, 5:35:29 PM4/1/13
to python-...@googlegroups.com
Hello,

I wanted to add futures to Momoko, but I don't really understand how
they work. I looked at the code in Tornado itself, but it's not really
clear what is happening. And the documentation doesn't really give
much information.

Can someone explain it or make a simple example? I understand that a
function/method must return an instance of a future.

Regards,
Frank

Shane Spencer

unread,
Apr 1, 2013, 6:28:36 PM4/1/13
to python-...@googlegroups.com
I am a bit lost as well, as unconstructive as that is to say, and think I need to just dive in.  I'm a bit flustered by the phrasing since I import future in other projects. :)

- Shane



--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornad...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Ben Darnell

unread,
Apr 1, 2013, 11:48:10 PM4/1/13
to Tornado Mailing List
First, the background: a Future represents the result of a function call.  Functions can either return a value or raise an exception, so a future can contain either a value or an exception (you normally access both with the future.result() method, which will raise the exception or return the value as appropriate).  Futures can exist before their corresponding functions are finished.  In a multithreaded/blocking world (which is where Futures were originally introduced, in the Python 3.2 concurrent.futures module), you can simply call future.result() to wait for the other thread or process to finish its work.  In an asynchronous world, you can attach a callback to the future to be notified when it's done (with future.add_done_callback or io_loop.add_future).  

In Tornado 3.0, the tornado.gen module has been updated to work seamlessly with Futures, although the Future objects themselves are mostly invisible.  In Tornado 2.x, to call an asynchronous function you have to pass it a callback; in generators this usually meant a gen.Task wrapper:
    response = yield gen.Task(http_client.fetch, url)

You couldn't (easily) call http_client.fetch(url) directly because you didn't have a callback to pass in.  In 3.0, two things changed: the callback is now optional, and the fetch method returns a Future which gives you a way to add a callback after you've already called the method:
    response = yield http_client.fetch(url)

Here, http_client.fetch returns a Future, which only passes through your code for a moment as it is immediately yielded to the coroutine runner.  On the left side of the equals sign, the gen module does its magic and calls future.result() for you.  This assigns the response to a local variable if the fetch succeeded, or raises an exception if it didn't.

If you're using generators, you don't need to think about this too much - just use @gen.coroutine instead of @gen.engine and don't use gen.Task and things will mostly just work automatically.  If you have a mix of generator and non-generator code you may need to be more careful as there are some small incompatibilities (for example, @gen.coroutine requires that the callback argument be passed by keyword instead of by position).  The @tornado.concurrent.return_future decorator can be used to make callback-based code return a Future so it can be used in generators (you probably don't want to create Futures except via the @gen.coroutine and @return_future decorators).

-Ben



Aleksey Silk

unread,
Apr 2, 2013, 2:01:50 AM4/2/13
to python-...@googlegroups.com
I still use @gen.engine, because no example code is here for new features. 
Maybe you should give more examples in documentation and it will help to get new for all of us ...

P.S. I've tryed to get my code work with @gen.coroutine, but I failed ... Failed for now ... 
And I think tornado is best :)


С уважением, Алексей Силк
With best regards, Aleksey Silk
 
skype - rootiks
 


2013/4/2 Ben Darnell <b...@bendarnell.com>

Ben Darnell

unread,
Apr 2, 2013, 10:38:11 AM4/2/13
to Tornado Mailing List
On Tue, Apr 2, 2013 at 2:01 AM, Aleksey Silk <ale...@silk.bz> wrote:
I still use @gen.engine, because no example code is here for new features. 
Maybe you should give more examples in documentation and it will help to get new for all of us ...

Are you looking at the right version of the docs (there's a version switcher in the corner of the page)?  The gen module's docs are all using gen.coroutine now:
So are other modules like auth:

-Ben
Reply all
Reply to author
Forward
0 new messages