From 8ea7650de58b763edbb374c94ee55f238be90e52 Mon Sep 17 00:00:00 2001 From: Adam <24621027+adoyle0@users.noreply.github.com> Date: Fri, 2 Aug 2024 21:01:52 -0400 Subject: [PATCH] use RwLock instead of Mutex for Users --- lib/src/game_master.rs | 8 ++++---- lib/src/models.rs | 8 ++++---- server/src/api.rs | 14 +++++++------- server/src/api/message_handler.rs | 12 ++++++------ server/src/main.rs | 10 +++++----- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/src/game_master.rs b/lib/src/game_master.rs index b23b00d..bd14a44 100644 --- a/lib/src/game_master.rs +++ b/lib/src/game_master.rs @@ -1,7 +1,7 @@ use anyhow::Result; use rand::prelude::IteratorRandom; use rand::thread_rng; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use crate::models::*; @@ -28,7 +28,7 @@ impl Game { tracing::debug!( "Creating game {} with {} as host", &request.name, - request.host.lock().unwrap().name + request.host.read().unwrap().name ); game.name = request.name; game.host = request.host.clone(); @@ -91,14 +91,14 @@ impl Game { } /// Create a new player and add them to the game. - pub fn create_player(&mut self, user: Arc>) -> Result<()> { + pub fn create_player(&mut self, user: Arc>) -> Result<()> { let mut new_player = Player { user: user.clone(), white: vec![], black: vec![], }; - let new_player_name = user.lock().unwrap().name.clone(); + let new_player_name = user.read().unwrap().name.clone(); tracing::debug!("Creating player for {}", &new_player_name); let mut hand_buf = vec![]; diff --git a/lib/src/models.rs b/lib/src/models.rs index ad868e4..b74d014 100644 --- a/lib/src/models.rs +++ b/lib/src/models.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; /// Games update #[derive(Serialize, Deserialize, Debug)] @@ -64,7 +64,7 @@ pub struct NewGameManifest { /// Game name pub name: String, /// Game host - pub host: Arc>, + pub host: Arc>, } /// Game join request structure @@ -127,7 +127,7 @@ pub enum PlayerRole { #[derive(Debug)] pub struct Player { /// Player's username - pub user: Arc>, + pub user: Arc>, /// The player's hand pub white: Vec, /// The player's wins @@ -140,7 +140,7 @@ pub struct Game { /// The name of the game pub name: String, /// The host user of the game - pub host: Arc>, + pub host: Arc>, /// White draw pile pub white: Vec, /// Black draw pile diff --git a/server/src/api.rs b/server/src/api.rs index 623e197..01ed971 100644 --- a/server/src/api.rs +++ b/server/src/api.rs @@ -12,7 +12,7 @@ use futures::{SinkExt, StreamExt}; use lib::models::*; use rand::seq::SliceRandom; use serde_json::to_string; -use std::sync::Mutex; +use std::sync::RwLock; use std::{net::SocketAddr, sync::Arc}; pub mod message_handler; use crate::message_handler::*; @@ -73,7 +73,7 @@ async fn handle_new_user( addr: &SocketAddr, ) -> Result<()> { // Create - let new_user = Arc::new(Mutex::new(generate_new_user(state))); + let new_user = Arc::new(RwLock::new(generate_new_user(state))); // Notify client of new username sender @@ -113,9 +113,9 @@ fn generate_new_user(state: &Arc) -> User { } /// Generate message to notify client of user changes -fn client_self_user_update(new_user: &Arc>) -> String { +fn client_self_user_update(new_user: &Arc>) -> String { to_string::(&UserUpdate { - username: new_user.lock().unwrap().name.clone(), + username: new_user.read().unwrap().name.clone(), }) .unwrap() } @@ -126,7 +126,7 @@ fn chat_meta_update(state: &Arc) -> String { let mut names = vec![]; for user in state.online_users.lock().unwrap().iter() { - names.push(user.1.lock().unwrap().name.clone()); + names.push(user.1.read().unwrap().name.clone()); } to_string::(&ChatUpdate { @@ -164,7 +164,7 @@ fn games_update(state: &Arc) -> String { names.push(format!( "Name: {} Host: {}", game.name, - game.host.lock().unwrap().name + game.host.read().unwrap().name )); } @@ -181,7 +181,7 @@ fn announce_join(state: &Arc, addr: &SocketAddr) -> String { .unwrap() .get(addr) .unwrap() - .lock() + .read() .unwrap() .name ); diff --git a/server/src/api/message_handler.rs b/server/src/api/message_handler.rs index f5c9ebe..b7566f0 100644 --- a/server/src/api/message_handler.rs +++ b/server/src/api/message_handler.rs @@ -82,7 +82,7 @@ fn handle_chat_message( tx: &Sender, addr: SocketAddr, ) -> Result<()> { - let msg = format! {"{0}: {1}", state.online_users.lock().unwrap().get(&addr).unwrap().lock().unwrap().name, chat_message.text}; + let msg = format! {"{0}: {1}", state.online_users.lock().unwrap().get(&addr).unwrap().read().unwrap().name, chat_message.text}; tracing::debug!("{msg}"); tx.send(to_string::(&ChatMessage { text: msg })?)?; @@ -102,7 +102,7 @@ fn handle_user_log_in( .unwrap() .get(&addr) .unwrap() - .lock() + .read() .unwrap() .name .clone(); @@ -138,7 +138,7 @@ fn handle_user_log_in( .unwrap() .get_mut(&addr) .unwrap() - .lock() + .write() .unwrap() .change_name(user_log_in.username); @@ -178,7 +178,7 @@ fn handle_close( .unwrap() .get(&addr) .unwrap() - .lock() + .read() .unwrap() .name, cf.code, @@ -197,7 +197,7 @@ fn handle_close( .unwrap() .get(&addr) .unwrap() - .lock() + .read() .unwrap() .name ), @@ -211,7 +211,7 @@ fn handle_close( .unwrap() .get(&addr) .unwrap() - .lock() + .read() .unwrap() .name .clone(); diff --git a/server/src/main.rs b/server/src/main.rs index 0ffa8d8..0c5b989 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -8,7 +8,7 @@ use std::{ fs::{read_to_string, File}, io::{BufRead, BufReader}, net::SocketAddr, - sync::{Arc, Mutex}, + sync::{Arc, Mutex, RwLock}, }; use tokio::sync::broadcast; use tower_http::services::ServeDir; @@ -43,8 +43,8 @@ fn load_names(path: &str) -> Result> { // Our shared state pub struct AppState { // We require unique usernames. This tracks which usernames have been taken. - online_users: Mutex>>>, - offline_users: Mutex>>>, + online_users: Mutex>>>, + offline_users: Mutex>>>, // Channel used to send messages to all connected clients. tx: broadcast::Sender, // Master card decks @@ -70,8 +70,8 @@ async fn main() -> Result<()> { // Set up application state for use with with_state(). // Main Broadcast Channel let (tx, _rx) = broadcast::channel(100); - let online_users = Mutex::new(HashMap::>>::new()); - let offline_users = Mutex::new(HashMap::>>::new()); + let online_users = Mutex::new(HashMap::>>::new()); + let offline_users = Mutex::new(HashMap::>>::new()); let all_cards = load_cards_from_json("data/cah-cards-full.json")?; let games = Mutex::new(vec![]); let first_names = load_names("data/first.txt")?;