From ad7d224207ee5c86eaf802f13209818799458849 Mon Sep 17 00:00:00 2001 From: Araozu Date: Wed, 13 Dec 2023 09:23:39 -0500 Subject: [PATCH] [BE] Use single connections instead of a Pool --- backend/src/controller/person/mod.rs | 3 +- backend/src/controller/scans/mod.rs | 2 +- backend/src/main.rs | 54 +++++-------------- backend/src/model/course.rs | 8 +-- backend/src/model/custom_label.rs | 12 ++--- backend/src/model/person.rs | 12 ++--- backend/src/model/register.rs | 23 ++++---- .../OnlineClassroom/ClassroomUserCreation.tsx | 2 +- rs-front/.gitignore | 1 + 9 files changed, 46 insertions(+), 71 deletions(-) diff --git a/backend/src/controller/person/mod.rs b/backend/src/controller/person/mod.rs index 12718cb..ac99967 100644 --- a/backend/src/controller/person/mod.rs +++ b/backend/src/controller/person/mod.rs @@ -2,6 +2,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}; @@ -11,7 +12,7 @@ use crate::{db, model::person::Person}; #[get("/person/")] pub async fn get_by_dni(dni: i32) -> (Status, Json>) { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => { return (Status::InternalServerError, JsonResult::err(reason)); diff --git a/backend/src/controller/scans/mod.rs b/backend/src/controller/scans/mod.rs index 58f7d09..9f3eaf0 100644 --- a/backend/src/controller/scans/mod.rs +++ b/backend/src/controller/scans/mod.rs @@ -12,7 +12,7 @@ use std::{ // TODO: Move to ENV const SCAN_PATH: &str = "/srv/srv/shares/eegsac/ESCANEOS/"; -/// Represents the result of parsing a QR code, and look for an eegsac URL. +/// Represents the result of parsing a QR code, and looking for an eegsac URL. /// /// When the frontend requests the list of files available for conversion, this /// is sent. It contains essentially a unix timestamp diff --git a/backend/src/main.rs b/backend/src/main.rs index 9e88b64..cdffdf0 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,8 +1,9 @@ use cors::Cors; use once_cell::sync::OnceCell; use sqlx::mysql::MySqlPoolOptions; -use sqlx::{MySql, Pool}; +use sqlx::{MySql, Pool, MySqlConnection}; use std::env; +use sqlx::Connection; #[macro_use] extern crate rocket; @@ -14,32 +15,12 @@ mod online_classroom; pub mod json_result; -static DB: OnceCell> = OnceCell::new(); - -/// Returns a global reference to the database pool +/// Opens & returns a connection to the database /// -/// If the database pool has not been initialized, this function will attempt to initialize it -/// up to 3 times -/// -/// If the database pool fails to initialize, this function will panic. -pub async fn db() -> Result<&'static Pool, 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> { +/// 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 { /* Init DB and set it as a global variable */ @@ -48,21 +29,12 @@ pub async fn init_db() -> Result<(), String> { Err(_) => return Err("env DATABASE_URL not found".to_string()), }; - let pool = MySqlPoolOptions::new() - .max_connections(5) - .connect(db_url.as_str()) - .await; + let conn = sqlx::MySqlConnection::connect(db_url.as_str()).await; - 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); + match conn { + Ok(connection) => Ok(connection), + Err(reason) => { + log::error!("Error connecting to DB: {}", reason); Err("Error connecting to DB".to_string()) } } @@ -73,7 +45,7 @@ async fn rocket() -> _ { dotenvy::dotenv().expect("Failed to load .env file"); env_logger::init(); - init_db().await; + // init_db().await; /* Init Rocket */ rocket::build().attach(Cors {}).mount( diff --git a/backend/src/model/course.rs b/backend/src/model/course.rs index 6a29653..deffbfb 100644 --- a/backend/src/model/course.rs +++ b/backend/src/model/course.rs @@ -28,14 +28,14 @@ pub struct Course { impl Course { pub async fn get_all() -> Result, String> { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => { return Err(reason); } }; - 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, @@ -60,7 +60,7 @@ impl Course { } pub async fn get_course_name(course_id: i32) -> Result { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => { return Err(reason); @@ -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 1776173..a5b0f2b 100644 --- a/backend/src/model/custom_label.rs +++ b/backend/src/model/custom_label.rs @@ -9,7 +9,7 @@ pub struct CustomLabel { impl CustomLabel { pub async fn get_all() -> Result, String> { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => return Err(reason), }; @@ -20,7 +20,7 @@ impl CustomLabel { FROM custom_label "#, ) - .fetch_all(db) + .fetch_all(&mut db) .await; match result { @@ -33,7 +33,7 @@ impl CustomLabel { } pub async fn get_id_by_value(value: &String) -> Result { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => return Err(reason), }; @@ -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 { @@ -63,7 +63,7 @@ impl CustomLabel { } pub async fn create(value: &String) -> Result { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => return Err(reason), }; @@ -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 1ae0bed..11ed287 100644 --- a/backend/src/model/person.rs +++ b/backend/src/model/person.rs @@ -34,13 +34,13 @@ 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 result = sqlx::query_as!(Person, "SELECT * FROM person WHERE person_dni = ?", dni) - .fetch_one(db) + .fetch_one(&mut db) .await; match result { @@ -63,7 +63,7 @@ pub struct PersonCreate { impl PersonCreate { pub async fn create(&self) -> Result<(), String> { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(err) => return Err(err), }; @@ -75,7 +75,7 @@ impl PersonCreate { self.person_paternal_surname, self.person_maternal_surname, ) - .execute(db) + .execute(&mut db) .await; match result { @@ -98,7 +98,7 @@ pub struct PersonLink { impl PersonLink { /// Links a person to a user in the online classroom pub async fn insert(&self) -> Result<(), String> { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => return Err(reason), }; @@ -109,7 +109,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 4ae22b0..10b88d6 100644 --- a/backend/src/model/register.rs +++ b/backend/src/model/register.rs @@ -32,7 +32,7 @@ pub struct RegisterCreate { impl RegisterCreate { /// Registers a new certificate pub async fn create(&self) -> Result<(), String> { - let db = match db().await { + let mut db = match db().await { Ok(db) => db, Err(reason) => return Err(reason), }; @@ -78,7 +78,7 @@ impl RegisterCreate { self.person_id, self.course_id ) - .execute(db) + .execute(&mut db) .await; match result { @@ -91,7 +91,7 @@ impl RegisterCreate { } async fn get_next_register_code(course_id: i32) -> Result { - let db = db().await?; + let mut db = db().await?; let course_name = Course::get_course_name(course_id).await?; @@ -102,7 +102,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 { @@ -121,7 +121,7 @@ impl RegisterCreate { WHERE register_course_id=?", course_id ) - .fetch_one(db) + .fetch_one(&mut db) .await; match res { @@ -165,14 +165,14 @@ pub struct Register { impl Register { pub async fn get_by_dni(dni: String) -> Result, String> { - let db = db().await?; + let mut db = db().await?; let res = sqlx::query!( "SELECT * FROM register WHERE register_person_id = (SELECT person_id FROM person WHERE person_dni = ?)", dni ) - .fetch_all(db) + .fetch_all(&mut db) .await; let res = match res { @@ -201,10 +201,10 @@ impl Register { } pub async fn delete(register_id: i32) -> Result<(), String> { - let db = db().await?; + 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 { @@ -220,8 +220,8 @@ impl Register { register_id_list: String, person_dni_list: String, ) -> Result, String> { - let db = db().await?; - + let mut db = db().await?; + let sql = format!( " select @@ -253,6 +253,7 @@ impl Register { let result = match db.fetch_all(sql.as_str()).await { Ok(res) => res, Err(err) => { + drop(sqlx::Error::PoolTimedOut); log::error!("Error fetching course & person: {:?}", err); return Err("Error fetching course & person".into()); } diff --git a/frontend/src/OnlineClassroom/ClassroomUserCreation.tsx b/frontend/src/OnlineClassroom/ClassroomUserCreation.tsx index 26e88a2..6ed7f96 100644 --- a/frontend/src/OnlineClassroom/ClassroomUserCreation.tsx +++ b/frontend/src/OnlineClassroom/ClassroomUserCreation.tsx @@ -17,7 +17,7 @@ export function ClassroomUserCreation(props: { person: Person, onCreate: (classroom_id: number, classroom_username: string) => void, }) { - const [email, setEmail] = createSignal("yuli.palo.apaza@gmail.com"); + const [email, setEmail] = createSignal("alumno@eegsac.com"); const [username, setUsername] = createSignal("USERNAME"); const {setError, status, setStatus} = useLoading(); const [names, setNames] = createSignal(props.person.person_names); diff --git a/rs-front/.gitignore b/rs-front/.gitignore index 2f8a107..b1a3993 100644 --- a/rs-front/.gitignore +++ b/rs-front/.gitignore @@ -2,4 +2,5 @@ dist .directory target public/tailwind.css +.vscode