From adbbd52b3eaf491da14c1802abee26df999d6929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Mon, 11 Mar 2024 03:34:52 +0300 Subject: [PATCH 1/3] feat: :sparkles: always control server status --- front/Cargo.toml | 1 + front/src/main.rs | 99 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 26 deletions(-) diff --git a/front/Cargo.toml b/front/Cargo.toml index 80c79ad..890291c 100644 --- a/front/Cargo.toml +++ b/front/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-std = "1.12.0" dioxus = { version = "0.5.0-alpha.0", features = ["web"] } log = "0.4.21" reqwest = { version = "0.11.24", features = ["json"] } diff --git a/front/src/main.rs b/front/src/main.rs index 0e2e411..cab0a88 100644 --- a/front/src/main.rs +++ b/front/src/main.rs @@ -1,7 +1,15 @@ +use std::time::Duration; +use async_std::task; use dioxus::prelude::*; use serde::Deserialize; const SERVER_ADDRESS: &str = "https://localhost:2323"; + +static SERVER_STATUS:GlobalSignal = Signal::global(move || ServerStatus {status:"Alive".to_string(),}); +static SERVER_STATUS_WATCHDOG:GlobalSignal = Signal::global(move || false); +static SERVER_STATUS_LOOSING:GlobalSignal = Signal::global(move || false); +static SERVER_STATUS_IS_DEAD:GlobalSignal = Signal::global(move || false); + #[derive(Debug, Clone, PartialEq, Deserialize)] struct ServerStatus{ status: String, @@ -17,8 +25,26 @@ fn main() { launch(app); } -async fn server_status_check() ->Result { - Ok(reqwest::get(SERVER_ADDRESS).await.unwrap().json::().await.unwrap()) +async fn server_status_check() ->ServerStatus { + match reqwest::get(SERVER_ADDRESS).await { + Ok(response) => { + *SERVER_STATUS_WATCHDOG.write() = false; + match response.json::().await { + Ok(server_status) => { + *SERVER_STATUS_LOOSING.write() = false; + server_status + } + Err(err_val) => { + *SERVER_STATUS_LOOSING.write() = true; + ServerStatus{status:err_val.to_string(),} + } + } + } + Err(err_val) => { + *SERVER_STATUS_LOOSING.write() = true; + ServerStatus{status:err_val.to_string(),} + } + } } async fn coin_status_check() -> Result { Ok(reqwest::get(format!("{}{}", SERVER_ADDRESS, "/coin")).await.unwrap().json::().await.unwrap()) @@ -46,34 +72,57 @@ fn page_base() ->Element { } } } - fn server_status_renderer() -> Element { - let server_status = use_resource(move || server_status_check()); - match &*server_status.value().read() { - Some(Ok(server_status)) => { - rsx! { - h5 { - ShowServerStatus { server_status: server_status.clone() } + let server_check_time = 1_u64; + let _server_status_task:Coroutine<()> = use_coroutine(|_| async move { + loop { + task::sleep(Duration::from_secs(server_check_time)).await; + *SERVER_STATUS_WATCHDOG.write() = true; + *SERVER_STATUS.write() = server_status_check().await; + /*match server_status_check().await { + Ok(status) => { + server_status_watchdog.set(false); + server_status.set(status); } - } + Err(err_val) => { + server_status.set(ServerStatus {status:err_val.to_string(),}); + } + }*/ - } - Some(Err(err_val)) => { - rsx! { - h5 { - "Server Status: " - { err_val.to_string() } + }; + }); + let _server_status_watchdog_timer:Coroutine<()> = use_coroutine(|_| async move { + let mut is_loosing_counter = 0_i8; + loop { + task::sleep(Duration::from_secs(2*server_check_time+1)).await; + if !SERVER_STATUS_WATCHDOG() { + *SERVER_STATUS_LOOSING.write() = false; } - } - } - None => { - rsx! { - h5 { - "Server Status: Dead" + if SERVER_STATUS_WATCHDOG() { + for _i in 0..5 { + task::sleep(Duration::from_secs(1)).await; + if SERVER_STATUS_WATCHDOG() { + is_loosing_counter += 1; + } + } + } - } + if is_loosing_counter > 4 { + *SERVER_STATUS_LOOSING.write() = true; + } + is_loosing_counter = 0; + } + }); + rsx! { + if SERVER_STATUS_LOOSING() && SERVER_STATUS_WATCHDOG() { + {*SERVER_STATUS_IS_DEAD.write() = true} + ShowServerStatus {server_status:ServerStatus{status:"Dead".to_string(),}} + } + else { + ShowServerStatus {server_status:SERVER_STATUS()} } } + } fn coin_status_renderer() -> Element { let is_loading = use_signal(|| false); @@ -89,15 +138,13 @@ fn coin_status_renderer() -> Element { is_loading.set(false); coin_result.set(coin_status); } - Err(err_val) => { + Err(_) => { is_loading.set(false); - log::info!("{}", err_val); } } } }); }; - log::info!("{}", is_loading); rsx! { div { button { From a6e95affabe07194af844fa10db640db35bda7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Fri, 15 Mar 2024 03:10:00 +0300 Subject: [PATCH 2/3] refactor: :recycle: global signals removed refactor: :recycle: type restrictions for statuses --- back/src/routing.rs | 18 ++++++-- front/src/main.rs | 110 +++++++++++++++++++++++++------------------- 2 files changed, 78 insertions(+), 50 deletions(-) diff --git a/back/src/routing.rs b/back/src/routing.rs index 7a1a647..e9c966e 100644 --- a/back/src/routing.rs +++ b/back/src/routing.rs @@ -1,8 +1,20 @@ use crate::AppState; use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Json, Router}; +use serde::{Deserialize, Serialize}; use tower_http::cors::CorsLayer; use rand::prelude::*; +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +enum ServerStatus{ + Alive, + Unstable, + Dead, +} +#[derive(Debug, Clone, PartialEq, Serialize,Deserialize)] +enum CoinStatus{ + Tail, + Head, +} pub async fn routing(State(state): State) -> Router { Router::new() @@ -14,7 +26,7 @@ pub async fn routing(State(state): State) -> Router { async fn alive() -> impl IntoResponse { let alive_json = serde_json::json!({ - "status":"Alive", + "status":ServerStatus::Alive, }); println!("{}", alive_json); (StatusCode::OK, Json(alive_json)) @@ -23,9 +35,9 @@ async fn alive() -> impl IntoResponse { async fn flip_coin() -> impl IntoResponse { let mut rng = rand::thread_rng(); let random:f64 = rng.gen(); - let mut flip_status:String = "Tail".to_string(); + let mut flip_status = CoinStatus::Tail; if random > 0.5 { - flip_status = "Head".to_string(); + flip_status = CoinStatus::Head; } let coin_json = serde_json::json!({ "status":flip_status, diff --git a/front/src/main.rs b/front/src/main.rs index cab0a88..dca26e4 100644 --- a/front/src/main.rs +++ b/front/src/main.rs @@ -2,21 +2,43 @@ use std::time::Duration; use async_std::task; use dioxus::prelude::*; use serde::Deserialize; - const SERVER_ADDRESS: &str = "https://localhost:2323"; -static SERVER_STATUS:GlobalSignal = Signal::global(move || ServerStatus {status:"Alive".to_string(),}); -static SERVER_STATUS_WATCHDOG:GlobalSignal = Signal::global(move || false); -static SERVER_STATUS_LOOSING:GlobalSignal = Signal::global(move || false); -static SERVER_STATUS_IS_DEAD:GlobalSignal = Signal::global(move || false); - #[derive(Debug, Clone, PartialEq, Deserialize)] -struct ServerStatus{ - status: String, +enum Server{ + Alive, + Unstable, + Dead, +} +impl Server { + fn to_string(&mut self) -> String{ + match self { + Self::Alive => {String::from("Alive")}, + Self::Unstable => {String::from("Unstable")}, + Self::Dead => {String::from("Dead")}, + } + } } #[derive(Debug, Clone, PartialEq, Deserialize)] -struct CoinStatus{ - status: String, +enum Coin{ + Tail, + Head, +} +impl Coin { + fn to_string(&mut self) -> String { + match self { + Self::Head => {String::from("Head")}, + Self::Tail => {String::from("Tail")}, + } + } +} +#[derive(Debug, Clone, PartialEq, Deserialize)] +struct ServerStatus { + status:Server, +} +#[derive(Debug, Clone, PartialEq, Deserialize)] +struct CoinStatus { + status:Coin, } fn main() { @@ -25,24 +47,25 @@ fn main() { launch(app); } -async fn server_status_check() ->ServerStatus { +async fn server_status_check(mut server_status:Signal) ->ServerStatus { match reqwest::get(SERVER_ADDRESS).await { Ok(response) => { - *SERVER_STATUS_WATCHDOG.write() = false; match response.json::().await { - Ok(server_status) => { - *SERVER_STATUS_LOOSING.write() = false; - server_status + Ok(_) => { + *server_status.write() = ServerStatus{status:Server::Alive,}; + ServerStatus{status:Server::Alive,} } Err(err_val) => { - *SERVER_STATUS_LOOSING.write() = true; - ServerStatus{status:err_val.to_string(),} + *server_status.write() = ServerStatus{status:Server::Dead,}; + log::info!("{}", err_val); + ServerStatus{status:Server::Dead,} } } } Err(err_val) => { - *SERVER_STATUS_LOOSING.write() = true; - ServerStatus{status:err_val.to_string(),} + *server_status.write() = ServerStatus{status:Server::Dead,}; + log::info!("{}", err_val); + ServerStatus{status:Server::Dead,} } } } @@ -74,59 +97,52 @@ fn page_base() ->Element { } fn server_status_renderer() -> Element { let server_check_time = 1_u64; + let mut server_status = use_signal(move || ServerStatus{status:Server::Unstable,}); + let mut server_status_watchdog = use_signal(move|| false); + let mut server_status_unstable = use_signal(move|| false); let _server_status_task:Coroutine<()> = use_coroutine(|_| async move { loop { task::sleep(Duration::from_secs(server_check_time)).await; - *SERVER_STATUS_WATCHDOG.write() = true; - *SERVER_STATUS.write() = server_status_check().await; - /*match server_status_check().await { - Ok(status) => { - server_status_watchdog.set(false); - server_status.set(status); - } - Err(err_val) => { - server_status.set(ServerStatus {status:err_val.to_string(),}); - } - }*/ - + *server_status_watchdog.write() = true; + *server_status.write() = server_status_check(server_status).await; + *server_status_watchdog.write() = false; }; }); let _server_status_watchdog_timer:Coroutine<()> = use_coroutine(|_| async move { - let mut is_loosing_counter = 0_i8; + let mut watchdog_counter = 0_i8; loop { task::sleep(Duration::from_secs(2*server_check_time+1)).await; - if !SERVER_STATUS_WATCHDOG() { - *SERVER_STATUS_LOOSING.write() = false; + if !server_status_watchdog() { + *server_status_unstable.write() = false; } - if SERVER_STATUS_WATCHDOG() { + if server_status_watchdog() { for _i in 0..5 { task::sleep(Duration::from_secs(1)).await; - if SERVER_STATUS_WATCHDOG() { - is_loosing_counter += 1; + if server_status_watchdog() { + watchdog_counter += 1; } } } - if is_loosing_counter > 4 { - *SERVER_STATUS_LOOSING.write() = true; + if watchdog_counter > 4 { + *server_status_unstable.write() = true; } - is_loosing_counter = 0; + watchdog_counter = 0; } }); rsx! { - if SERVER_STATUS_LOOSING() && SERVER_STATUS_WATCHDOG() { - {*SERVER_STATUS_IS_DEAD.write() = true} - ShowServerStatus {server_status:ServerStatus{status:"Dead".to_string(),}} + if server_status_unstable() && server_status_watchdog() { + ShowServerStatus {server_status:ServerStatus{status:Server::Dead,}} } else { - ShowServerStatus {server_status:SERVER_STATUS()} + ShowServerStatus {server_status:server_status()} } } } fn coin_status_renderer() -> Element { let is_loading = use_signal(|| false); - let coin_result = use_signal(|| CoinStatus{status:"None".to_string(),}); + let coin_result = use_signal(|| CoinStatus{status:Coin::Head,}); let call_coin = move |_| { spawn({ to_owned![is_loading]; @@ -169,7 +185,7 @@ fn ShowServerStatus(server_status: ServerStatus) -> Element { div { div { class: "flex items-center", span { "Server Status: " } - span { { server_status.status } } + span { { server_status.status.to_string() } } } } } @@ -180,7 +196,7 @@ fn ShowCoinStatus(coin_status: CoinStatus) -> Element { div { div { class: "flex items-center", span { "Coin Status: " } - span { { coin_status.status } } + span { { coin_status.status.to_string() } } } } } From cd2c571226be112a93491a90be745bc0cfedef25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Fri, 15 Mar 2024 03:37:09 +0300 Subject: [PATCH 3/3] refactor: :recycle: status data structures --- back/src/lib.rs | 14 ++++++++++++++ back/src/routing.rs | 17 ++--------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/back/src/lib.rs b/back/src/lib.rs index 2b191cc..d9c68af 100644 --- a/back/src/lib.rs +++ b/back/src/lib.rs @@ -1,6 +1,20 @@ +use serde::{Deserialize, Serialize}; + pub mod routing; +pub mod read; #[derive(Debug, Clone)] pub struct AppState{ +} +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +enum ServerStatus{ + Alive, + Unstable, + Dead, +} +#[derive(Debug, Clone, PartialEq, Serialize,Deserialize)] +enum CoinStatus{ + Tail, + Head, } \ No newline at end of file diff --git a/back/src/routing.rs b/back/src/routing.rs index e9c966e..8caef3c 100644 --- a/back/src/routing.rs +++ b/back/src/routing.rs @@ -1,21 +1,8 @@ -use crate::AppState; +use crate::{AppState, ServerStatus, CoinStatus}; use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Json, Router}; -use serde::{Deserialize, Serialize}; use tower_http::cors::CorsLayer; use rand::prelude::*; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -enum ServerStatus{ - Alive, - Unstable, - Dead, -} -#[derive(Debug, Clone, PartialEq, Serialize,Deserialize)] -enum CoinStatus{ - Tail, - Head, -} - pub async fn routing(State(state): State) -> Router { Router::new() .route("/", get(alive)) @@ -44,4 +31,4 @@ async fn flip_coin() -> impl IntoResponse { }); println!("{}", coin_json); (StatusCode::OK, Json(coin_json)) -} \ No newline at end of file +}