nix-eval-jobs: handle worker interruption properly
Right now, the worker will not receive interrupts, as it has no signal handler thread due to the way it forks, but this will change soon. Prepare to handle worker interruption properly, by letting the worker exit successfully in this case and adjusting the coordinator to handle this exit gracefully. Change-Id: I9f79670b0d2004e7e2d8bf36cf67108e6a6a6964
This commit is contained in:
committed by
alois31
parent
9d01255046
commit
441f7db5f1
@@ -56,6 +56,8 @@ Drv::Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo,
|
||||
assert(optOutputPath);
|
||||
outputs[outputName] = state.ctx.store->printStorePath(*optOutputPath);
|
||||
}
|
||||
} catch (const nix::Interrupted &) {
|
||||
throw;
|
||||
} catch (const std::exception &e) { // NOLINT(lix-foreign-exceptions)
|
||||
state.ctx.errors.make<nix::EvalError>(
|
||||
"derivation '%s' does not have valid outputs: %s",
|
||||
|
||||
@@ -161,7 +161,18 @@ void handleBrokenWorkerPipe(Proc &proc, std::string_view msg, bool retry = true)
|
||||
strerror(errno));
|
||||
} else {
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) == 1) {
|
||||
if (WEXITSTATUS(status) == 0) {
|
||||
// On the user hitting Ctrl-C, both the worker and the coordinator will receive the signal.
|
||||
// When the worker is interrupted, it will "unexpectedly" exit successfully.
|
||||
// Check whether the coordinator was interrupted as well, and don't show an ugly error in this case.
|
||||
checkInterrupt();
|
||||
// Maybe the coordinator noticed the broken pipe before its own interrupt.
|
||||
// Wait for a bit and try again.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
checkInterrupt();
|
||||
// No, the coordinator was not interrupted, possibly the signal was sent manually to the worker.
|
||||
// Show the error in this case.
|
||||
} else if (WEXITSTATUS(status) == 1) {
|
||||
throw Error(
|
||||
"while %s, evaluation worker exited with exit code 1, "
|
||||
"(possible infinite recursion)",
|
||||
|
||||
@@ -252,6 +252,8 @@ try {
|
||||
// Don't forget to print it into the STDERR log, this is
|
||||
// what's shown in the Hydra UI.
|
||||
std::cerr << msg << "\n";
|
||||
} catch (const nix::Interrupted &) {
|
||||
throw;
|
||||
} catch ( // NOLINT(lix-foreign-exceptions)
|
||||
const std::exception &e) { // FIXME: for some reason the catch block
|
||||
// above, doesn't trigger on macOS (?)
|
||||
@@ -282,6 +284,8 @@ try {
|
||||
if (tryWriteLine(to.get(), "restart") < 0) {
|
||||
return; // main process died
|
||||
};
|
||||
} catch (const nix::Interrupted &) {
|
||||
// The coordinator should get the interrupt too, so it doesn't need to be logged.
|
||||
} catch (nix::Error &e) {
|
||||
nix::JSON err;
|
||||
auto msg = e.msg();
|
||||
|
||||
Reference in New Issue
Block a user