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)?
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.
class asyncio. Future(*, loop=None) A Future represents an eventual result of an asynchronous operation. Not thread-safe. Future is an awaitable object.
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 .
gather() method - It runs awaitable objects (objects which have await keyword) concurrently.
My question is if i can transfer
concurrent.future.Future
toasyncio.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
.)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With