forked from goodboy/tractor
Demo-abandonment on shielded `trio`-side work
Finally this reproduces the issue as it (originally?) exhibited inside `piker` where the `Actor.lifetime_stack` wasn't closed in cases where during `infected_aio`-actor cancellation/shutdown `trio` side tasks which are doing shielded (teardown) work are NOT being watched/waited on from the `aio_main()` task-closure inside `run_as_asyncio_guest()`! This is then the root cause of the guest-run being abandoned since if our `aio_main()` task-closure doesn't know it should allow the run to finish, it's going to call `loop.close()` eventually resulting in the `GeneratorExit` thrown into `trio._core._run.unrolled_run()`.. So, this extends the `test_sigint_closes_lifetime_stack()` suite to include cases for such shielded `trio`-task ops: - add a new `trio_side_is_shielded: bool` which will toggle whether to add a shielded 0.5s `trio.sleep()` loop to `manage_file()` which should outlive the `asyncio` event-loop shutdown sequence and result in an abandoned guest-run and thus a leaked file. - parametrize the existing suite with this case resulting in a total 16 test set B) This patch demonstrates the problem with our `aio_main()` task-closure impl via the now 4 failing tests, a fix is coming in a follow up commit!aio_abandons
parent
4f1db1ff52
commit
268bd0d8ec
|
@ -644,6 +644,7 @@ async def manage_file(
|
||||||
ctx: tractor.Context,
|
ctx: tractor.Context,
|
||||||
tmp_path_str: str,
|
tmp_path_str: str,
|
||||||
send_sigint_to: str,
|
send_sigint_to: str,
|
||||||
|
trio_side_is_shielded: bool = True,
|
||||||
bg_aio_task: bool = False,
|
bg_aio_task: bool = False,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
|
@ -693,11 +694,6 @@ async def manage_file(
|
||||||
# => ????? honestly i'm lost but it seems to be some issue
|
# => ????? honestly i'm lost but it seems to be some issue
|
||||||
# with `asyncio` and SIGINT..
|
# with `asyncio` and SIGINT..
|
||||||
#
|
#
|
||||||
# XXX NOTE XXX SO, if this LINE IS UNCOMMENTED and
|
|
||||||
# `run_as_asyncio_guest()` is written WITHOUT THE
|
|
||||||
# `.cancel_soon()` soln, both of these tests will pass ??
|
|
||||||
# so maybe it has something to do with `asyncio` loop init
|
|
||||||
# state?!?
|
|
||||||
# honestly, this REALLY reminds me why i haven't used
|
# honestly, this REALLY reminds me why i haven't used
|
||||||
# `asyncio` by choice in years.. XD
|
# `asyncio` by choice in years.. XD
|
||||||
#
|
#
|
||||||
|
@ -715,6 +711,15 @@ async def manage_file(
|
||||||
# os.getpid(),
|
# os.getpid(),
|
||||||
# signal.SIGINT,
|
# signal.SIGINT,
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
# XXX spend a half sec doing shielded checkpointing to
|
||||||
|
# ensure that despite the `trio`-side task ignoring the
|
||||||
|
# SIGINT, the `asyncio` side won't abandon the guest-run!
|
||||||
|
if trio_side_is_shielded:
|
||||||
|
with trio.CancelScope(shield=True):
|
||||||
|
for i in range(5):
|
||||||
|
await trio.sleep(0.1)
|
||||||
|
|
||||||
await trio.sleep_forever()
|
await trio.sleep_forever()
|
||||||
|
|
||||||
# signalled manually at the OS level (aka KBI) by the parent actor.
|
# signalled manually at the OS level (aka KBI) by the parent actor.
|
||||||
|
@ -726,6 +731,17 @@ async def manage_file(
|
||||||
raise RuntimeError('shoulda received a KBI?')
|
raise RuntimeError('shoulda received a KBI?')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'trio_side_is_shielded',
|
||||||
|
[
|
||||||
|
False,
|
||||||
|
True,
|
||||||
|
],
|
||||||
|
ids=[
|
||||||
|
'trio_side_no_shielding',
|
||||||
|
'trio_side_does_shielded_work',
|
||||||
|
],
|
||||||
|
)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'send_sigint_to',
|
'send_sigint_to',
|
||||||
[
|
[
|
||||||
|
@ -768,6 +784,7 @@ def test_sigint_closes_lifetime_stack(
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
wait_for_ctx: bool,
|
wait_for_ctx: bool,
|
||||||
bg_aio_task: bool,
|
bg_aio_task: bool,
|
||||||
|
trio_side_is_shielded: bool,
|
||||||
debug_mode: bool,
|
debug_mode: bool,
|
||||||
send_sigint_to: str,
|
send_sigint_to: str,
|
||||||
):
|
):
|
||||||
|
@ -793,6 +810,7 @@ def test_sigint_closes_lifetime_stack(
|
||||||
tmp_path_str=str(tmp_path),
|
tmp_path_str=str(tmp_path),
|
||||||
send_sigint_to=send_sigint_to,
|
send_sigint_to=send_sigint_to,
|
||||||
bg_aio_task=bg_aio_task,
|
bg_aio_task=bg_aio_task,
|
||||||
|
trio_side_is_shielded=trio_side_is_shielded,
|
||||||
) as (ctx, first):
|
) as (ctx, first):
|
||||||
|
|
||||||
path_str, cpid = first
|
path_str, cpid = first
|
||||||
|
|
Loading…
Reference in New Issue