feat: retry and reload XvB automaticcly if requests for stats fails

retry every ten seconds
red status
disable column XvB stats
user can stop/restart service
This commit is contained in:
Cyrix126 2024-04-05 13:28:23 +02:00
parent 70250775ec
commit c203f45d34
7 changed files with 73 additions and 22 deletions

View file

@ -1,4 +1,5 @@
use super::App;
use crate::helper::ProcessState;
use crate::macros::lock;
use crate::SECOND;
use egui::CentralPanel;
@ -93,6 +94,10 @@ impl eframe::App for App {
xmrig_is_alive,
xvb_is_alive,
);
// 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;
self.middle_panel(
ctx,
frame,

View file

@ -605,7 +605,7 @@ fn status_p2pool(state: ProcessState, ui: &mut Ui, size: Vec2) {
color = ORANGE;
P2POOL_SYNCING
}
Middle | Waiting | NotMining | OfflineNodesAll => {
Middle | Waiting | NotMining | OfflineNodesAll | Retry => {
color = YELLOW;
P2POOL_MIDDLE
}
@ -632,7 +632,7 @@ fn status_xmrig(state: ProcessState, ui: &mut Ui, size: Vec2) {
color = ORANGE;
XMRIG_NOT_MINING
}
Middle | Waiting | Syncing => {
Middle | Waiting | Syncing | Retry => {
color = YELLOW;
XMRIG_MIDDLE
}
@ -650,7 +650,7 @@ fn status_xvb(state: ProcessState, ui: &mut Ui, size: Vec2) {
color = GRAY;
XVB_DEAD
}
Failed => {
Failed | Retry => {
color = RED;
XVB_FAILED
}

View file

@ -183,7 +183,9 @@ 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
}
#[inline]
@ -204,6 +206,8 @@ 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

View file

@ -200,7 +200,8 @@ impl Helper {
pub_api_xmrig,
state_p2pool,
state_xmrig,
);
)
.await;
// check signal
debug!("XvB | check signal");
@ -283,7 +284,7 @@ impl Helper {
lock!(pub_api).stats_priv.win_current = true
}
}
if (first_loop || *lock!(retry)|| is_algo_finished) && lock!(gui_api_xmrig).hashrate_raw > 0.0
if (first_loop || *lock!(retry)|| is_algo_finished) && lock!(gui_api_xmrig).hashrate_raw > 0.0 && lock!(process).state == ProcessState::Alive
{
// if algo was started, it must not retry next loop.
*lock!(retry) = false;
@ -302,8 +303,9 @@ impl Helper {
).await;
})));
} else {
// if xmrig is still at 0 HR but is alive and algorithm is skipped, recheck first 10s of xmrig inside algorithm next time (in one minute)
if lock!(gui_api_xmrig).hashrate_raw == 0.0 {
// if xmrig is still at 0 HR but is alive and algorithm is skipped, recheck first 10s of xmrig inside algorithm next time (in one minute). Don't check if algo failed to start because state was not alive after getting private stats.
if lock!(gui_api_xmrig).hashrate_raw == 0.0 && lock!(process).state == ProcessState::Alive {
*lock!(retry) = true
}
}
@ -468,7 +470,7 @@ async fn check_conditions_for_start(
lock!(process_xvb).state = state;
}
#[allow(clippy::too_many_arguments)]
fn check_state_outcauses_xvb(
async fn check_state_outcauses_xvb(
client: &Client,
gui_api: &Arc<Mutex<PubXvbApi>>,
pub_api: &Arc<Mutex<PubXvbApi>>,
@ -560,6 +562,10 @@ fn check_state_outcauses_xvb(
"XvB is now started because p2pool and xmrig came online.",
);
}
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
_ => {}
};

View file

@ -120,7 +120,11 @@ 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.
lock!(process_xvb).state = ProcessState::Syncing;
if lock!(process_xvb).state != ProcessState::Syncing
&& lock!(process_xvb).state != ProcessState::Retry
{
lock!(process_xvb).state = ProcessState::Syncing;
}
}
lock!(pub_api_xvb).stats_priv.node = node;
}

