backend: Use enum to handle multiple db requests

This commit is contained in:
Stephen Seo 2022-03-28 16:31:53 +09:00
parent ca2b74eb03
commit fcd20af9bd
4 changed files with 60 additions and 46 deletions

2
back_end/.gitignore vendored
View file

@ -1 +1,3 @@
/target /target
fourLineDropper.db
.dump

View file

@ -4,6 +4,11 @@ use std::thread;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use rusqlite::Connection; use rusqlite::Connection;
#[derive(Clone, Debug)]
pub enum DBHandlerRequest {
GetID(SyncSender<u32>),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum DBFirstRun { enum DBFirstRun {
FirstRun, FirstRun,
@ -58,7 +63,7 @@ fn init_conn(sqlite_path: &str, first_run: DBFirstRun) -> Result<Connection, Str
} }
pub fn start_db_handler_thread( pub fn start_db_handler_thread(
rx: Receiver<SyncSender<u32>>, rx: Receiver<DBHandlerRequest>,
sqlite_path: String, sqlite_path: String,
shutdown_tx: SyncSender<()>, shutdown_tx: SyncSender<()>,
) { ) {
@ -74,52 +79,55 @@ pub fn start_db_handler_thread(
'outer: loop { 'outer: loop {
let rx_recv_result = rx.recv(); let rx_recv_result = rx.recv();
if let Err(e) = rx_recv_result { if let Err(e) = rx_recv_result {
println!("Failed to get player_tx: {:?}", e); println!("Failed to get DBHandlerRequest: {:?}", e);
shutdown_tx.send(()).ok(); shutdown_tx.send(()).ok();
break; break;
} }
let player_tx = rx_recv_result.unwrap(); let db_request = rx_recv_result.unwrap();
match db_request {
// got request to create new player, create new player DBHandlerRequest::GetID(player_tx) => {
let mut player_id: u32 = thread_rng().gen(); // got request to create new player, create new player
let conn_result = init_conn(&sqlite_path, DBFirstRun::NotFirstRun); let mut player_id: u32 = thread_rng().gen();
if let Err(e) = conn_result { let conn_result = init_conn(&sqlite_path, DBFirstRun::NotFirstRun);
println!("Failed to get sqlite db connection: {:?}", e); if let Err(e) = conn_result {
shutdown_tx.send(()).ok(); println!("Failed to get sqlite db connection: {:?}", e);
break; shutdown_tx.send(()).ok();
} break;
let conn = conn_result.unwrap();
loop {
let stmt_result = conn.prepare("SELECT id FROM players WHERE id = ?;");
if let Err(e) = stmt_result {
println!("Failed to create sqlite statement: {:?}", e);
shutdown_tx.send(()).ok();
break 'outer;
}
let mut stmt = stmt_result.unwrap();
match stmt.query_row([player_id], |_row| Ok(())) {
Ok(_) => {
player_id = thread_rng().gen();
} }
Err(_) => break, let conn = conn_result.unwrap();
loop {
let stmt_result = conn.prepare("SELECT id FROM players WHERE id = ?;");
if let Err(e) = stmt_result {
println!("Failed to create sqlite statement: {:?}", e);
shutdown_tx.send(()).ok();
break 'outer;
}
let mut stmt = stmt_result.unwrap();
match stmt.query_row([player_id], |_row| Ok(())) {
Ok(_) => {
player_id = thread_rng().gen();
}
Err(_) => break,
}
}
let insert_result = conn.execute(
"INSERT INTO players (id, date_added) VALUES (?, datetime());",
[player_id],
);
if let Err(e) = insert_result {
println!("Failed to insert into sqlite db: {:?}", e);
shutdown_tx.send(()).ok();
break 'outer;
}
let send_result = player_tx.send(player_id);
if let Err(e) = send_result {
println!("Failed to send back player id: {:?}", e);
shutdown_tx.send(()).ok();
break 'outer;
}
send_result.unwrap();
} }
} }
let insert_result = conn.execute(
"INSERT INTO players (id, date_added) VALUES (?, datetime());",
[player_id],
);
if let Err(e) = insert_result {
println!("Failed to insert into sqlite db: {:?}", e);
shutdown_tx.send(()).ok();
break 'outer;
}
let send_result = player_tx.send(player_id);
if let Err(e) = send_result {
println!("Failed to send back player id: {:?}", e);
shutdown_tx.send(()).ok();
break 'outer;
}
send_result.unwrap();
// Pair up players // Pair up players
// TODO // TODO

View file

@ -1,3 +1,5 @@
use crate::db_handler::DBHandlerRequest;
use std::{ use std::{
sync::mpsc::{sync_channel, SyncSender}, sync::mpsc::{sync_channel, SyncSender},
time::Duration, time::Duration,
@ -7,7 +9,7 @@ use serde_json::Value;
pub fn handle_json( pub fn handle_json(
root: Value, root: Value,
tx: SyncSender<SyncSender<u32>>, tx: SyncSender<DBHandlerRequest>,
_shutdown_tx: SyncSender<()>, // maybe used here, not sure if it will be _shutdown_tx: SyncSender<()>, // maybe used here, not sure if it will be
) -> Result<String, String> { ) -> Result<String, String> {
if let Some(Value::String(type_str)) = root.get("type") { if let Some(Value::String(type_str)) = root.get("type") {
@ -24,9 +26,9 @@ pub fn handle_json(
} }
} }
fn handle_pairing_request(tx: SyncSender<SyncSender<u32>>) -> Result<String, String> { fn handle_pairing_request(tx: SyncSender<DBHandlerRequest>) -> Result<String, String> {
let (player_tx, player_rx) = sync_channel::<u32>(1); let (player_tx, player_rx) = sync_channel::<u32>(1);
if tx.send(player_tx).is_err() { if tx.send(DBHandlerRequest::GetID(player_tx)).is_err() {
return Err("{\"type\":\"pairing_response\", \"status\":\"internal_error\"}".into()); return Err("{\"type\":\"pairing_response\", \"status\":\"internal_error\"}".into());
} }
if let Ok(pid) = player_rx.recv_timeout(Duration::from_secs(5)) { if let Ok(pid) = player_rx.recv_timeout(Duration::from_secs(5)) {

View file

@ -3,7 +3,9 @@ mod json_handlers;
const SQLITE_DB_PATH: &str = "./fourLineDropper.db"; const SQLITE_DB_PATH: &str = "./fourLineDropper.db";
use std::sync::mpsc::{sync_channel, SyncSender}; use db_handler::DBHandlerRequest;
use std::sync::mpsc::sync_channel;
use db_handler::start_db_handler_thread; use db_handler::start_db_handler_thread;
use tokio::sync::oneshot; use tokio::sync::oneshot;
@ -11,7 +13,7 @@ use warp::{Filter, Rejection};
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let (db_tx, db_rx) = sync_channel::<SyncSender<u32>>(32); let (db_tx, db_rx) = sync_channel::<DBHandlerRequest>(32);
let db_tx_clone = db_tx.clone(); let db_tx_clone = db_tx.clone();
let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>(); let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();