mirror of
https://github.com/ARM-software/devlib.git
synced 2025-04-03 16:30:04 +01:00
utils/asyn: Fix cancellation of async tasks in map_concurrently()
Ensure the canceled tasks are awaited, so cancellation actually takes place.
This commit is contained in:
parent
5425f4afff
commit
f02a0a38b0
@ -123,6 +123,10 @@ class AsyncManager:
|
||||
except BaseException:
|
||||
for task in tasks:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
raise
|
||||
finally:
|
||||
|
||||
|
@ -23,7 +23,7 @@ from contextlib import contextmanager
|
||||
|
||||
from pytest import skip, raises
|
||||
|
||||
from devlib.utils.asyn import run, asynccontextmanager
|
||||
from devlib.utils.asyn import run, asynccontextmanager, AsyncManager
|
||||
|
||||
|
||||
class AsynTestExcep(Exception):
|
||||
@ -517,6 +517,53 @@ def _do_test_run(top_run):
|
||||
|
||||
test_async_gen1()
|
||||
|
||||
def test_async_map_concurrently():
|
||||
async def agen_f():
|
||||
manager = AsyncManager()
|
||||
|
||||
async def f1():
|
||||
return 1
|
||||
|
||||
async def f2():
|
||||
return 2
|
||||
|
||||
return await manager.concurrently([f1(), f2()])
|
||||
|
||||
agen = agen_f()
|
||||
assert top_run(agen) == [1, 2]
|
||||
|
||||
test_async_map_concurrently()
|
||||
|
||||
def test_async_map_concurrently_cancel():
|
||||
class MyException(Exception):
|
||||
pass
|
||||
|
||||
async def agen_f():
|
||||
manager = AsyncManager()
|
||||
cancelled1 = False
|
||||
|
||||
async def f1():
|
||||
nonlocal cancelled1
|
||||
|
||||
try:
|
||||
# Await on a future that will never be available. We should
|
||||
# get canceled at some point, so it does not matter.
|
||||
await asyncio.Future()
|
||||
except asyncio.CancelledError:
|
||||
cancelled1 = True
|
||||
|
||||
async def f2():
|
||||
raise MyException('from f2')
|
||||
|
||||
with raises(MyException):
|
||||
await manager.concurrently([f1(), f2()])
|
||||
|
||||
assert cancelled1
|
||||
|
||||
top_run(agen_f())
|
||||
|
||||
test_async_map_concurrently_cancel()
|
||||
|
||||
|
||||
def _test_in_thread(setup, test):
|
||||
def f():
|
||||
|
Loading…
x
Reference in New Issue
Block a user