Submit the task to the asyncio event loop

I would like to send jobs from the thread to the asyncio event asyncio (same as run_in_executor , but vice versa).

Here's asyncio documentation talking about concurrency and multithreading :

To schedule a callback from another thread, use the BaseEventLoop.call_soon_threadsafe () method. An example for planning a coroutine from another thread: loop.call_soon_threadsafe(asyncio.async, coro_func())

This works fine, but the coroutine result is lost.

Instead, you can use a function that adds the callback made to the future returned by async (or ensure_future ) so that the stream can access the result through concurrent.futures.Future .

Is there a special reason why such a function is not implemented in the standard library? Or did I miss an easier way to achieve this?

+7
python multithreading python-asyncio
source share
1 answer

My request came through and the run_coroutine_threadsafe function was implemented.

Example:

 def target(loop, timeout=None): future = asyncio.run_coroutine_threadsafe(add(1, b=2), loop) return future.result(timeout) async def add(a, b): await asyncio.sleep(1) return a + b loop = asyncio.get_event_loop() future = loop.run_in_executor(None, target, loop) assert loop.run_until_complete(future) == 3 

I originally placed a subclass of the concurrent.futures.Executor class, which can be implemented as:

 class LoopExecutor(concurrent.futures.Executor): """An Executor subclass that uses an event loop to execute calls asynchronously.""" def __init__(self, loop=None): """Initialize the executor with a given loop.""" self.loop = loop or asyncio.get_event_loop() def submit(self, fn, *args, **kwargs): """Schedule the callable, fn, to be executed as fn(*args **kwargs). Return a Future object representing the execution of the callable.""" coro = asyncio.coroutine(fn)(*args, **kwargs) return asyncio.run_coroutine_threadsafe(coro, self.loop) 
+6
source share

All Articles