Skip to content

Commit

Permalink
Expose lifetime stack as class attr, add base test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
goodboy committed Sep 15, 2022
1 parent f07ddf1 commit 2bc75e8
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 6 deletions.
70 changes: 70 additions & 0 deletions tests/test_runtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
Verifying internal runtime state and undocumented extras.
"""
import os

import pytest
import trio
import tractor

from conftest import tractor_test


_file_path: str = ''


def unlink_file():
print('Removing tmp file!')
os.remove(_file_path)


async def crash_and_clean_tmpdir(
tmp_file_path: str,
error: bool = True,
):
global _file_path
_file_path = tmp_file_path

actor = tractor.current_actor()
actor.lifetime_stack.callback(unlink_file)

assert os.path.isfile(tmp_file_path)
await trio.sleep(0.1)
if error:
assert 0
else:
actor.cancel_soon()


@pytest.mark.parametrize(
'error_in_child',
[True, False],
)
@tractor_test
async def test_lifetime_stack_wipes_tmpfile(
tmp_path,
error_in_child: bool,
):
child_tmp_file = tmp_path / "child.txt"
child_tmp_file.touch()
assert child_tmp_file.exists()
path = str(child_tmp_file)

try:
with trio.move_on_after(0.5):
async with tractor.open_nursery() as n:
await ( # inlined portal
await n.run_in_actor(
crash_and_clean_tmpdir,
tmp_file_path=path,
error=error_in_child,
)
).result()

except tractor.RemoteActorError:
pass

# tmp file should have been wiped by
# teardown stack.
assert not child_tmp_file.exists()
1 change: 1 addition & 0 deletions tests/test_spawning.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""
Spawning basics
"""
from typing import Optional

Expand Down
12 changes: 6 additions & 6 deletions tractor/_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,6 @@ def _get_mod_abspath(module):
return os.path.abspath(module.__file__)


# process-global stack closed at end on actor runtime teardown
_lifetime_stack: ExitStack = ExitStack()


async def try_ship_error_to_parent(
channel: Channel,
err: Union[Exception, trio.MultiError],
Expand Down Expand Up @@ -406,6 +402,10 @@ class Actor:
# if started on ``asycio`` running ``trio`` in guest mode
_infected_aio: bool = False

# Process-global stack closed at end on actor runtime teardown.
# NOTE: this is currently an undocumented public api.
lifetime_stack: ExitStack = ExitStack()

def __init__(
self,
name: str,
Expand Down Expand Up @@ -1293,7 +1293,7 @@ async def async_main(
# killed (i.e. this actor is cancelled or signalled by the parent)
except Exception as err:
log.info("Closing all actor lifetime contexts")
_lifetime_stack.close()
actor.lifetime_stack.close()

if not registered_with_arbiter:
# TODO: I guess we could try to connect back
Expand Down Expand Up @@ -1332,7 +1332,7 @@ async def async_main(
# with trio.CancelScope(shield=True):
# await _debug.breakpoint()

_lifetime_stack.close()
actor.lifetime_stack.close()

# Unregister actor from the arbiter
if registered_with_arbiter and (
Expand Down

0 comments on commit 2bc75e8

Please sign in to comment.