erdewit / nest_asyncio

Patch asyncio to allow nested event loops
BSD 2-Clause "Simplified" License
693 stars 79 forks source link

Exceptions support #39

Closed bschindler closed 3 years ago

bschindler commented 3 years ago

I am having an issue with this library in that an exception thrown in a coroutine can cause stalls. Here is a very simple sample code:

import asyncio
import nest_asyncio

async def nested_function():
    print("Nested function called")
    await asyncio.sleep(1)

async def crashing_function():
    print("Launching crashing function")
    await asyncio.sleep(0.01)
    raise RuntimeError("This thing crashed")

def recursive_function():
    print("Initial")
    loop = asyncio.get_running_loop()
    loop.run_until_complete(nested_function())

async def calls_recursive():
    await asyncio.sleep(0.01)
    recursive_function()

async def async_main():
    print("Async main")
    nest_asyncio.apply(loop)
    tasks = [calls_recursive(), crashing_function()]
    print("Async main resuming")
    await asyncio.gather(*tasks)

loop = asyncio.get_event_loop()
loop.run_until_complete(async_main())

What I would expect this code to do is that the nested run_until_complete to finish the nested function and that the excpetion thrown in crashing_function() to be report in the await asyncio.gather() call. Instead, the nested run_until_complete call just hangs forever

erdewit commented 3 years ago

If the nest_asyncio.apply() is moved to the top (after the imports) it will work. Otherwise there's an unpatched task that causes problems.