From f305cb5a85f7bad21010144e7a30a3f1a3e23cdf Mon Sep 17 00:00:00 2001 From: hex Date: Sat, 2 Aug 2025 20:39:13 +0200 Subject: [PATCH] feat: health checker --- src/health.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/health.rs diff --git a/src/health.rs b/src/health.rs new file mode 100644 index 0000000..83cfbc3 --- /dev/null +++ b/src/health.rs @@ -0,0 +1,60 @@ +use http_body_util::Empty; +use hyper::{Request, body::Bytes}; +use hyper_util::rt::TokioIo; +use log::error; +use tokio::net::TcpStream; + +use crate::db::{BoxyDatabase, Endpoint}; + +pub async fn check(db: &mut BoxyDatabase) { + let endpoints = Endpoint::get_all(db).await.unwrap(); + + for endpoint in endpoints { + let address = format!("{}:{}", endpoint.address, endpoint.port); + + let url = format!("http://{}{}", address, endpoint.callback) + .parse::() + .unwrap(); + + let stream = match TcpStream::connect(address).await { + Ok(x) => x, + Err(e) => { + error!("Could not reach endpoint {}: {e}", endpoint.id.unwrap()); + + endpoint.delete(db).await.unwrap(); + + continue; + } + }; + + let io = TokioIo::new(stream); + + let (mut sender, conn) = hyper::client::conn::http1::handshake(io).await.unwrap(); + + tokio::task::spawn(async move { + if let Err(err) = conn.await { + println!("Connection failed: {:?}", err); + } + }); + + let req = Request::builder() + .uri(url) + .body(Empty::::new()) + .unwrap(); + + let res = match sender.send_request(req).await { + Ok(x) => x, + Err(e) => { + error!("Could not reach endpoint {}: {e}", endpoint.id.unwrap()); + + endpoint.delete(db).await.unwrap(); + + continue; + } + }; + + if !res.status().is_success() { + endpoint.delete(db).await.unwrap(); + } + } +}