I have a code like that :
import asyncio
import time
# long blocking synchronous calls
def long_blocking_sync_calls():
print('task 2 (thread) : sleeping for a long time')
time.sleep(1000)
print('task 2 (thread) : terminate')
# task2, that execute blocking_sync_calls in separate thread
async def task2():
print('task 2 : running a long blocking call, in a separate thread')
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, long_blocking_sync_calls)
# task1
async def task1(task_2):
print('task 1 : waiting')
await asyncio.sleep(2)
print('task 1 : cancelling task 2 ..')
print(str(task_2.cancel()))
print('task 1 : task 2 cancelled.')
# create tasks and gather
async def run():
print('creating tasks..')
task_2 = asyncio.create_task(task2())
task_1 = asyncio.create_task(task1(task_2))
print('tasks created. now gather..')
await asyncio.gather(
task_1,
task_2,
)
print('program end')
if __name__ == '__main__':
asyncio.run(run())
The output is as follow :
creating tasks.. tasks created. now gather.. task 2 : running a long blocking call, in a separate thread task 2 (thread) : sleeping for a long time task 1 : waiting task 1 : cancelling task 2 .. True task 1 : task 2 cancelled. ... the program never end here ...
As you can see, I have multiples coroutines that I gather on.
The task2 coroutine is particular, because it executes long blocking calls (which are not async) in a separate thread.
The problem is that, when the task1 try to cancel task2, it doesn’t work.
Question : is there a way to kill the long_blocking_sync_calls thread, from the coroutine task1 ?
Thank you
Advertisement
Answer
I end up to a full asyncio solution, by avoiding any long blocking synchronous calls, thanks to various libraries.