diff --git a/Cargo.lock b/Cargo.lock index b145bac..6a3bf4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,7 +291,7 @@ dependencies = [ "objc2", "objc2-app-kit", "objc2-foundation", - "parking_lot", + "parking_lot 0.12.3", "x11rb", ] @@ -1380,7 +1380,7 @@ dependencies = [ "objc2", "objc2-app-kit", "objc2-foundation", - "parking_lot", + "parking_lot 0.12.3", "percent-encoding", "pollster", "raw-window-handle", @@ -1584,7 +1584,7 @@ dependencies = [ "epaint_default_fonts", "log", "nohash-hasher", - "parking_lot", + "parking_lot 0.12.3", ] [[package]] @@ -1777,6 +1777,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -1784,6 +1799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -1792,6 +1808,17 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -1840,6 +1867,7 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1878,8 +1906,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -2095,6 +2125,8 @@ dependencies = [ "readable", "regex", "reqwest", + "reqwest-middleware", + "reqwest-retry", "rfd", "serde", "serde-this-or-that", @@ -2405,6 +2437,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "interpolate_name" version = "0.2.4" @@ -2560,7 +2604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -3278,6 +3322,17 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -3285,7 +3340,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -3705,6 +3774,15 @@ dependencies = [ "windows 0.58.0", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -3811,6 +3889,51 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "reqwest-middleware" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" +dependencies = [ + "anyhow", + "async-trait", + "http", + "reqwest", + "serde", + "thiserror", + "tower-service", +] + +[[package]] +name = "reqwest-retry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a83df1aaec00176d0fabb65dea13f832d2a446ca99107afc17c5d2d4981221d0" +dependencies = [ + "anyhow", + "async-trait", + "futures", + "getrandom", + "http", + "hyper", + "parking_lot 0.11.2", + "reqwest", + "reqwest-middleware", + "retry-policies", + "tokio", + "tracing", + "wasm-timer", +] + +[[package]] +name = "retry-policies" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5875471e6cab2871bc150ecb8c727db5113c9338cc3354dc5ee3425b6aa40a1c" +dependencies = [ + "rand", +] + [[package]] name = "rfd" version = "0.15.0" @@ -4888,6 +5011,21 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wayland-backend" version = "0.3.7" @@ -5062,7 +5200,7 @@ dependencies = [ "js-sys", "log", "naga 22.1.0", - "parking_lot", + "parking_lot 0.12.3", "profiling", "raw-window-handle", "smallvec", @@ -5087,7 +5225,7 @@ dependencies = [ "js-sys", "log", "naga 23.0.0", - "parking_lot", + "parking_lot 0.12.3", "profiling", "raw-window-handle", "smallvec", @@ -5115,7 +5253,7 @@ dependencies = [ "log", "naga 22.1.0", "once_cell", - "parking_lot", + "parking_lot 0.12.3", "profiling", "raw-window-handle", "rustc-hash 1.1.0", @@ -5140,7 +5278,7 @@ dependencies = [ "log", "naga 23.0.0", "once_cell", - "parking_lot", + "parking_lot 0.12.3", "profiling", "raw-window-handle", "rustc-hash 1.1.0", @@ -5179,7 +5317,7 @@ dependencies = [ "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", - "parking_lot", + "parking_lot 0.12.3", "profiling", "raw-window-handle", "renderdoc-sys", @@ -5222,7 +5360,7 @@ dependencies = [ "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", - "parking_lot", + "parking_lot 0.12.3", "profiling", "range-alloc", "raw-window-handle", @@ -5287,7 +5425,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d5b68d7..df09dc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,8 @@ egui_extras = {version="0.29.1", features = ["image"] } env_logger = "0.11.5" figment = { version = "0.10.19", features = ["toml"] } reqwest = {version = "0.12.9", default-features=false, features=["json", "rustls-tls"]} +reqwest-middleware = "0.3" +reqwest-retry = "0.6" image = { version = "0.25.4", features = ["png"] } log = "0.4.22" num-format = { version = "0.4.4", default-features = false } diff --git a/src/app/eframe_impl.rs b/src/app/eframe_impl.rs index 1ed9a73..d3d057f 100644 --- a/src/app/eframe_impl.rs +++ b/src/app/eframe_impl.rs @@ -130,7 +130,7 @@ impl eframe::App for App { // xvb_is_alive is not the same for bottom and for middle. // for status we don't want to enable the column when it is retrying request // but for bottom we don't want the user to be able to start it in this case. - let xvb_is_alive = xvb_state != ProcessState::Retry && xvb_state != ProcessState::Dead; + let xvb_is_alive = xvb_state != ProcessState::Dead; self.middle_panel( ctx, frame, diff --git a/src/app/panels/bottom.rs b/src/app/panels/bottom.rs index 8a00d52..f57b156 100644 --- a/src/app/panels/bottom.rs +++ b/src/app/panels/bottom.rs @@ -914,7 +914,7 @@ fn status_p2pool(state: ProcessState, ui: &mut Ui, size: Vec2) { color = ORANGE; P2POOL_SYNCING } - Middle | Waiting | NotMining | OfflineNodesAll | Retry => { + Middle | Waiting | NotMining | OfflineNodesAll => { color = YELLOW; P2POOL_MIDDLE } @@ -940,7 +940,7 @@ fn status_node(state: ProcessState, ui: &mut Ui, size: Vec2) { color = ORANGE; NODE_SYNCING } - Middle | Waiting | NotMining | OfflineNodesAll | Retry => { + Middle | Waiting | NotMining | OfflineNodesAll => { color = YELLOW; NODE_MIDDLE } @@ -967,7 +967,7 @@ fn status_xmrig(state: ProcessState, ui: &mut Ui, size: Vec2) { color = ORANGE; XMRIG_NOT_MINING } - Middle | Waiting | Syncing | Retry => { + Middle | Waiting | Syncing => { color = YELLOW; XMRIG_MIDDLE } @@ -994,7 +994,7 @@ fn status_xp(state: ProcessState, ui: &mut Ui, size: Vec2) { color = ORANGE; XMRIG_PROXY_NOT_MINING } - Middle | Waiting | Syncing | Retry => { + Middle | Waiting | Syncing => { color = YELLOW; XMRIG_PROXY_MIDDLE } @@ -1012,7 +1012,7 @@ fn status_xvb(state: ProcessState, ui: &mut Ui, size: Vec2) { color = GRAY; XVB_DEAD } - Failed | Retry => { + Failed => { color = RED; XVB_FAILED } diff --git a/src/helper/mod.rs b/src/helper/mod.rs index f59fa8c..6e2049e 100644 --- a/src/helper/mod.rs +++ b/src/helper/mod.rs @@ -196,7 +196,6 @@ impl Process { self.state == ProcessState::Alive || self.state == ProcessState::Middle || self.state == ProcessState::Syncing - || self.state == ProcessState::Retry || self.state == ProcessState::NotMining || self.state == ProcessState::OfflineNodesAll } @@ -219,8 +218,6 @@ pub enum ProcessState { // Only for P2Pool and XvB, ORANGE. // XvB: Xmrig or P2pool are not alive Syncing, - // XvB: if requests for stats fail, retry state to retry every minutes - Retry, // Only for XMRig and XvB, ORANGE. // XvB: token or address are invalid even if syntax correct diff --git a/src/helper/tests.rs b/src/helper/tests.rs index f3e7c33..bb543d4 100644 --- a/src/helper/tests.rs +++ b/src/helper/tests.rs @@ -8,6 +8,7 @@ mod test { xvb::{priv_stats::RuntimeDonationLevel, priv_stats::RuntimeMode}, Helper, Process, ProcessName, ProcessState, }; + use crate::miscs::client; #[test] fn get_current_shares() { @@ -549,11 +550,11 @@ Uptime = 0h 2m 4s }; use crate::helper::xvb::{public_stats::XvbPubStats, PubXvbApi}; - use reqwest::Client; + use reqwest_middleware::ClientWithMiddleware as Client; #[test] fn public_api_deserialize() { - let client = Client::new(); + let client = client(); let new_data = thread::spawn(move || corr(&client)).join().unwrap(); assert!(!new_data.reward_yearly.is_empty()); } @@ -564,7 +565,7 @@ Uptime = 0h 2m 4s #[test] fn test_manual_xvb_mode() { - let client = reqwest::Client::new(); + let client = client(); let pub_api = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xvb = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xmrig = Arc::new(Mutex::new(PubXmrigApi::new())); @@ -603,7 +604,7 @@ Uptime = 0h 2m 4s #[test] fn test_manual_p2pool_mode() { - let client = reqwest::Client::new(); + let client = client(); let pub_api = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xvb = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xmrig = Arc::new(Mutex::new(PubXmrigApi::new())); @@ -642,7 +643,7 @@ Uptime = 0h 2m 4s #[test] fn test_manual_donor_level_mode_donor() { - let client = reqwest::Client::new(); + let client = client(); let pub_api = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xvb = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xmrig = Arc::new(Mutex::new(PubXmrigApi::new())); @@ -686,7 +687,7 @@ Uptime = 0h 2m 4s #[test] fn test_auto_mode() { - let client = reqwest::Client::new(); + let client = client(); let pub_api = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xvb = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xmrig = Arc::new(Mutex::new(PubXmrigApi::new())); @@ -747,7 +748,7 @@ Uptime = 0h 2m 4s #[test] fn test_hero_mode() { - let client = reqwest::Client::new(); + let client = client(); let pub_api = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xvb = Arc::new(Mutex::new(PubXvbApi::new())); let gui_api_xmrig = Arc::new(Mutex::new(PubXmrigApi::new())); diff --git a/src/helper/xrig/mod.rs b/src/helper/xrig/mod.rs index d16ad9d..1dc0d9f 100644 --- a/src/helper/xrig/mod.rs +++ b/src/helper/xrig/mod.rs @@ -3,7 +3,7 @@ use anyhow::anyhow; use anyhow::Result; use log::info; use reqwest::header::AUTHORIZATION; -use reqwest::Client; +use reqwest_middleware::ClientWithMiddleware as Client; use serde::Deserialize; use serde::Serialize; use serde_json::Value; diff --git a/src/helper/xrig/xmrig.rs b/src/helper/xrig/xmrig.rs index f160798..81e341f 100644 --- a/src/helper/xrig/xmrig.rs +++ b/src/helper/xrig/xmrig.rs @@ -3,7 +3,7 @@ use crate::helper::xrig::update_xmrig_config; use crate::helper::{arc_mut, check_died, check_user_input, sleep, sleep_end_loop, Process}; use crate::helper::{Helper, ProcessName, ProcessSignal, ProcessState}; use crate::helper::{PubXvbApi, XvbNode}; -use crate::miscs::output_console; +use crate::miscs::{client, output_console}; use crate::regex::{contains_error, contains_usepool, detect_new_node_xmrig, XMRIG_REGEX}; use crate::utils::human::HumanNumber; use crate::utils::sudo::SudoState; @@ -13,7 +13,7 @@ use portable_pty::Child; use readable::num::Unsigned; use readable::up::Uptime; use reqwest::header::AUTHORIZATION; -use reqwest::Client; +use reqwest_middleware::ClientWithMiddleware as Client; use serde::{Deserialize, Serialize}; use std::path::Path; use std::{ @@ -455,7 +455,7 @@ impl Helper { let output_parse = Arc::clone(&process.lock().unwrap().output_parse); let output_pub = Arc::clone(&process.lock().unwrap().output_pub); - let client = Client::new(); + let client = client(); let start = process.lock().unwrap().start; let api_uri = { if !api_ip_port.ends_with('/') { diff --git a/src/helper/xrig/xmrig_proxy.rs b/src/helper/xrig/xmrig_proxy.rs index 683308a..e914071 100644 --- a/src/helper/xrig/xmrig_proxy.rs +++ b/src/helper/xrig/xmrig_proxy.rs @@ -1,6 +1,7 @@ use enclose::enc; use log::{debug, error, info, warn}; -use reqwest::{header::AUTHORIZATION, Client}; +use reqwest::header::AUTHORIZATION; +use reqwest_middleware::ClientWithMiddleware as Client; use serde::{Deserialize, Serialize}; use std::fmt::Write; use std::{ @@ -11,6 +12,7 @@ use std::{ }; use tokio::spawn; +use crate::miscs::client; use crate::{ disk::state::Xmrig, helper::{ @@ -333,7 +335,7 @@ impl Helper { let api_config_xmrig = XMRIG_CONFIG_URL; // set state - let client = Client::new(); + let client = client(); process.lock().unwrap().state = ProcessState::NotMining; process.lock().unwrap().signal = ProcessSignal::None; // reset stats diff --git a/src/helper/xvb/algorithm.rs b/src/helper/xvb/algorithm.rs index d9a7332..a794593 100644 --- a/src/helper/xvb/algorithm.rs +++ b/src/helper/xvb/algorithm.rs @@ -9,7 +9,7 @@ use std::{ }; use log::{info, warn}; -use reqwest::Client; +use reqwest_middleware::ClientWithMiddleware as Client; use tokio::time::sleep; use crate::{ diff --git a/src/helper/xvb/mod.rs b/src/helper/xvb/mod.rs index b86358b..3fc7e80 100644 --- a/src/helper/xvb/mod.rs +++ b/src/helper/xvb/mod.rs @@ -3,13 +3,13 @@ use crate::helper::xvb::algorithm::algorithm; use crate::helper::xvb::priv_stats::XvbPrivStats; use crate::helper::xvb::public_stats::XvbPubStats; use crate::helper::{sleep_end_loop, ProcessName}; -use crate::miscs::output_console; +use crate::miscs::{client, output_console}; use crate::{XMRIG_CONFIG_URL, XMRIG_PROXY_CONFIG_URL, XMRIG_PROXY_SUMMARY_URL, XMRIG_SUMMARY_URL}; use bounded_vec_deque::BoundedVecDeque; use enclose::enc; use log::{debug, info, warn}; use readable::up::Uptime; -use reqwest::Client; +use reqwest_middleware::ClientWithMiddleware as Client; use std::mem; use std::time::Duration; use std::{ @@ -162,8 +162,7 @@ impl Helper { process_xp: &Arc<Mutex<Process>>, ) { // create uniq client that is going to be used for during the life of the thread. - let client = reqwest::Client::new(); - + let client = client(); // checks confition to start XvB, will set proper state of XvB. // if state is middle (everything fine here),set which xvb node could be used. // should wait for it, because algo needs to not be started if at least one node of XvB are not responsive. @@ -199,6 +198,12 @@ impl Helper { let handle_algo = Arc::new(Mutex::new(None)); let handle_request = Arc::new(Mutex::new(None)); let mut msg_retry_done = false; + + // let's create the memory of last hour average sent to p2pool and XvB + // tuple (p2pool, xvb) + // need to keep it alive even if algo is down, and push values of hashrate sent to p2pool and 0 for XvB. + // spawn a task to keep the values updated, looking at hr and pool direction. + // info!("XvB | Entering Process mode... "); loop { debug!("XvB Watchdog | ----------- Start of loop -----------"); @@ -459,10 +464,6 @@ impl PubXvbApi { runtime_manual_donation_level, ..pub_api.stats_priv.clone() }, - p2pool_sent_last_hour_samples: std::mem::take( - &mut gui_api.p2pool_sent_last_hour_samples, - ), - xvb_sent_last_hour_samples: std::mem::take(&mut gui_api.xvb_sent_last_hour_samples), ..pub_api.clone() }; } @@ -667,10 +668,6 @@ async fn check_state_outcauses_xvb( ProcessName::Xvb, ); } - ProcessState::Retry => { - debug!("XvB | Retry to get stats from https://xmrvsbeast.com in this loop if delay is done."); - *first_loop = true; - } // nothing to do, we don't want to change other state _ => {} }; diff --git a/src/helper/xvb/nodes.rs b/src/helper/xvb/nodes.rs index 9411776..ce10aca 100644 --- a/src/helper/xvb/nodes.rs +++ b/src/helper/xvb/nodes.rs @@ -5,7 +5,7 @@ use std::{ use derive_more::Display; use log::{error, info, warn}; -use reqwest::Client; +use reqwest_middleware::ClientWithMiddleware as Client; use tokio::spawn; use crate::{ @@ -128,9 +128,7 @@ impl XvbNode { // could be used by xmrig who signal that a node is not joignable // or by the start of xvb // next iteration of the loop of XvB process will verify if all conditions are met to be alive. - if process_xvb.lock().unwrap().state != ProcessState::Syncing - && process_xvb.lock().unwrap().state != ProcessState::Retry - { + if process_xvb.lock().unwrap().state != ProcessState::Syncing { process_xvb.lock().unwrap().state = ProcessState::Syncing; } } diff --git a/src/helper/xvb/priv_stats.rs b/src/helper/xvb/priv_stats.rs index 15f4fec..d46afa8 100644 --- a/src/helper/xvb/priv_stats.rs +++ b/src/helper/xvb/priv_stats.rs @@ -4,10 +4,10 @@ use std::{ }; use anyhow::bail; -use log::{debug, error, warn}; -use reqwest::{Client, StatusCode}; +use log::{debug, error, info, warn}; +use reqwest::StatusCode; +use reqwest_middleware::ClientWithMiddleware as Client; use serde::Deserialize; -use tokio::time::sleep; use crate::{ disk::state::ManualDonationLevel, @@ -90,7 +90,7 @@ impl XvbPrivStats { ] .concat(), ) - .timeout(Duration::from_secs(5)) + .timeout(Duration::from_secs(10)) .send() .await?; match resp.status() { @@ -122,6 +122,16 @@ impl XvbPrivStats { Ok(new_data) => { debug!("XvB Watchdog | HTTP API request OK"); pub_api.lock().unwrap().stats_priv = new_data; + let previously_failed = process.lock().unwrap().state == ProcessState::Failed; + if previously_failed { + info!("XvB Watchdog | Public stats are working again"); + output_console( + &mut gui_api.lock().unwrap().output, + "requests for public API are now working", + ProcessName::Xvb, + ); + process.lock().unwrap().state = ProcessState::Syncing; + } // if last request failed, we are now ready to show stats again and maybe be alive next loop. } Err(err) => { @@ -129,22 +139,20 @@ impl XvbPrivStats { "XvB Watchdog | Could not send HTTP private API request to: {}\n:{}", XVB_URL, err ); + if process.lock().unwrap().state != ProcessState::Failed { + output_console( + &mut gui_api.lock().unwrap().output, + "Failure to retrieve private stats \nWill retry shortly...", + ProcessName::Xvb, + ); + } + // we stop the algo (will be stopped by the check status on next loop) because we can't make the rest work without public stats. (winner in xvb private stats). output_console( &mut gui_api.lock().unwrap().output, - &format!( - "Failure to retrieve private stats from {} because of this error: {}", - XVB_URL, err - ), + "request to get private API failed", ProcessName::Xvb, ); - process.lock().unwrap().state = ProcessState::Retry; - // sleep here because it is in a spawn and will not block the user stopping or restarting the service. - output_console( - &mut gui_api.lock().unwrap().output, - "Waiting 10 seconds before trying to get stats again.", - ProcessName::Xvb, - ); - sleep(Duration::from_secs(10)).await; + process.lock().unwrap().state = ProcessState::Failed; } } } diff --git a/src/helper/xvb/public_stats.rs b/src/helper/xvb/public_stats.rs index 0172ca0..28aa148 100644 --- a/src/helper/xvb/public_stats.rs +++ b/src/helper/xvb/public_stats.rs @@ -3,11 +3,10 @@ use std::{ time::Duration, }; -use log::{debug, warn}; -use reqwest::Client; +use log::{debug, info, warn}; +use reqwest_middleware::ClientWithMiddleware as Client; use serde::Deserialize; use serde_this_or_that::as_u64; -use tokio::time::sleep; use crate::{ helper::{xvb::output_console, Process, ProcessName, ProcessState}, @@ -47,7 +46,7 @@ impl XvbPubStats { ) -> std::result::Result<Self, anyhow::Error> { Ok(client .get(XVB_URL_PUBLIC_API) - .timeout(Duration::from_secs(5)) + .timeout(Duration::from_secs(10)) .send() .await? .json::<Self>() @@ -64,24 +63,25 @@ impl XvbPubStats { Ok(new_data) => { debug!("XvB Watchdog | HTTP API request OK"); pub_api.lock().unwrap().stats_pub = new_data; - // if last request failed, we are now ready to show stats again and maybe be alive next loop. - if process.lock().unwrap().state == ProcessState::Retry { - process.lock().unwrap().state = ProcessState::Syncing; + let previously_failed = process.lock().unwrap().state == ProcessState::Failed; + if previously_failed { + info!("XvB Watchdog | Public stats are working again"); output_console( &mut gui_api.lock().unwrap().output, - "Stats are now working again after last successful request.", + "requests for public API are now working", ProcessName::Xvb, ); + process.lock().unwrap().state = ProcessState::Syncing; } } Err(err) => { warn!( - "XvB Watchdog | Could not send HTTP API request to: {}\n:{}", + "XvB Watchdog | Could not send HTTP API request to: {} even after multiples tries\n:{}", XVB_URL_PUBLIC_API, err ); // output the error to console // if error already present, no need to print it multiple times. - if process.lock().unwrap().state != ProcessState::Retry { + if process.lock().unwrap().state != ProcessState::Failed { output_console( &mut gui_api.lock().unwrap().output, &format!( @@ -92,14 +92,12 @@ impl XvbPubStats { ); } // we stop the algo (will be stopped by the check status on next loop) because we can't make the rest work without public stats. (winner in xvb private stats). - process.lock().unwrap().state = ProcessState::Retry; - // sleep here because it is in a spawn and will not block the user stopping or restarting the service. output_console( &mut gui_api.lock().unwrap().output, - "Waiting 10 seconds before trying to get stats again.", + "request to get public API failed", ProcessName::Xvb, ); - sleep(Duration::from_secs(10)).await; + process.lock().unwrap().state = ProcessState::Failed; } } } diff --git a/src/miscs.rs b/src/miscs.rs index 94c8f85..68a7b1d 100644 --- a/src/miscs.rs +++ b/src/miscs.rs @@ -2,6 +2,7 @@ // Get absolute [Gupax] binary path use std::fmt::Write; +use std::time::Duration; #[cold] #[inline(never)] pub fn get_exe() -> Result<String, std::io::Error> { @@ -134,6 +135,7 @@ use chrono::Local; use log::error; use log::warn; use regex::Regex; +use reqwest_middleware::ClientWithMiddleware; use std::path::PathBuf; use std::process::exit; use std::sync::Arc; @@ -170,3 +172,13 @@ pub fn output_console_without_time(output: &mut String, msg: &str, p_name: Proce fn datetimeonsole() -> String { format!("[{}] ", Local::now().format("%Y-%m-%d %H:%M:%S%.3f")) } + +pub fn client() -> ClientWithMiddleware { + reqwest_middleware::ClientBuilder::new(reqwest::Client::new()) + .with(reqwest_retry::RetryTransientMiddleware::new_with_policy( + reqwest_retry::policies::ExponentialBackoff::builder() + .retry_bounds(Duration::from_secs(1), Duration::from_secs(5)) + .build_with_total_retry_duration(Duration::from_secs(20)), + )) + .build() +}