fix(console): release busy gate when the fast worker stops
When the daemon disconnects, teardown stops the fast RPC worker without draining its queued main-thread callbacks. The console busy gate was released inside that callback, so a command whose callback was discarded left the input disabled for the rest of the session. - The busy gate now drops from an RAII guard at the end of the worker job itself, so it is released however the job ends: success, error, or a worker torn down undrained. - The result is published to the console before the gate drops, so a freed-up console always has the output queued. - An unknown, non-std::exception failure is now caught and reported instead of escaping the job. User-visible: the Console input can no longer stay stuck disabled after a reconnect. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,12 @@ void FullNodeConsoleExecutor::submit(const std::string& cmd)
|
||||
if (worker) {
|
||||
in_flight_.fetch_add(1); // gates busy() so the input is disabled until this returns
|
||||
worker->post([rpc, method, params, this]() -> rpc::RPCWorker::MainCb {
|
||||
// Drops the busy gate when the worker job ends, however it ends. The gate used to drop in the
|
||||
// MainCb, which is lost when teardown stops the fast worker undrained, leaving busy() stuck.
|
||||
struct ReleaseGate {
|
||||
std::atomic<int>& n;
|
||||
~ReleaseGate() { n.fetch_sub(1); }
|
||||
} gate{in_flight_};
|
||||
std::string result_str;
|
||||
bool is_error = false;
|
||||
try {
|
||||
@@ -129,14 +135,19 @@ void FullNodeConsoleExecutor::submit(const std::string& cmd)
|
||||
} catch (const std::exception& e) {
|
||||
result_str = e.what();
|
||||
is_error = true;
|
||||
} catch (...) {
|
||||
result_str = "RPC failed (unknown error)";
|
||||
is_error = true;
|
||||
}
|
||||
return [this, result_str, is_error]() {
|
||||
in_flight_.fetch_sub(1);
|
||||
{
|
||||
// Publish the result before the gate drops, so a non-busy console always has it queued.
|
||||
std::lock_guard<std::mutex> lk(results_mutex_);
|
||||
results_.push_back({result_str, is_error});
|
||||
}
|
||||
return [this]() {
|
||||
// A Console command may have changed the wallet (a send, an import, a new address): the
|
||||
// scans gated on change signals must look again. (Main thread: this is a drained callback.)
|
||||
if (app_) app_->noteWalletMutation();
|
||||
std::lock_guard<std::mutex> lk(results_mutex_);
|
||||
results_.push_back({result_str, is_error});
|
||||
};
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user