Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error leaving open_loop() with background Trio sandwich running #56

Closed
oremanj opened this issue May 14, 2019 · 0 comments · Fixed by #96
Closed

Error leaving open_loop() with background Trio sandwich running #56

oremanj opened this issue May 14, 2019 · 0 comments · Fixed by #96

Comments

@oremanj
Copy link
Member

oremanj commented May 14, 2019

The platform: CPython 3.6.7 on Linux, Trio 0.11.0, trio-asyncio 0.10.0.

The setup: Inside a trio-asyncio async loop, I have an asyncio task running in the background, that's in turn awaiting a long-running Trio task (using trio_as_aio appropriately). I exit the async with trio_asyncio.open_loop(): block with the background task still running. In code:

import trio
import trio_asyncio
import asyncio

@trio_asyncio.trio_as_aio
async def trio_grandchild():
    await trio.sleep_forever()

async def asyncio_child():
    await asyncio.sleep(1)
    await trio_grandchild()

@trio_asyncio.aio_as_trio
async def asyncio_spawner():
    asyncio.ensure_future(asyncio_child())

async def trio_main():
    async with trio_asyncio.open_loop() as loop:
        await asyncio_spawner()
        await trio.sleep(2)

if __name__ == "__main__":
    trio.run(trio_main)

The error, after 2 seconds:

Exception in default exception handler
Traceback (most recent call last):
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/base.py", line 300, in __run_trio
    res = await proc(*args)
  File "t.py", line 7, in trio_grandchild
    await trio.sleep_forever()
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio/_timeouts.py", line 51, in sleep_forever
    await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio/_core/_traps.py", line 166, in wait_task_rescheduled
    return (await _async_yield(WaitTaskRescheduled(abort_func))).unwrap()
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/outcome/_sync.py", line 111, in unwrap
    raise captured_error
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio/_core/_run.py", line 740, in raise_cancel
    raise Cancelled._init()
trio.Cancelled

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.6/asyncio/base_events.py", line 1299, in call_exception_handler
    self.default_exception_handler(context)
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/async_.py", line 47, in default_exception_handler
    raise RuntimeError(message)
RuntimeError: Task was destroyed but it is pending!
Exception in default exception handler
Traceback (most recent call last):
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/base.py", line 300, in __run_trio
    res = await proc(*args)
  File "t.py", line 7, in trio_grandchild
    await trio.sleep_forever()
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio/_timeouts.py", line 51, in sleep_forever
    await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio/_core/_traps.py", line 166, in wait_task_rescheduled
    return (await _async_yield(WaitTaskRescheduled(abort_func))).unwrap()
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/outcome/_sync.py", line 111, in unwrap
    raise captured_error
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio/_core/_run.py", line 740, in raise_cancel
    raise Cancelled._init()
trio.Cancelled

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.6/asyncio/base_events.py", line 1299, in call_exception_handler
    self.default_exception_handler(context)
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/async_.py", line 49, in default_exception_handler
    raise exception
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/handles.py", line 135, in _call_async
    await self._callback(self)
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/base.py", line 306, in __run_trio
    f.set_exception(exc)
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/base.py", line 399, in call_soon
    return self._queue_handle(Handle(callback, args, self, context=context, is_sync=True))
  File "/usr/scratch/labtestvenv/lib/python3.6/site-packages/trio_asyncio/async_.py", line 18, in _queue_handle
    self._check_closed()
  File "/usr/lib/python3.6/asyncio/base_events.py", line 366, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

(In a classic display of asyncio robustness, this is just stderr -- the script exits successfully.)

This seems to occur because a Cancelled exception escapes from BaseTrioEventLoop.__run_trio after the open_loop() block's __aexit__ cancels its enclosing nursery's cancel scope. The future that __run_trio is working with isn't cancelled, so the cancellation check in __run_trio doesn't fire.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant