diff --git a/tractor/_testing/_reap.py b/tractor/_testing/_reap.py index 875ad899..71857f52 100644 --- a/tractor/_testing/_reap.py +++ b/tractor/_testing/_reap.py @@ -291,13 +291,15 @@ def find_runaway_subactors( def find_orphans( - repo_root: pathlib.Path, + repo_root: pathlib.Path|None = None, ) -> list[int]: ''' PIDs that are: - reparented to init (`PPid == 1`), - - have `cwd == `, + - have `cwd == ` (defaults to the calling + proc's cwd, i.e. the repo root under a normal + `pytest` invocation), - and have a `python` in their cmdline. This is the "pytest-died-mid-session" case where the @@ -306,7 +308,7 @@ def find_orphans( init-children on the box. ''' - repo: str = str(repo_root) + repo: str = str(repo_root or pathlib.Path.cwd()) hits: list[int] = [] for pid in _iter_live_pids(): if _read_status_ppid(pid) != 1: @@ -1017,6 +1019,19 @@ def reap_subactors_per_test() -> int: (`_reap_orphaned_subactors`) only kicks in at session end which is too late to save the cascade. + Reaps both: + 1. direct descendants of `pytest` (`PPid==pytest_pid`) + 2. NEW init-adopted tractor procs (`PPid==1` AND + `_is_tractor_subactor`) that appeared between + pre-yield and post-yield — these are the leaked + subactors whose mid-tier parent died during the + cascade, reparenting them to init. + + Pre-yield snapshot of init-adopted tractor procs is + used to scope (2) to THIS test's leaks only — without + it we'd also reap orphans from concurrent unrelated + tractor uses on the box (piker, etc.). + Apply at module-level on the topically-problematic test files via: @@ -1036,7 +1051,16 @@ def reap_subactors_per_test() -> int: ''' parent_pid: int = os.getpid() + # Snapshot pre-existing init-adopted tractor procs so + # we can scope post-test reap to NEW orphans only. + pre_orphans: set[int] = set(find_orphans()) yield parent_pid pids: list[int] = find_descendants(parent_pid) + new_orphans: list[int] = [ + pid for pid in find_orphans() + if pid not in pre_orphans + ] + if new_orphans: + pids.extend(new_orphans) if pids: reap(pids, grace=3.0)