Unable to call result () on tornado futures

I want to make some asynchronous HTTP requests using the python library tornado (version 4.2). However, I cannot force the future to complete (using result()), as I get an exception: "DummyFuture does not support locking results."

I have python 3.4.3, so future support should be part of the standard library. The documentation concurrent.pysays:

A tornado will use concurrent.futures.Futureif available; otherwise, it will use the compatible class defined in this module.

The minimum example of what I'm trying to do is given below:

from tornado.httpclient import AsyncHTTPClient;

future = AsyncHTTPClient().fetch("http://google.com")
future.result()

If I understand my problem correctly, this is because the import is concurrent.futures.Futuresomehow not used. The corresponding code in the tornado seems to be in concurrent.py, but I don't really understand where exactly the problem lies.

+4
source share
1 answer

Try creating another one Futureand use add_done_callback:

From the Tornado documentation

from tornado.concurrent import Future

def async_fetch_future(url):
    http_client = AsyncHTTPClient()
    my_future = Future()
    fetch_future = http_client.fetch(url)
    fetch_future.add_done_callback(
        lambda f: my_future.set_result(f.result()))
    return my_future

But you still need to decide the future with ioloop , for example:

# -*- coding: utf-8 -*-
from tornado.concurrent import Future
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop


def async_fetch_future():
    http_client = AsyncHTTPClient()
    my_future = Future()
    fetch_future = http_client.fetch('http://www.google.com')
    fetch_future.add_done_callback(
        lambda f: my_future.set_result(f.result()))
    return my_future

response = IOLoop.current().run_sync(async_fetch_future)

print(response.body)

Another way to do this is to use a decorator tornado.gen.coroutine, for example:

# -*- coding: utf-8 -*-
from tornado.gen import coroutine
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop


@coroutine
def async_fetch_future():
    http_client = AsyncHTTPClient()
    fetch_result = yield http_client.fetch('http://www.google.com')
    return fetch_result

result = IOLoop.current().run_sync(async_fetch_future)

print(result.body)

coroutineThe decorator forces the function to return Future.

+3
source

All Articles