fix(daemon): actually stop an external daemon on quit when the setting is on
"Stop external daemon" silently left an external dragonxd running. beginShutdown() calls rpc_->requestAbort() (a sticky abort flag, cleared only by connect()) to unblock in-flight requests; the shutdown thread's stopEmbeddedDaemon() then sent the graceful "stop" over that same connection, so curl self-aborted it (CURLE_ABORTED_BY_CALLBACK). doRPC swallowed the error but stop_sent was set true anyway, skipping the temp-connection fallback that would have worked — so the daemon never received "stop" and only died via the 20s by-name force-kill (which collides with the 8s "Force Quit / may corrupt chain data" prompt, so it read as "doesn't work"). Clear the abort before the shutdown stop and send it synchronously via sendStopCommandSafely so real delivery success is surfaced (and the fallback can still run on failure). The graceful stop now reaches the daemon, it exits in a second or two, and the 20s stall / Force-Quit prompt no longer appears. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
16
src/app.cpp
16
src/app.cpp
@@ -5047,17 +5047,17 @@ void App::stopEmbeddedDaemon()
|
||||
// daemon flush state, save block indexes, close sockets, etc.
|
||||
bool stop_sent = false;
|
||||
|
||||
// Try the existing RPC connection first
|
||||
// Try the existing RPC connection first. beginShutdown() called rpc_->requestAbort() to unblock any
|
||||
// in-flight request — but that sticky abort (cleared only by connect()) would make THIS "stop" self-
|
||||
// abort mid-flight (CURLE_ABORTED_BY_CALLBACK). The old async rpc_->stop() swallowed that error yet
|
||||
// set stop_sent=true, so the daemon never heard "stop" and the working temp-connection fallback was
|
||||
// skipped — which is why "Stop external daemon" left an external dragonxd running (it only died via
|
||||
// the 20s force-kill). Clear the abort and send SYNCHRONOUSLY so real success is surfaced.
|
||||
if (rpc_ && rpc_->isConnected()) {
|
||||
DEBUG_LOGF("Sending stop command via existing RPC connection...\n");
|
||||
try {
|
||||
rpc_->stop([](const json&) {
|
||||
DEBUG_LOGF("Stop command acknowledged by daemon\n");
|
||||
});
|
||||
rpc_->clearAbort();
|
||||
if (sendStopCommandSafely(*rpc_, "existing connection stop"))
|
||||
stop_sent = true;
|
||||
} catch (...) {
|
||||
DEBUG_LOGF("Failed to send stop via existing connection\n");
|
||||
}
|
||||
}
|
||||
|
||||
// If the main connection wasn't established (e.g. daemon was still
|
||||
|
||||
Reference in New Issue
Block a user