From 8fa36e00ec722191692f602de3529c424db87d1a Mon Sep 17 00:00:00 2001 From: fernando Date: Tue, 30 Jan 2024 16:58:24 -0500 Subject: [PATCH] [BE] Fixes #39: Spawn a connection on every request rather than having a db pool --- backend/.gitignore | 1 + backend/src/controller/classroom/mod.rs | 2 +- backend/src/controller/person/mod.rs | 1 + backend/src/main.rs | 80 +++---------------------- backend/src/model/course.rs | 4 +- backend/src/model/custom_label.rs | 6 +- backend/src/model/person.rs | 8 +-- backend/src/model/register.rs | 10 ++-- frontend/src/index.css | 38 ++++++------ 9 files changed, 44 insertions(+), 106 deletions(-) diff --git a/backend/.gitignore b/backend/.gitignore index 60690e4..9776676 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -4,3 +4,4 @@ aulavirtual scraps request-logs .idea +.directory diff --git a/backend/src/controller/classroom/mod.rs b/backend/src/controller/classroom/mod.rs index 9a8b1b9..8647da7 100644 --- a/backend/src/controller/classroom/mod.rs +++ b/backend/src/controller/classroom/mod.rs @@ -12,8 +12,8 @@ use rocket::{http::Status, serde::json::Json}; mod courses; -pub use courses::disenroll_user_options; pub use courses::disenroll_user; +pub use courses::disenroll_user_options; #[options("/classroom/user")] pub fn create_user_options() -> Status { diff --git a/backend/src/controller/person/mod.rs b/backend/src/controller/person/mod.rs index abebf2c..c53f191 100644 --- a/backend/src/controller/person/mod.rs +++ b/backend/src/controller/person/mod.rs @@ -4,6 +4,7 @@ use log::{error, info}; use reqwest::Client; use rocket::http::Status; use rocket::serde::json::Json; +use sqlx::Connection; use crate::json_result::JsonResult; use crate::model::person::{PersonCreate, PersonLink}; diff --git a/backend/src/main.rs b/backend/src/main.rs index 27e1c4f..9da8eb5 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,7 +1,8 @@ use cors::Cors; use once_cell::sync::OnceCell; -use sqlx::mysql::MySqlPoolOptions; +use sqlx::Connection; use sqlx::MySql; +use sqlx::MySqlConnection; use sqlx::Pool; use std::env; use std::time::Instant; @@ -20,13 +21,13 @@ 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<&'static Pool, String> { +/// We don't use a connection pool because on some days, on the afternoon, +/// the connections die and the user has to wait for all 5 connections +/// in the pool to die and then wait for the new connections to be created. +pub async fn db() -> Result { /* 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()), @@ -43,73 +44,6 @@ pub async fn db() -> Result<&'static Pool, String> { Err("Error connecting to DB".to_string()) } } - // */ - - let attempts = 3; - - for _ in 0..attempts { - match DB.get() { - Some(db) => { - log::info!("DB active connections: {}", db.size()); - log::info!("DB num_idle connections: {}", db.num_idle()); - - 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) - /* - On some afternoons for some god forsaken reason the idle connections - to the db stay alive, but stop responding. - When this happens, we must restart the server, or wait for all - the active connections to timeout. - Here are some measures to circumvent that: - */ - // Set the maximum wait time for connections to 10 seconds - // In practice, the slowest connections take 1.5 seconds to connect - .acquire_timeout(std::time::Duration::from_secs(10)) - // Set the maximum idle time for connections to 10 minutes - .idle_timeout(std::time::Duration::from_secs(10 * 60)) - .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 1251834..deffbfb 100644 --- a/backend/src/model/course.rs +++ b/backend/src/model/course.rs @@ -35,7 +35,7 @@ impl Course { } }; - let results = sqlx::query!("SELECT * FROM course").fetch_all(db).await; + let results = sqlx::query!("SELECT * FROM course").fetch_all(&mut db).await; let results = match results { Ok(res) => res, @@ -71,7 +71,7 @@ impl Course { "SELECT course_name FROM course WHERE course_id = ?", course_id ) - .fetch_one(db) + .fetch_one(&mut db) .await; match res { diff --git a/backend/src/model/custom_label.rs b/backend/src/model/custom_label.rs index 2e30cf1..a5b0f2b 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(db) + .fetch_all(&mut db) .await; match result { @@ -42,7 +42,7 @@ impl CustomLabel { "SELECT custom_label_id FROM custom_label WHERE custom_label_value = ?", value ) - .fetch_all(db) + .fetch_all(&mut db) .await; let result = match result { @@ -72,7 +72,7 @@ impl CustomLabel { "INSERT INTO custom_label (custom_label_value) VALUES (?)", value ) - .execute(db) + .execute(&mut db) .await; if let Err(err) = result { diff --git a/backend/src/model/person.rs b/backend/src/model/person.rs index b36c677..7c28dd3 100644 --- a/backend/src/model/person.rs +++ b/backend/src/model/person.rs @@ -36,14 +36,14 @@ pub struct Person { impl Person { pub async fn get_by_dni(dni: i32) -> Result { - let db = match db().await { + let mut 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(db) + .fetch_one(&mut db) .await; log::info!( "DB query (person by dni) took: {:?} ms", @@ -82,7 +82,7 @@ impl PersonCreate { self.person_paternal_surname, self.person_maternal_surname, ) - .execute(db) + .execute(&mut db) .await; match result { @@ -116,7 +116,7 @@ impl PersonLink { self.person_classroom_username, self.person_id, ) - .execute(db) + .execute(&mut db) .await; match res { diff --git a/backend/src/model/register.rs b/backend/src/model/register.rs index 0add405..ada47e3 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(db) + .execute(&mut 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(db) + .fetch_one(&mut db) .await; match res { @@ -126,7 +126,7 @@ impl RegisterCreate { WHERE register_course_id=?", course_id ) - .fetch_one(db) + .fetch_one(&mut 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(db) + .fetch_all(&mut 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(db) + .execute(&mut db) .await; match res { diff --git a/frontend/src/index.css b/frontend/src/index.css index a063eeb..a505389 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -3,7 +3,7 @@ --c-on-error: #690005; --c-error-container: #93000a; --c-on-error-container: #ffdad6; - + --c-outline-50: rgba(143, 144, 154, 0.5); } @@ -32,20 +32,22 @@ body { .progress { animation: progress 1s infinite linear; - } - - .left-right { - transform-origin: 0% 50%; - } - @keyframes progress { - 0% { - transform: translateX(0) scaleX(0); - } - 40% { - transform: translateX(0) scaleX(0.4); - } - 100% { - transform: translateX(100%) scaleX(0.5); - } - } - +} + +.left-right { + transform-origin: 0% 50%; +} + +@keyframes progress { + 0% { + transform: translateX(0) scaleX(0); + } + + 40% { + transform: translateX(0) scaleX(0.4); + } + + 100% { + transform: translateX(100%) scaleX(0.5); + } +} \ No newline at end of file