From bc671ea789ca6d9b40d266ceaec944424555ec49 Mon Sep 17 00:00:00 2001 From: Araozu Date: Wed, 13 Dec 2023 15:05:17 -0500 Subject: [PATCH] [BE] Re-enable database pool for latency measuring --- backend/src/main.rs | 57 +++++++++++++++++++++++++++++-- backend/src/model/course.rs | 4 +-- backend/src/model/custom_label.rs | 6 ++-- backend/src/model/person.rs | 13 ++++--- backend/src/model/register.rs | 10 +++--- 5 files changed, 73 insertions(+), 17 deletions(-) diff --git a/backend/src/main.rs b/backend/src/main.rs index 681468e..c7e8626 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,6 +1,10 @@ use cors::Cors; +use once_cell::sync::OnceCell; use sqlx::Connection; +use sqlx::MySql; use sqlx::MySqlConnection; +use sqlx::Pool; +use sqlx::mysql::MySqlPoolOptions; use std::env; use std::time::Instant; @@ -14,15 +18,17 @@ mod online_classroom; pub mod json_result; +static DB: OnceCell> = OnceCell::new(); + /// Opens & returns a connection to the database /// /// We don't use a connection pool because it often times out, /// we don't have a lot of traffic and reiniting the pool would /// require to change a lot of code in multiple places. -pub async fn db() -> Result { +pub async fn db() -> Result<&'static Pool, String> { /* Init DB and set it as a global variable - */ + * / let db_url = match env::var("DATABASE_URL") { Ok(url) => url, Err(_) => return Err("env DATABASE_URL not found".to_string()), @@ -39,6 +45,53 @@ pub async fn db() -> Result { Err("Error connecting to DB".to_string()) } } + // */ + + let attempts = 3; + + for _ in 0..attempts { + match DB.get() { + Some(db) => return Ok(db), + None => { + log::info!("DB not initialized, initializing from db()"); + let _ = init_db().await; + } + } + } + + log::error!("Failed to initialize DB after {} attempts", attempts); + Err("Failed to initialize DB".to_string()) +} + +pub async fn init_db() -> Result<(), String> { + /* + Init DB and set it as a global variable + */ + let db_url = match env::var("DATABASE_URL") { + Ok(url) => url, + Err(_) => return Err("env DATABASE_URL not found".to_string()), + }; + + let start = Instant::now(); + let pool = MySqlPoolOptions::new() + .max_connections(5) + .connect(db_url.as_str()) + .await; + log::info!("DB Pool connection took: {:?} ms", start.elapsed().as_millis()); + + match pool { + Ok(pool) => match DB.set(pool) { + Ok(_) => Ok(()), + Err(_) => { + log::error!("Failed to set DB global variable"); + Err("Failed to set DB".to_string()) + } + }, + Err(e) => { + log::error!("Error connecting to DB: {}", e); + Err("Error connecting to DB".to_string()) + } + } } #[launch] diff --git a/backend/src/model/course.rs b/backend/src/model/course.rs index b61aeaa..0fe6d69 100644 --- a/backend/src/model/course.rs +++ b/backend/src/model/course.rs @@ -36,7 +36,7 @@ impl Course { }; let results = sqlx::query!("SELECT * FROM course") - .fetch_all(&mut db) + .fetch_all(db) .await; let results = match results { @@ -73,7 +73,7 @@ impl Course { "SELECT course_name FROM course WHERE course_id = ?", course_id ) - .fetch_one(&mut db) + .fetch_one(db) .await; match res { diff --git a/backend/src/model/custom_label.rs b/backend/src/model/custom_label.rs index a5b0f2b..2e30cf1 100644 --- a/backend/src/model/custom_label.rs +++ b/backend/src/model/custom_label.rs @@ -20,7 +20,7 @@ impl CustomLabel { FROM custom_label "#, ) - .fetch_all(&mut db) + .fetch_all(db) .await; match result { @@ -42,7 +42,7 @@ impl CustomLabel { "SELECT custom_label_id FROM custom_label WHERE custom_label_value = ?", value ) - .fetch_all(&mut db) + .fetch_all(db) .await; let result = match result { @@ -72,7 +72,7 @@ impl CustomLabel { "INSERT INTO custom_label (custom_label_value) VALUES (?)", value ) - .execute(&mut db) + .execute(db) .await; if let Err(err) = result { diff --git a/backend/src/model/person.rs b/backend/src/model/person.rs index 40cbb5d..b36c677 100644 --- a/backend/src/model/person.rs +++ b/backend/src/model/person.rs @@ -36,16 +36,19 @@ pub struct Person { impl Person { pub async fn get_by_dni(dni: i32) -> Result { - let mut db = match db().await { + let db = match db().await { Ok(db) => db, Err(reason) => return Err(DBError::Str(reason)), }; let start = Instant::now(); let result = sqlx::query_as!(Person, "SELECT * FROM person WHERE person_dni = ?", dni) - .fetch_one(&mut db) + .fetch_one(db) .await; - log::info!("DB query (person by dni) took: {:?} ms", start.elapsed().as_millis()); + log::info!( + "DB query (person by dni) took: {:?} ms", + start.elapsed().as_millis() + ); match result { Ok(v) => Ok(v), @@ -79,7 +82,7 @@ impl PersonCreate { self.person_paternal_surname, self.person_maternal_surname, ) - .execute(&mut db) + .execute(db) .await; match result { @@ -113,7 +116,7 @@ impl PersonLink { self.person_classroom_username, self.person_id, ) - .execute(&mut db) + .execute(db) .await; match res { diff --git a/backend/src/model/register.rs b/backend/src/model/register.rs index ada47e3..0add405 100644 --- a/backend/src/model/register.rs +++ b/backend/src/model/register.rs @@ -83,7 +83,7 @@ impl RegisterCreate { self.person_id, self.course_id ) - .execute(&mut db) + .execute(db) .await; match result { @@ -107,7 +107,7 @@ impl RegisterCreate { WHERE register_course_id IN (SELECT course_id FROM course WHERE course_name LIKE 'Matpel%')", ) - .fetch_one(&mut db) + .fetch_one(db) .await; match res { @@ -126,7 +126,7 @@ impl RegisterCreate { WHERE register_course_id=?", course_id ) - .fetch_one(&mut db) + .fetch_one(db) .await; match res { @@ -345,7 +345,7 @@ impl Register { WHERE register_person_id = (SELECT person_id FROM person WHERE person_dni = ?)", dni ) - .fetch_all(&mut db) + .fetch_all(db) .await; log::info!( "DB (get register by id) took: {:?} ms", @@ -381,7 +381,7 @@ impl Register { let mut db = db().await?; let res = sqlx::query!("DELETE FROM register WHERE register_id = ?", register_id) - .execute(&mut db) + .execute(db) .await; match res {