I know that asyncio features heavily in StackOverflow, but despite the many questions answered here, I still don't understand how to do something as simple as parallelise 2 tasks that execute blocking code.
For example, this works beautifully:
import asyncio
async def slow_thing():
await asyncio.sleep(2)
async def try_alpha():
print("Alpha start")
await slow_thing()
print("Alpha stop")
return "Alpha"
async def try_bravo():
print("Bravo start")
await slow_thing()
print("Bravo stop")
return "Bravo"
async def main():
futures = [
try_alpha(),
try_bravo(),
]
for response in await asyncio.gather(*futures):
print(response)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
The output is exactly what I'm looking for:
Alpha start
Bravo start
*2 second wait*
Alpha stop
Bravo stop
Alpha
Bravo
However, if I swap out await syncio.sleep(2)
with time.sleep(2)
, the output is as if there's nothing async about my code:
Alpha start
*2 second wait*
Alpha stop
Bravo start
*2 second wait*
Bravo stop
Alpha
Bravo
The thing is, in my real-world example, I don't control that slow code so I can't change it to use coroutines. In some cases, it's just a bunch of uses of requests.get()
and in others I'm using the kodijson
library which does a bunch of things I don't have access to.
So I'm left wondering if asyncio is even the right tool here. Is it possible to use blocking code inside async code when you're trying to parallelise with .gather()?
Also note that I'm (unfortunately) stuck with Python 3.6 on this one. I'm writing a Mycroft extension, and that's the environment they're stuck on at the moment.