perf(market): fetch price and market data on a dedicated HTTP lane
The CoinGecko price, tickers and market chart and the exchange candle GETs ran on the wallet's RPC worker, the same FIFO lane as balance, history and sends. A slow or blocked endpoint held that lane for up to 10-12 s per price or ticker fetch and 2 x 30 s per chart or candle job, and a wallet scan in turn delayed the price. At quit a hung GET held shutdown until the 15 s watchdog cut teardown short. They now run on their own RPCWorker thread; results are applied on the main thread and wake the idle loop. A new util::httpGet takes a cancel flag (checked by libcurl's progress callback), sets CURLOPT_NOSIGNAL and returns the HTTP status and error; httpGetString wraps it. Shutdown sets the flag, so queued GETs return at once and one in flight aborts within about a second. The price uses a plain in-flight flag instead of the connection-scoped refresh job, so a disconnect no longer throws away a good in-flight price and leaves it loading until the next tick. User-visible: - chart and candle GETs use a 5 s connect / 20 s total timeout (were 15 s / 30 s); - the price request goes through the shared GET: User-Agent ObsidianDragon/1.0 (was DragonX-Wallet/1.0) and a 16 MiB reply cap; - market fetches on connect start alongside the wallet refresh instead of queuing behind it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -762,9 +762,9 @@ public:
|
||||
void verifyDebugCredential(const std::string& secret, std::function<void(bool)> cb);
|
||||
|
||||
/// @brief Something finished on a background thread and waits for update() to apply it on the main thread
|
||||
/// (the RPC worker lanes). main.cpp's idle loop polls this every <= 200 ms (hasImmediateWork) and renders a
|
||||
/// frame when it is true, so the result shows without input, even while the window is hidden. A new lane whose
|
||||
/// results are applied in update() adds its term HERE.
|
||||
/// (the RPC worker lanes, the HTTP lane). main.cpp's idle loop polls this every <= 200 ms (hasImmediateWork) and
|
||||
/// renders a frame when it is true, so the result shows without input, even while the window is hidden. A new
|
||||
/// lane whose results are applied in update() adds its term HERE.
|
||||
bool hasPendingBackgroundResults() const;
|
||||
bool hasTransactionSendProgress() const { return send_progress_active_ || send_submissions_in_flight_ > 0 || !pending_opids_.empty(); }
|
||||
std::string transactionSendProgressText() const;
|
||||
@@ -896,6 +896,15 @@ private:
|
||||
std::unique_ptr<rpc::RPCClient> fast_rpc_;
|
||||
std::unique_ptr<rpc::RPCWorker> fast_worker_;
|
||||
|
||||
// HTTP lane: price / tickers / market chart / exchange candle GETs on their own thread, so a slow or
|
||||
// blocked HTTP endpoint never queues in front of wallet RPCs on worker_ (and wallet scans never delay the
|
||||
// price). Not tied to the daemon connection: started in init(), stopped only at shutdown. Work functions
|
||||
// touch only http_cancel_ and their captures; results apply in MainCbs (main thread). http_cancel_ is
|
||||
// declared BEFORE http_worker_ on purpose: members die in reverse order, and the lane's thread reads the
|
||||
// flag until ~RPCWorker joins it.
|
||||
std::atomic<bool> http_cancel_{false}; // set at shutdown: queued GETs return at once, an in-flight one aborts
|
||||
std::unique_ptr<rpc::RPCWorker> http_worker_;
|
||||
|
||||
// Saved connection credentials (needed to open the fast-lane connection)
|
||||
rpc::ConnectionConfig saved_config_;
|
||||
|
||||
@@ -1154,6 +1163,7 @@ private:
|
||||
std::string exchange_chart_fail_key_;
|
||||
std::chrono::steady_clock::time_point market_manual_retry_at_{};
|
||||
bool price_fetch_failed_ = false; // last price fetch failed (connectivity probe for the backoffs)
|
||||
bool price_fetch_in_flight_ = false; // a price GET is on http_worker_ (main thread only)
|
||||
// Per-exchange candle chart (refreshExchangeChart): which pair the loaded series is for, an
|
||||
// in-flight guard, and a slow refresh timer (candles move slowly, like the aggregate chart).
|
||||
std::string exchange_chart_key_; // "<identifier>:<BASE>/<QUOTE>" of the loaded series ("" = none)
|
||||
|
||||
Reference in New Issue
Block a user