diff --git a/examples/debugging/fast_error_in_root_after_spawn.py b/examples/debugging/fast_error_in_root_after_spawn.py new file mode 100644 index 0000000..d22833f --- /dev/null +++ b/examples/debugging/fast_error_in_root_after_spawn.py @@ -0,0 +1,53 @@ +''' +fast fail test with a context. +ensure the partially initialized sub-actor process +doesn't cause a hang on error/cancel of the parent +nrusery. + +''' +import trio +import tractor + + +@tractor.context +async def sleep( + ctx: tractor.Context, +): + await trio.sleep(0.5) + await ctx.started() + await trio.sleep_forever() + + +async def open_ctx( + n: tractor._trionics.ActorNursery +): + + # spawn both actors + portal = await n.start_actor( + name='sleeper', + enable_modules=[__name__], + ) + + async with portal.open_context( + sleep, + ) as (ctx, first): + assert first is None + + +async def main(): + + async with tractor.open_nursery( + debug_mode=True, + loglevel='runtime', + ) as an: + + async with trio.open_nursery() as n: + n.start_soon(open_ctx, an) + + await trio.sleep(0.2) + await trio.sleep(0.1) + assert 0 + + +if __name__ == '__main__': + trio.run(main) diff --git a/tests/test_debugger.py b/tests/test_debugger.py index 6c334b6..e0dec93 100644 --- a/tests/test_debugger.py +++ b/tests/test_debugger.py @@ -497,3 +497,21 @@ def test_root_nursery_cancels_before_child_releases_tty_lock( assert "tractor._exceptions.RemoteActorError: ('spawner0'" in before assert "tractor._exceptions.RemoteActorError: ('name_error'" in before assert "NameError: name 'doggypants' is not defined" in before + + +def test_root_cancels_child_context_during_startup( + spawn, +): + '''Verify a fast fail in the root doesn't lock up the child reaping + and all while using the new context api. + + ''' + child = spawn('fast_error_in_root_after_spawn') + + child.expect(r"\(Pdb\+\+\)") + + before = str(child.before.decode()) + assert "AssertionError" in before + + child.sendline('c') + child.expect(pexpect.EOF)