tradingbot/src/server_health_check_team.rs
2024-02-03 16:28:14 +00:00

151 lines
4.8 KiB
Rust

#![allow(unused)]
#![allow(warnings)]
use crate::database_control::*;
use crate::time_checking_team::UserTime;
use rand::*;
use reqwest::{Client, ClientBuilder, Response};
use tokio::join;
use tokio::time::*;
use log;
#[derive(Debug)]
pub struct ServerHealth {
pub server_on: bool, // the total status of server. Its value is decided by AND operation of ping_on and wallet_system_on
// through is_server_on method.
pub ping_on: bool, // ping test to server.
pub wallet_system_on: bool, // check wallet system of server.
pub waiting_maximum: u32, // maximum time for timer to wait until server works on again. the value will be null when the server works on.
}
impl ServerHealth {
pub fn new() -> ServerHealth {
// make an instance and initialize fields
ServerHealth {
server_on: false,
ping_on: false,
wallet_system_on: false,
waiting_maximum: 0,
}
}
}
// to check the current server health and store data into database.
pub async fn execute_server_health_check(
usertime: &mut UserTime,
serverhealth: &mut ServerHealth,
client: &Client,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut rng = rand::rngs::OsRng;
let mut waiting_time: u32;
loop {
update(serverhealth, usertime, &client).await?;
if serverhealth.server_on == true {
serverhealth.waiting_maximum = 0;
// update_database(&serverhealth).await;
break;
} else {
usertime.update_last_server().await;
// whenever server is off, waiting_maximum increases a second
// and thread sleeps for uniform distribution random number between 1sec and waiting_maximum.
serverhealth.waiting_maximum += 1;
waiting_time = rng.gen_range(1..=serverhealth.waiting_maximum);
// update_database(&serverhealth).await;
if waiting_time > 2 {
log::warn!(">>> retry connection after {} second(s).", waiting_time);
}
sleep(Duration::from_secs(waiting_time as u64)).await;
}
}
// println!("server health 완료");
Ok(())
}
// check the server on or off
async fn update(
serverHealth: &mut ServerHealth,
usertime: &mut UserTime,
client: &Client,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let (r1, r2) = join!(check_ping(usertime, &client), check_wallet_system(&client));
serverHealth.ping_on = r1?;
serverHealth.wallet_system_on = r2?;
serverHealth.server_on = serverHealth.ping_on && serverHealth.wallet_system_on;
Ok(())
}
// test ping to server and record the last running time of server (/api, Weight 1)
async fn check_ping(
usertime: &mut UserTime,
client: &Client,
) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
let response = client
.get("https://api.binance.com/api/v3/ping")
.send()
.await;
match response {
Ok(T) => {
let body = T.text_with_charset("utf-8").await?;
if body.contains("{}") {
Ok(true)
} else {
Ok(false)
}
}
Err(e) => Ok(false),
}
}
// check wallet system status (/sapi, Weight 1)
async fn check_wallet_system(
client: &Client,
) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
let response = client
.get("https://api.binance.com/sapi/v1/system/status")
.send()
.await;
match response {
Ok(T) => {
let body = T.text_with_charset("utf-8").await?;
if body.contains("0") {
Ok(true)
} else {
Ok(false)
}
}
Err(E) => Ok(false),
}
}
async fn update_database(serverhealth: &ServerHealth) {
let table_name = String::from("serverhealth");
let mut record: Vec<(&str, &str)> = Vec::new();
let condition = vec![("id", "1")];
let mut server_on = serverhealth.server_on.to_string();
let mut ping_on = serverhealth.ping_on.to_string();
let mut wallet_system_on = serverhealth.wallet_system_on.to_string();
let mut waiting_maximum = serverhealth.waiting_maximum.to_string();
record.push(("server_on", server_on.as_str()));
record.push(("ping_on", ping_on.as_str()));
record.push(("wallet_system_on", wallet_system_on.as_str()));
record.push(("waiting_maximum", waiting_maximum.as_str()));
let mut delete_query_result = update_record(&table_name, &record, &condition).await;
if delete_query_result.is_err() {
loop {
delete_query_result = update_record(&table_name, &record, &condition).await;
if delete_query_result.is_ok() {
break;
}
sleep(Duration::from_millis(10)).await;
}
}
}