View file

@ -1,12 +1,16 @@
use std::sync::{Arc, Mutex};
use std::{
sync::{Arc, Mutex},
time::Duration,
};
use anyhow::bail;
use log::{debug, error, warn};
use reqwest::{Client, StatusCode};
use serde::Deserialize;
use tokio::time::sleep;
use crate::{
helper::{xvb::output_console, Process, ProcessSignal, ProcessState},
helper::{xvb::output_console, Process, ProcessState},
macros::lock,
XVB_URL,
};
@ -48,6 +52,7 @@ impl XvbPrivStats {
]
.concat(),
)
.timeout(Duration::from_secs(5))
.send()
.await?;
match resp.status() {
@ -79,6 +84,7 @@ impl XvbPrivStats {
Ok(new_data) => {
debug!("XvB Watchdog | HTTP API request OK");
lock!(&pub_api).stats_priv = new_data;
// if last request failed, we are now ready to show stats again and maybe be alive next loop.
}
Err(err) => {
warn!(
@ -89,8 +95,13 @@ impl XvbPrivStats {
gui_api,
&format!("Failure to retrieve private stats from {}", XVB_URL),
);
lock!(process).state = ProcessState::Failed;
lock!(process).signal = ProcessSignal::Stop;
lock!(process).state = ProcessState::Retry;
// sleep here because it is in a spawn and will not block the user stopping or restarting the service.
output_console(
gui_api,
"Waiting 10 seconds before trying to get stats again.",
);
sleep(Duration::from_secs(10)).await;
}
}
}

View file

@ -1,12 +1,16 @@
use std::sync::{Arc, Mutex};
use std::{
sync::{Arc, Mutex},
time::Duration,
};
use log::{debug, warn};
use reqwest::Client;
use serde::Deserialize;
use serde_this_or_that::as_u64;
use tokio::time::sleep;
use crate::{
helper::{xvb::output_console, Process, ProcessSignal, ProcessState},
helper::{xvb::output_console, Process, ProcessState},
macros::lock,
XVB_URL_PUBLIC_API,
};
@ -43,6 +47,7 @@ impl XvbPubStats {
) -> std::result::Result<Self, anyhow::Error> {
Ok(client
.get(XVB_URL_PUBLIC_API)
.timeout(Duration::from_secs(5))
.send()
.await?
.json::<Self>()
@ -59,6 +64,14 @@ impl XvbPubStats {
Ok(new_data) => {
debug!("XvB Watchdog | HTTP API request OK");
lock!(&pub_api).stats_pub = new_data;
// if last request failed, we are now ready to show stats again and maybe be alive next loop.
if lock!(process).state == ProcessState::Retry {
lock!(process).state = ProcessState::Syncing;
output_console(
gui_api,
"Stats are now working again after last successful request.",
);
}
}
Err(err) => {
warn!(
@ -66,16 +79,24 @@ impl XvbPubStats {
XVB_URL_PUBLIC_API, err
);
// output the error to console
// if error already present, no need to print it multiple times.
if lock!(process).state != ProcessState::Retry {
output_console(
gui_api,
&format!(
"Failure to retrieve public stats from {}\nWill retry shortly...",
XVB_URL_PUBLIC_API
),
);
}
// 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).
lock!(process).state = ProcessState::Retry;
// sleep here because it is in a spawn and will not block the user stopping or restarting the service.
output_console(
gui_api,
&format!(
"Failure to retrieve public stats from {}",
XVB_URL_PUBLIC_API
),
"Waiting 10 seconds before trying to get stats again.",
);
// we stop because we can't make the rest work without public stats. (winner in xvb private stats).
lock!(process).state = ProcessState::Failed;
lock!(process).signal = ProcessSignal::Stop;
sleep(Duration::from_secs(10)).await;
}
}
}