Factor `child_in_debug()` state sampling

`_try_cancel_then_kill()` repeated the same child/tree debugger
predicate before and after its cancel-RPC checkpoint. Inline
duplication obscured that lock state must be sampled at both points.

Factor the predicate into a local `child_in_debug()` sampler. Use it
for initial hard-kill protection and re-run it after the await before
debugger waiting, preserving dynamic lock-state behavior. Keep it
local since one input is supervisor-owned nursery configuration.

Review: PR #481 (goodboy)
https://github.com/goodboy/tractor/pull/481#pullrequestreview-5012942328

Prompt-IO: ai/prompt-io/opencode/20260824T225356Z_2f86dd1a_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
wkt/to_actor_subpkg
Gud Boi 2026-08-24 19:38:22 -04:00
parent 2f86dd1a33
commit 5327b25e1b
3 changed files with 71 additions and 8 deletions

View File

@ -0,0 +1,39 @@
---
model: openai/gpt-5.6-sol
service: opencode
session: d9d7df2c-7044-463f-8768-ec024718eac9
timestamp: 2026-08-24T22:53:56Z
git_ref: 2f86dd1a
scope: code
substantive: true
raw_file: 20260824T225356Z_2f86dd1a_prompt_io.raw.md
---
## Prompt
Continue PR #481 review remediation after committing the paired
`ActorNursery` reap-state invariant. The human selected "keep" for the
reviewer's request to factor a duplicated debugger predicate in
`_try_cancel_then_kill()`.
## Response summary
Factor the child/tree debugger predicate into a local sampler used both
before and after the cancel-RPC checkpoint. Preserve dynamic debugger
lock re-evaluation and its distinction from root-wide debug mode.
## Files changed
- `tractor/runtime/_supervise.py` - factor the duplicated debugger
predicate without changing cancellation behavior.
## Human edits
The human explicitly selected "keep" after receiving keep/defer/drop
options for this isolated review item. During commit-plan review, the
agent found that a single pre-checkpoint snapshot could become stale;
the human selected a local helper which re-evaluates the lock after the
cancel RPC. The human then considered moving the predicate into
`.devx.debug` and accepted keeping it local after confirming that no
existing helper shares its supervisor-owned semantics. No direct
source-line edits were made by the human.

View File

@ -0,0 +1,18 @@
---
model: openai/gpt-5.6-sol
service: opencode
timestamp: 2026-08-24T22:53:56Z
git_ref: 2f86dd1a
diff_cmd: git diff HEAD~1..HEAD
---
Implement the approved PR #481 review refactor in
`_try_cancel_then_kill()` without changing debugger behavior.
> `git diff HEAD~1..HEAD -- tractor/runtime/_supervise.py`
Compute the child/tree debugger predicate once, reuse it in the broader
hard-kill protection predicate, and pass it directly to
`debug.maybe_wait_for_debugger()`.
Run focused debugger/cancellation coverage and lint after the edit.

View File

@ -130,12 +130,21 @@ async def _try_cancel_then_kill(
# mutated by per-child `debug_mode=True`). ORing covers
# every flavor without false-positively skipping
# legitimate hard-kill paths in non-debug trees.
debug_protected: bool = (
def child_in_debug() -> bool:
'''
Sample child/tree debugger protection state.
'''
return (
debug_mode_active
or
debug.Lock.ctx_in_debug is not None
)
debug_protected: bool = (
child_in_debug()
or
_state._runtime_vars.get('_debug_mode', False)
or
debug_mode_active
)
try:
@ -145,11 +154,8 @@ async def _try_cancel_then_kill(
if not cancelled:
if debug_protected:
await debug.maybe_wait_for_debugger(
child_in_debug=(
debug_mode_active
or
debug.Lock.ctx_in_debug is not None
),
# Re-sample after the cancel-RPC checkpoint.
child_in_debug=child_in_debug(),
header_msg=(
'Delaying subproc hard-reap while '
'debugger locked..\n'