[Python] Coroutines in `aws` are cancelled in asyncio.gather(*aws, return_exceptions=False)...

Discussão em 'Python' iniciado por Stack, Setembro 30, 2024.

  1. Stack

    Stack Membro Participativo

    My question is from this post. I'll describe it here.

    I have the following Python code:

    import asyncio, time

    async def fn1(x):
    await asyncio.sleep(3)
    print(f"fn1 is called with x={x}")
    return "fn1 SUCCESS"

    async def fn2(y):
    await asyncio.sleep(2)
    print(f"fn2 is called with y={y}")
    raise asyncio.TimeoutError()
    print(y, '*'*10)
    return "fn2 SUCCESS"

    async def main():
    print("start:",time.ctime())
    result = ['No results']
    try:
    result = await asyncio.gather(
    fn1("fn1"),
    fn2("fn2"),
    return_exceptions=False,
    # return_exceptions=True,
    )
    except Exception as e:
    print('e:', type(e), str(e))
    print("end:",time.ctime())
    print(result)

    asyncio.run(main())


    This is the result I got:

    start: Mon Sep 30 17:25:28 2024
    fn2 is called with y=fn2
    e: <class 'TimeoutError'>
    end: Mon Sep 30 17:25:30 2024
    ['No results']


    According to awaitable asyncio.gather(*aws, return_exceptions=False)¶,


    If return_exceptions is False (default), the first raised exception is immediately propagated to the task that awaits on gather(). Other awaitables in the aws sequence won’t be cancelled and will continue to run.
    ​

    But this is contrary to the result I got. Why fn1("fn1") coroutine does not get to finish running? If it finishes running, the line print(f"fn1 is called with x={x}") should print it out.

    Then, I made a simple change to fn1, where the "sleep" time is shorter:

    async def fn1(x):
    await asyncio.sleep(3-1)
    print(f"fn1 is called with x={x}")
    return "fn1 SUCCESS"


    In this time the coroutine fn1 gets to finish:

    start: Mon Sep 30 17:30:29 2024
    fn1 is called with x=fn1
    fn2 is called with y=fn2
    e: <class 'TimeoutError'>
    end: Mon Sep 30 17:30:31 2024
    ['No results']


    This is unexpected for me! The behaviours here seem to be not in line with the doc that "Other awaitables in the aws sequence won’t be cancelled and will continue to run." Can you please explain why?

    Continue reading...

Compartilhe esta Página