Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can concurrent.futures.Future be converted to asyncio.Future?

I'm practicing asyncio after writing multithreaded code many years.

Noticed something which i find it strange. Both in asyncio and in concurrent there is a Future object.

from asyncio import Future
from concurrent.futures import Future

Guess each onee has it's own role..

My question is if i can transfer concurrent.future.Future to asyncio.Future (or the opposite)?

like image 814
Aaron_ab Avatar asked Jan 08 '19 16:01

Aaron_ab


People also ask

Is Asyncio concurrent?

asyncio is a library to write concurrent code using the async/await syntax. asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.

What is an Asyncio future?

class asyncio. Future(*, loop=None) A Future represents an eventual result of an asynchronous operation. Not thread-safe. Future is an awaitable object.

What are concurrent futures?

The concurrent.futures module provides a high-level interface for asynchronously executing callables. The asynchronous execution can be performed with threads, using ThreadPoolExecutor , or separate processes, using ProcessPoolExecutor .

Which function is used to run Awaitables concurrently in Asyncio?

gather() method - It runs awaitable objects (objects which have await keyword) concurrently.


2 Answers

My question is if i can transfer concurrent.future.Future to asyncio.Future (or the opposite)?

If by "transfer" you mean convert one to the other, yes, it's possible, although bridging the impedance mismatch can take some work.

To convert a concurrent.futures.Future into an asyncio.Future, you can call asyncio.wrap_future. The returned asyncio future is awaitable in the asyncio event loop and will complete when the underlying threading future completes. This is effectively how run_in_executor is implemented.

There is no public functionality to directly convert an asyncio future to concurrent.futures future, but there is the asyncio.run_coroutine_threadsafe function, which takes a coroutine, submits it to an event loop, and returns a concurrent future which completes when the asyncio future does. This can be used to effectively convert any asyncio-awaitable future to concurrent future, like this:

def to_concurrent(fut, loop):
    async def wait():
        await fut
    return asyncio.run_coroutine_threadsafe(wait(), loop)

The returned future will behave like you'd expect from a concurrent future, e.g. its result() method will block, etc. One thing you might want to be careful of is that callbacks added to the concurrent future with add_done_callback run in the thread that marked the future completed, which in this case is the event loop thread. This means that if you add some done callbacks, you need to be careful not to invoke blocking calls in their implementation lest you block the event loop.

Note that calling run_coroutine_threadsafe requires the event loop to actually run in some other thread. (For example, you can start a background thread and have it execute loop.run_forever.)

like image 175
user4815162342 Avatar answered Sep 21 '22 18:09

user4815162342


There is a function called wrap_future in asyncio.

Wrap a concurrent.futures.Future object in a asyncio.Future object.

See https://docs.python.org/3/library/asyncio-future.html#asyncio.wrap_future

like image 43
bitdancer Avatar answered Sep 24 '22 18:09

bitdancer