fix(core): join both output drains once across the grace windows - #315
Merged
Merged
Conversation
A supervised process's stdout and stderr drains were joined inside the first grace window with a fresh tokio::join! of the two JoinHandles, and joined again in the second window when the first timed out. A JoinHandle yields its output once and panics when polled after that, so a drain that finished inside the first window (the usual shape when a detached descendant keeps only one inherited pipe open) was polled again in the second and the whole turn ended on "JoinHandle polled after completion". One join future is now pinned and polled through both windows, so the finished side is remembered and never polled again. Grace timings, the stop cancel, the abort path, and the error text are unchanged. The new test finishes one drain at once and holds the other until the stop token fires; it panics on the previous code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A supervised process's stdout and stderr drains were joined inside the first grace window with a fresh
tokio::join!of the twoJoinHandles, and joined again in the second window when the first timed out. AJoinHandleyields its output once and panics when polled after that, so a drain that finished inside the first window (the usual shape when a detached descendant keeps only one inherited pipe open) was polled again in the second, and the whole turn ended onJoinHandle polled after completionwith the task abandoned mid-way.Summary
join_streamspins one join future and polls it through both grace windows, so the finished side is remembered and never polled again. Grace timings, the stop cancel, the abort path, and the error text are unchanged.Optionplus let-else replaces the nested match, and one closure replaces the duplicated two-step error mapping.Test Plan
a_finished_drain_is_not_polled_again_when_the_other_hangs: finishes one drain at once and holds the other until the stop token fires. Panics with the exact message on the previous code; passes now.cargo test --workspace --lockedgreen (599 core, 27 CLI);cargo +1.97.0 clippy --workspace --all-targets --locked -- -D warningsclean.Greptile Summary
This PR fixes output-drain supervision by polling one pinned join future across both grace windows, preventing a completed drain task from being polled again. The targeted regression scenario now returns both captured streams after cancellation instead of crashing.
Confidence Score: 5/5
Safe to merge: the changed drain-supervision path preserves timeout and cancellation behavior while preventing the completed-task polling crash.
No outstanding issues were found. The focused scenario that previously crashed after one drain completed now completes and returns both stream results.
Files Needing Attention: None.
What T-Rex did
Reviews (1): Last reviewed commit: "fix(core): join both output drains once ..." | Re-trigger Greptile
Context used: