Hopefully Fix Server getting stuck when main thread dies
All checks were successful
Run Tests on Code / run-tests (push) Successful in 0s
Build and Release Binary File / run-tests (push) Successful in 0s
Build and Release Binary File / build (push) Successful in 1m8s
Build and Release Binary File / upload-release (push) Successful in 13s

This commit is contained in:
Neshura 2023-12-12 20:39:34 +01:00
parent b3347a6e53
commit 75eefab02c
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C

View file

@ -6,16 +6,18 @@ use dotenvy::dotenv;
use tokio::time::sleep;
use std::{env, fs, net::Ipv4Addr, net::Ipv6Addr, time::Duration, sync::{Arc, atomic::{AtomicBool, Ordering}}};
use std::process::abort;
use chrono::Local;
use actix_web::{middleware::Logger, web, App, HttpServer, Result};
use actix_web::{middleware::Logger, web, App, HttpServer};
use serde::{Deserialize, Serialize};
use sqlx::{PgPool, Pool, Postgres, Connection};
use utoipa::{OpenApi, openapi::security::{SecurityScheme, ApiKey, ApiKeyValue}, Modify};
use utoipa_swagger_ui::{Config, SwaggerUi, Url};
mod db;
mod v1;
mod v2;
mod v3;
@ -65,8 +67,8 @@ pub struct AppState {
auth_tokens: AuthenticationTokens,
}
async fn postgres_watchdog(pool: PgPool, is_alive: Arc<AtomicBool>, shutdown: Arc<AtomicBool>) {
loop {
async fn postgres_watchdog(pool: PgPool, shutdown: Arc<AtomicBool>) {
while !shutdown.load(Ordering::Relaxed) {
let start = Local::now();
let mut conn = match pool.acquire().await {
@ -94,31 +96,17 @@ async fn postgres_watchdog(pool: PgPool, is_alive: Arc<AtomicBool>, shutdown: Ar
while Local::now() - start < chrono::Duration::seconds(15) {
sleep(Duration::from_millis(100)).await;
if shutdown.load(Ordering::Relaxed) {
break;
}
}
if shutdown.load(Ordering::Relaxed) {
break;
}
}
is_alive.store(false, Ordering::Relaxed);
}
#[actix_web::main]
async fn main() -> Result<()> {
async fn main() {
env_logger::init();
dotenv().ok();
let shutdown: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
let shutdown_clone = Arc::clone(&shutdown);
ctrlc::set_handler(move || {
eprintln!("Ctrl-C received");
shutdown_clone.store(true, Ordering::Relaxed)
})
.expect("Error setting Ctrl-C handler");
let toml_str = fs::read_to_string("config.toml").expect("Failed to read config.toml");
let config: ConfigToml = toml::from_str(&toml_str).expect("Failed to parse config.toml");
@ -322,36 +310,16 @@ async fn main() -> Result<()> {
.config(swagger_config.clone()),
)
})
.bind((Ipv6Addr::UNSPECIFIED, config.port.default)).expect("Port or IP already occupied")
.run();
.bind((Ipv6Addr::UNSPECIFIED, config.port.default)).expect("Port or IP already occupied")
.run()
.await;
let server_thread = tokio::spawn(async {
println!("Awaiting server");
let _ = server.await;
println!("Stopped awaiting server");
});
watchdog_thread.abort();
println!("Started Serving API on: ");
println!(" -> http://[{}]:{}", Ipv6Addr::UNSPECIFIED, 8080);
println!(" -> http://{}:{}", Ipv4Addr::UNSPECIFIED, 8080);
sleep(Duration::from_secs(10)).await;
let is_alive_clone = Arc::clone(&is_alive);
let shutdown_clone = Arc::clone(&shutdown);
let _ = tokio::spawn(async move { postgres_watchdog(pool_copy, is_alive_clone, shutdown_clone).await });
println!("Service crashed due to unexpected Error, restarting thread after wait...");
//watchdog_thread.await;
while is_alive.load(Ordering::Relaxed) {
sleep(Duration::from_millis(200)).await;
}
if shutdown.load(Ordering::Relaxed) {
break;
}
eprintln!("Connection died, restarting Server");
server_thread.abort();
sleep(Duration::from_secs(10)).await;
}
Ok(())
}