diff --git a/Cargo.lock b/Cargo.lock index cf28e61..d0a1404 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,7 +28,6 @@ dependencies = [ "actix-codec", "actix-rt", "actix-service", - "actix-tls", "actix-utils", "ahash", "base64", @@ -122,25 +121,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "actix-tls" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac453898d866cdbecdbc2334fe1738c747b4eba14a677261f2b768ba05329389" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "impl-more", - "openssl", - "pin-project-lite", - "tokio", - "tokio-openssl", - "tokio-util", - "tracing", -] - [[package]] name = "actix-utils" version = "3.0.1" @@ -164,7 +144,6 @@ dependencies = [ "actix-rt", "actix-server", "actix-service", - "actix-tls", "actix-utils", "actix-web-codegen", "ahash", @@ -2323,17 +2302,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-openssl" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59df6849caa43bb7567f9a36f863c447d95a11d5903c9cc334ba32576a27eadd" -dependencies = [ - "openssl", - "openssl-sys", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.0" diff --git a/src/main.rs b/src/main.rs index ec10c24..64c081b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -190,6 +190,7 @@ macro_rules! lock_onto_mutex { break value; } Err(_) => { + $mutex.clear_poison(); actix_web::rt::time::sleep(std::time::Duration::from_millis(15)).await; } } diff --git a/src/router/clear_rate.rs b/src/router/clear_rate.rs index 292638e..c6194d9 100644 --- a/src/router/clear_rate.rs +++ b/src/router/clear_rate.rs @@ -167,11 +167,13 @@ fn get_json() -> JsonValue { } async fn get_clearrate_json() -> JsonValue { - let mut result = crate::lock_onto_mutex!(CACHED_DATA); - if result.is_none() { - result.replace(get_json()); - } - let cache = result.as_ref().unwrap(); + let cache = { + let mut result = crate::lock_onto_mutex!(CACHED_DATA); + if result.is_none() { + result.replace(get_json()); + } + result.as_ref().unwrap().clone() + }; let rv = cache["cache"].clone(); if cache["last_updated"].as_u64().unwrap() + (60 * 60) < global::timestamp() { let mut result = crate::lock_onto_mutex!(CACHED_DATA); diff --git a/src/sql.rs b/src/sql.rs index 40363d3..569c4c2 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -5,23 +5,8 @@ use json::{JsonValue, array}; use crate::router::clear_rate::Live; pub struct SQLite { - engine: Mutex -} - -// This is duplicated, for ease of people wanting to use this file in their project -macro_rules! lock_onto_mutex { - ($mutex:expr) => {{ - loop { - match $mutex.lock() { - Ok(value) => { - break value; - } - Err(_) => { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - } - } - }}; + engine: Mutex, + sleep_duration: u64 } impl SQLite { @@ -29,60 +14,98 @@ impl SQLite { let conn = Connection::open(crate::get_data_path(path)).unwrap(); conn.execute("PRAGMA foreign_keys = ON;", ()).unwrap(); let instance = SQLite { - engine: Mutex::new(conn) + engine: Mutex::new(conn), + sleep_duration: 10 }; setup(&instance); instance } pub fn lock_and_exec(&self, command: &str, args: &[&dyn ToSql]) { - let conn = lock_onto_mutex!(self.engine); - conn.execute(command, args).unwrap(); + loop { + match self.engine.lock() { + Ok(conn) => { + conn.execute(command, args).unwrap(); + return; + } + Err(_) => { + self.engine.clear_poison(); + std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); + } + } + } } pub fn lock_and_select(&self, command: &str, args: &[&dyn ToSql]) -> Result { - let conn = lock_onto_mutex!(self.engine); - let mut stmt = conn.prepare(command)?; - return stmt.query_row(args, |row| { - match row.get::(0) { - Ok(val) => Ok(val.to_string()), - Err(_) => row.get(0) + loop { + match self.engine.lock() { + Ok(conn) => { + let mut stmt = conn.prepare(command)?; + return stmt.query_row(args, |row| { + match row.get::(0) { + Ok(val) => Ok(val.to_string()), + Err(_) => row.get(0) + } + }); + } + Err(_) => { + self.engine.clear_poison(); + std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); + } } - }); + } } pub fn lock_and_select_all(&self, command: &str, args: &[&dyn ToSql]) -> Result { - let conn = lock_onto_mutex!(self.engine); - let mut stmt = conn.prepare(command)?; - let map = stmt.query_map(args, |row| { - match row.get::(0) { - Ok(val) => Ok(val.to_string()), - Err(_) => row.get(0) + loop { + match self.engine.lock() { + Ok(conn) => { + let mut stmt = conn.prepare(command)?; + let map = stmt.query_map(args, |row| { + match row.get::(0) { + Ok(val) => Ok(val.to_string()), + Err(_) => row.get(0) + } + })?; + let mut rv = array![]; + for val in map { + let res = val?; + match res.clone().parse::() { + Ok(v) => rv.push(v).unwrap(), + Err(_) => rv.push(res).unwrap() + }; + } + return Ok(rv); + } + Err(_) => { + self.engine.clear_poison(); + std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); + } } - })?; - let mut rv = array![]; - for val in map { - let res = val?; - match res.clone().parse::() { - Ok(v) => rv.push(v).unwrap(), - Err(_) => rv.push(res).unwrap() - }; } - return Ok(rv); } pub fn get_live_data(&self, id: i64) -> Result { - let conn = lock_onto_mutex!(self.engine); - let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?; - return stmt.query_row(params!(id), |row| { - Ok(Live { - live_id: row.get(0)?, - normal_failed: row.get(1)?, - normal_pass: row.get(2)?, - hard_failed: row.get(3)?, - hard_pass: row.get(4)?, - expert_failed: row.get(5)?, - expert_pass: row.get(6)?, - master_failed: row.get(7)?, - master_pass: row.get(8)?, - }) - }); + loop { + match self.engine.lock() { + Ok(conn) => { + let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?; + return stmt.query_row(params!(id), |row| { + Ok(Live { + live_id: row.get(0)?, + normal_failed: row.get(1)?, + normal_pass: row.get(2)?, + hard_failed: row.get(3)?, + hard_pass: row.get(4)?, + expert_failed: row.get(5)?, + expert_pass: row.get(6)?, + master_failed: row.get(7)?, + master_pass: row.get(8)?, + }) + }); + } + Err(_) => { + self.engine.clear_poison(); + std::thread::sleep(std::time::Duration::from_millis(self.sleep_duration)); + } + } + } } pub fn create_store_v2(&self, table: &str) { self.lock_and_exec(table, params!());