Add init-adopted orphan reap to `reap_subactors_per_test`
Post-yield now also reaps init-adopted (`ppid==1`) tractor procs
that appeared during the test — leaked subactors whose mid-tier
parent died during cascade teardown, reparenting them to init.
Pre-yield snapshot of existing orphans scopes reap to THIS test's
leaks only, avoiding reap of unrelated tractor uses (piker, etc.)
on the box.
(this commit msg was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
(cherry picked from commit 01ce2857ea)
(factored: also default `find_orphans(repo_root=None)` -> cwd so the new bare call sites work ahead of the later intrinsic-identity rewrite)
testing_harness_infra
parent
e84dac233d
commit
2cd0908bdb
|
|
@ -291,13 +291,15 @@ def find_runaway_subactors(
|
||||||
|
|
||||||
|
|
||||||
def find_orphans(
|
def find_orphans(
|
||||||
repo_root: pathlib.Path,
|
repo_root: pathlib.Path|None = None,
|
||||||
) -> list[int]:
|
) -> list[int]:
|
||||||
'''
|
'''
|
||||||
PIDs that are:
|
PIDs that are:
|
||||||
|
|
||||||
- reparented to init (`PPid == 1`),
|
- reparented to init (`PPid == 1`),
|
||||||
- have `cwd == <repo_root>`,
|
- have `cwd == <repo_root>` (defaults to the calling
|
||||||
|
proc's cwd, i.e. the repo root under a normal
|
||||||
|
`pytest` invocation),
|
||||||
- and have a `python` in their cmdline.
|
- and have a `python` in their cmdline.
|
||||||
|
|
||||||
This is the "pytest-died-mid-session" case where the
|
This is the "pytest-died-mid-session" case where the
|
||||||
|
|
@ -306,7 +308,7 @@ def find_orphans(
|
||||||
init-children on the box.
|
init-children on the box.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
repo: str = str(repo_root)
|
repo: str = str(repo_root or pathlib.Path.cwd())
|
||||||
hits: list[int] = []
|
hits: list[int] = []
|
||||||
for pid in _iter_live_pids():
|
for pid in _iter_live_pids():
|
||||||
if _read_status_ppid(pid) != 1:
|
if _read_status_ppid(pid) != 1:
|
||||||
|
|
@ -1017,6 +1019,19 @@ def reap_subactors_per_test() -> int:
|
||||||
(`_reap_orphaned_subactors`) only kicks in at session
|
(`_reap_orphaned_subactors`) only kicks in at session
|
||||||
end which is too late to save the cascade.
|
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
|
Apply at module-level on the topically-problematic
|
||||||
test files via:
|
test files via:
|
||||||
|
|
||||||
|
|
@ -1036,7 +1051,16 @@ def reap_subactors_per_test() -> int:
|
||||||
|
|
||||||
'''
|
'''
|
||||||
parent_pid: int = os.getpid()
|
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
|
yield parent_pid
|
||||||
pids: list[int] = find_descendants(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:
|
if pids:
|
||||||
reap(pids, grace=3.0)
|
reap(pids, grace=3.0)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue