New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signal handling fixes #10758
Signal handling fixes #10758
Conversation
0bbeb86
to
cf88745
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
src/rust/engine/src/scheduler.rs
Outdated
@@ -474,6 +476,19 @@ impl Scheduler { | |||
session.maybe_display_initialize(&self.core.executor, &sender); | |||
self.execute_helper(request, session, sender); | |||
let result = loop { | |||
match externs::call(&python_signal, &[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to move this out into a helper function to keep the loop body small. You might also move the check "after" the call to recv_timeout
but before the match
... as the most likely time to receive a signal is while we are waiting, and reacting to it before we render the UI/print_stderr/etc will be the most responsive.
src/rust/engine/src/scheduler.rs
Outdated
return Err(ExecutionTermination::KeyboardInterrupt); | ||
} | ||
} | ||
Err(e) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this function is running in the main thread (it won't always be), it's possible that the error type received here will actually be KeyboardInterrupt: in which case you'd want to return ExecutionTermination::KeyboardInterrupt
.
875acca
to
abcebc8
Compare
abcebc8
to
4dabde2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
# An instance of `SignalHandler` which is invoked to handle a static set of specific | ||
# nonfatal signals (these signal handlers are allowed to make pants exit, but unlike SIGSEGV they | ||
# don't need to exit immediately). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This information was potentially useful... did you determine that it is no longer accurate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope that was an extraneous delete, restoring
ExceptionSink.toggle_ignoring_sigint(True) | ||
return self._scheduler.run_local_interactive_process(request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this would be a good place to use a context manager / with
block... any idea why we stopped doing that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code never used a with
block, although I agree that that would be a good improvement, and I might implement that shortly in a followup commit.
src/rust/engine/src/externs/mod.rs
Outdated
|
||
pub fn call(func: &Value, args: &[Value]) -> Result<Value, Failure> { | ||
let output = call_function(func, args); | ||
let gil = Python::acquire_gil(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could avoid re-acquiring the GIL here unless this fails, by moving let gil
inside the map_err.
As well as do some additional refactoring. [ci skip-rust] [ci skip-build-wheels]
[ci skip-build-wheels]
[ci skip-build-wheels]
[ci skip-build-wheels]
[ci skip-build-wheels]
[ci skip-build-wheels]
[ci skip-build-wheels]
97264c8
to
3e3f452
Compare
Yay,
Pantsd isn't quite right, but an improvement. If you use
I can't delete the O, and when I type something, the characters get corrupted. |
Problem
Ideally, pants should exit promptly when a user hits Ctrl-C in the terminal, regardless of how it is configured to run or what it is running. cf. #10051 and other general observations made while using pants, there are still a few cases where pants does not respond quickly to a Ctrl-C and hangs or otherwise takes a while to quit. This commit is an attempt to fix these cases.
Solution
In the
--debug
case, the problem turned out to be that we were explicitly disabling SIGINT handling in the case where pants was running anInteractiveProcess
. For the non-pantsd case, this is desirable - we use theInteractiveProcess
abstraction fortest --debug
and a few other cases where we legitimately want a pants subprocess to take over the terminal and do its own signal handling. But when pantsd is running, we don't want to explicitly disable SIGINT handling, because that means that pantsd will ignore a signal from its own client process. This commit solves the problem by adding a flag toSignalHandler
to indicate whether this is a pantsd run, and doesn't ignore SIGINT if it is.Some other instances of pants ignoring prompt signal handling are caused by rust code not heeding the Python interrupt state triggered by SIGINT, resulting in pants not quitting until execution returns to the Python main thread. This commit works around this by having the Python signal handling infrastructure set a flag on
ExceptionSink
once it has handled a signal that would cause pants to terminate. A python helper function is passed into the main execution loop inscheduler.rs
that checks for the presence of this flag, and breaks the loop to terminate the engine if it finds that the flag is set.Result
Ctrl-C should now work in the
test --debug
case with pantsd, and work in the--no-pantsd
case when any kind of test is running. It still does seem to take more than one hit of Ctrl-C to fully quit pants in some cases, though, which will be addressed in followup commits.