I have one blocking function:
def blocking_function():
doing.start_preparing()
while not doing.is_ready():
pass
return doing.do()
I want to change it into an async function.
I've read some source code of asyncio, and I've found this two options:
@types.coroutine
def yield_option() -> typing.Generator:
doing.start_preparing()
while not doing.is_ready():
yield
return doing.do()
def future_and_call_soon_option() -> asyncio.Future:
doing.start_preparing()
loop = asyncio.get_running_loop()
future = loop.create_future()
def inner():
if not doing.is_ready():
loop.call_soon(inner)
else:
future.set_result(doing.do())
inner()
return future
async def main():
await asyncio.gather(yield_option(), future_and_call_soon_option()) #runs concurently
asyncio.run(main())
Both of these options do work but which of them is better? Or is there any third option that is better to use?
CodePudding user response:
How about:
async def blocking_function():
doing.start_preparing()
while not doing.is_ready():
await asyncio.sleep(0)
return doing.do()
This will cooperate with other tasks. It is simple and would probably be acceptable in practice if the blocking functions are fast enough. But if the blocking functions take a significant amount of time it would be better to move them to another thread.