diff --git a/src/app.cpp b/src/app.cpp index 3bb21f8..1d9fe8b 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -760,13 +760,18 @@ void App::update() } } - // Poll pending z_sendmany operations for completion (full-node opid flow; lite has none) + // Poll pending z_sendmany operations for completion (full-node opid flow; lite has none). + // Prefer the fast lane but fall back to the main worker (mirrors every other fast_worker_ user) + // so a torn-down/not-yet-restarted fast lane can't silently strand the poll on "Waiting for + // operation" — the symptom when fast_worker_ was stopped on reconnect and never came back. + rpc::RPCWorker* opidWorker = (fast_worker_ && fast_worker_->isRunning()) + ? fast_worker_.get() : worker_.get(); if (network_refresh_.isDue(RefreshTimer::Opid) && !pending_opids_.empty() - && rpcConnected && fast_worker_ && !opid_poll_in_progress_) { + && rpcConnected && opidWorker && !opid_poll_in_progress_) { network_refresh_.reset(RefreshTimer::Opid); auto opids = pending_opids_; // copy for worker thread opid_poll_in_progress_ = true; - fast_worker_->post([this, opids]() -> rpc::RPCWorker::MainCb { + opidWorker->post([this, opids]() -> rpc::RPCWorker::MainCb { auto* rpc = (fast_rpc_ && fast_rpc_->isConnected()) ? fast_rpc_.get() : rpc_.get(); if (!rpc) return [this](){ opid_poll_in_progress_ = false; }; json ids = json::array(); diff --git a/src/app_network.cpp b/src/app_network.cpp index 544b119..d9bb1b2 100644 --- a/src/app_network.cpp +++ b/src/app_network.cpp @@ -582,6 +582,11 @@ void App::onDisconnected(const std::string& reason) if (fast_rpc_) fast_rpc_->requestAbort(); if (fast_worker_) { fast_worker_->stop(); + // Drop the stopped worker so onConnected recreates and starts a fresh one. Keeping a + // stopped-but-present worker would defeat onConnected's `if (!fast_worker_)` guard, leaving + // the fast lane dead for the rest of the session — which silently stalls the opid poll + // (its post() never runs, so a completed send spins on "Waiting for operation"). + fast_worker_.reset(); } if (fast_rpc_) { fast_rpc_->disconnect();