Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I wrap a synchronous function in an async coroutine?

I'm using aiohttp to build an API server that sends TCP requests off to a seperate server. The module that sends the TCP requests is synchronous and a black box for my purposes. So my problem is that these requests are blocking the entire API. I need a way to wrap the module requests in an asynchronous coroutine that won't block the rest of the API.

So, just using sleep as a simple example, is there any way to somehow wrap time-consuming synchronous code in a non-blocking coroutine, something like this:

async def sleep_async(delay):     # After calling sleep, loop should be released until sleep is done     yield sleep(delay)     return 'I slept asynchronously' 
like image 404
Zac Delventhal Avatar asked Apr 05 '17 20:04

Zac Delventhal


1 Answers

Eventually I found an answer in this thread. The method I was looking for is run_in_executor. This allows a synchronous function to be run asynchronously without blocking an event loop.

In the sleep example I posted above, it might look like this:

import asyncio from time import sleep  async def sleep_async(loop, delay):     # None uses the default executor (ThreadPoolExecutor)     await loop.run_in_executor(None, sleep, delay)     return 'I slept asynchronously' 

Also see the following answer -> How do we call a normal function where a coroutine is expected?

like image 82
Zac Delventhal Avatar answered Sep 17 '22 23:09

Zac Delventhal