fix(cli, rfd): Escalate Ctrl-C only on unanswered presses - #988
Open
JeanMertz wants to merge 2 commits into
Open
fix(cli, rfd): Escalate Ctrl-C only on unanswered presses#988JeanMertz wants to merge 2 commits into
JeanMertz wants to merge 2 commits into
Conversation
`EscalationState` reset the Ctrl-C press count on elapsed time alone, so a press an interrupt menu had already answered stayed on the escalation ladder. Answering the streaming menu and interrupting again inside the two-second cooldown counted as a second press, which bypasses the handler stack and requests a graceful shutdown, so the run ended with no menu and no message. Answering the menu quickly made the next Ctrl-C fatal; taking longer than the cooldown left it working. A delivered press is now an `InterruptNotice` that the notified event loop resolves. `handled()` clears the count, `decline()` hands the press to the next handler down with the count intact, and dropping it leaves the press on the ladder, which is the safe default for a handler that was notified but produced nothing visible. Only presses that produced nothing escalate. Carrying the reset on the delivered value rather than on the router means an event loop cannot decide what a press did without holding the value that records the decision, so the ladder behaves the same at every handler site. `lock.rs` and `plugin/dispatch.rs` had the same defect and now resolve their presses too. `inline_select` returning `Err` mapped every error to an escalation, conflating the user cancelling the menu with the menu being unable to run at all. The latter now yields `PromptFailed`, which leaves the turn untouched and the press on the ladder, so a second Ctrl-C gets the user out through the router instead of through a prompt that is not working. The interrupt path also logs the resolved action, the decision the handler reached, and the `InquireError` behind a prompt that returned without a selection. That error was discarded as `Err(_)`, and its absence is why diagnosing this took several rounds of guessing. RFD 045 is updated to match: the ladder counts unanswered presses, and `SignalRouter::decline` is replaced by resolving the notice. T0014 stays open, since the traces that opened it showed a different signature and are no longer available. Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
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.
EscalationStatereset the Ctrl-C press count on elapsed time alone, so a press an interrupt menu had already answered stayed on the escalation ladder. Answering the streaming menu and interrupting again inside the two-second cooldown counted as a second press, which bypasses the handler stack and requests a graceful shutdown, so the run ended with no menu and no message. Answering the menu quickly made the next Ctrl-C fatal; taking longer than the cooldown left it working.A delivered press is now an
InterruptNoticethat the notified event loop resolves.handled()clears the count,decline()hands the press to the next handler down with the count intact, and dropping it leaves the press on the ladder, which is the safe default for a handler that was notified but produced nothing visible. Only presses that produced nothing escalate.Carrying the reset on the delivered value rather than on the router means an event loop cannot decide what a press did without holding the value that records the decision, so the ladder behaves the same at every handler site.
lock.rsandplugin/dispatch.rshad the same defect and now resolve their presses too.inline_selectreturningErrmapped every error to an escalation, conflating the user cancelling the menu with the menu being unable to run at all. The latter now yieldsPromptFailed, which leaves the turn untouched and the press on the ladder, so a second Ctrl-C gets the user out through the router instead of through a prompt that is not working.The interrupt path also logs the resolved action, the decision the handler reached, and the
InquireErrorbehind a prompt that returned without a selection. That error was discarded asErr(_), and its absence is why diagnosing this took several rounds of guessing.RFD 045 is updated to match: the ladder counts unanswered presses, and
SignalRouter::declineis replaced by resolving the notice. T0014 stays open, since the traces that opened it showed a different signature and are no longer available.