Clear fatal-error interrupt window unconditionally on body exit - #6994
Conversation
Review follow-ups: clear in_body in a finally around the yield so a task failing after the with-body raised its own exception can no longer interrupt unrelated caller code (the executor shutdown does not wait), replacing the two scattered clears; document the 5-second assertion threshold in the hang regression test; add a regression test for the late-failure case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
|
Note: this was opened moments before your replies landed on the #6990 threads ("if we're going down, we're going down" / "test code"), so calling out the delta explicitly: Generated by Claude Code |
Greptile SummaryThe PR clears the fatal-error interrupt window in a
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| reflex/utils/processes.py | Moves interrupt-window cleanup into an unconditional nested finally, covering all body-exit paths. |
| tests/units/utils/test_processes.py | Adds coverage for late worker failures and documents the existing timeout relationship. |
| news/+interrupt-window-followup.bugfix.md | Records the corrected late-interrupt behavior in the changelog. |
Reviews (3): Last reviewed commit: "Clear the interrupt window when the pre-..." | Re-trigger Greptile
Merging this PR will not alter performance
Comparing Footnotes
|
The 0.3s/0.6s sleeps made ordering scheduler-dependent: under load the task could fail before the body raised, or outlive the settle window. Events now enforce the ordering (task fails only after the context has unwound; a done callback registered after the context's own confirms the interrupt callback ran), leaving only a 0.1s signal-delivery window, documented in place. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
There was a problem hiding this comment.
All reported issues were addressed
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Review follow-up: raise_first_failure ran outside the try/finally, so a task failing before the body was entered left in_body armed and a surviving task could interrupt caller code after the context exited. The finally now wraps the pre-check as well. New regression test fails 10/10 against the previous structure and passes 10/10 with the fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
Type of change
Changes To Core Features:
Description
Follow-up to #6990 (merged while this review round was in flight), addressing the two review threads that were still open there:
run_concurrently_contextclearedin_bodyonly on the normal post-body path and in theKeyboardInterrupthandler. If the with-body raises any other exception,in_bodystaysTrue— and since the executor shuts down withwait=False, a task failing after the context has unwound could still deliver a stray SIGINT into unrelated caller code. The fix wraps theyieldin atry/finallythat clearsin_bodyhowever the body exits, replacing the two scattered clears — a net simplification of the mechanism, not an addition (per the review discussion, no extra guarded setup path).5-second assertion threshold now carries a comment explaining its relationship to the body's 10s wait.Adds
test_run_concurrently_context_no_interrupt_after_body_exception, which pins the escaped-interrupt case (late-failing task + body exception → the body's ownValueErrorpropagates, no strayKeyboardInterrupt).Test Plan
uv run pytest tests/units/utils/test_processes.py -k run_concurrently: 4 passed (the new test plus the three from Fix reflex run hanging after fatal error in the frontend thread #6990).uv run ruff check/ruff format --checkclean on changed files;uv run pyright0 errors on changed files.reflex-release changelog-check --base-ref origin/mainpasses.test_is_process_on_port_*failures in this sandbox are pre-existing on clean main here (container network stack), unrelated to the diff.🤖 Generated with Claude Code
https://claude.ai/code/session_01EMjBXPozsNeQNSBZecNH8x
Generated by Claude Code