Compare commits

...

2 commits

Author SHA1 Message Date
Adam
8ea7650de5 use RwLock instead of Mutex for Users 2024-08-02 21:01:52 -04:00
Adam
37fbb8dfba update deps 2024-08-02 21:01:02 -04:00
6 changed files with 43 additions and 34 deletions

25
Cargo.lock generated
View file

@ -1224,7 +1224,7 @@ dependencies = [
"hermit-abi", "hermit-abi",
"libc", "libc",
"wasi", "wasi",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -1517,9 +1517,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.5" version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -1880,7 +1880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -2015,7 +2015,7 @@ dependencies = [
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -2482,11 +2482,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -2504,6 +2504,15 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.6" version = "0.52.6"

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use rand::prelude::IteratorRandom; use rand::prelude::IteratorRandom;
use rand::thread_rng; use rand::thread_rng;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, RwLock};
use crate::models::*; use crate::models::*;
@ -28,7 +28,7 @@ impl Game {
tracing::debug!( tracing::debug!(
"Creating game {} with {} as host", "Creating game {} with {} as host",
&request.name, &request.name,
request.host.lock().unwrap().name request.host.read().unwrap().name
); );
game.name = request.name; game.name = request.name;
game.host = request.host.clone(); game.host = request.host.clone();
@ -91,14 +91,14 @@ impl Game {
} }
/// Create a new player and add them to the game. /// Create a new player and add them to the game.
pub fn create_player(&mut self, user: Arc<Mutex<User>>) -> Result<()> { pub fn create_player(&mut self, user: Arc<RwLock<User>>) -> Result<()> {
let mut new_player = Player { let mut new_player = Player {
user: user.clone(), user: user.clone(),
white: vec![], white: vec![],
black: 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); tracing::debug!("Creating player for {}", &new_player_name);
let mut hand_buf = vec![]; let mut hand_buf = vec![];

View file

@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, RwLock};
/// Games update /// Games update
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -64,7 +64,7 @@ pub struct NewGameManifest {
/// Game name /// Game name
pub name: String, pub name: String,
/// Game host /// Game host
pub host: Arc<Mutex<User>>, pub host: Arc<RwLock<User>>,
} }
/// Game join request structure /// Game join request structure
@ -127,7 +127,7 @@ pub enum PlayerRole {
#[derive(Debug)] #[derive(Debug)]
pub struct Player { pub struct Player {
/// Player's username /// Player's username
pub user: Arc<Mutex<User>>, pub user: Arc<RwLock<User>>,
/// The player's hand /// The player's hand
pub white: Vec<CardWhite>, pub white: Vec<CardWhite>,
/// The player's wins /// The player's wins
@ -140,7 +140,7 @@ pub struct Game {
/// The name of the game /// The name of the game
pub name: String, pub name: String,
/// The host user of the game /// The host user of the game
pub host: Arc<Mutex<User>>, pub host: Arc<RwLock<User>>,
/// White draw pile /// White draw pile
pub white: Vec<CardWhite>, pub white: Vec<CardWhite>,
/// Black draw pile /// Black draw pile

View file

@ -12,7 +12,7 @@ use futures::{SinkExt, StreamExt};
use lib::models::*; use lib::models::*;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use serde_json::to_string; use serde_json::to_string;
use std::sync::Mutex; use std::sync::RwLock;
use std::{net::SocketAddr, sync::Arc}; use std::{net::SocketAddr, sync::Arc};
pub mod message_handler; pub mod message_handler;
use crate::message_handler::*; use crate::message_handler::*;
@ -73,7 +73,7 @@ async fn handle_new_user(
addr: &SocketAddr, addr: &SocketAddr,
) -> Result<()> { ) -> Result<()> {
// Create // 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 // Notify client of new username
sender sender
@ -113,9 +113,9 @@ fn generate_new_user(state: &Arc<AppState>) -> User {
} }
/// Generate message to notify client of user changes /// Generate message to notify client of user changes
fn client_self_user_update(new_user: &Arc<Mutex<User>>) -> String { fn client_self_user_update(new_user: &Arc<RwLock<User>>) -> String {
to_string::<UserUpdate>(&UserUpdate { to_string::<UserUpdate>(&UserUpdate {
username: new_user.lock().unwrap().name.clone(), username: new_user.read().unwrap().name.clone(),
}) })
.unwrap() .unwrap()
} }
@ -126,7 +126,7 @@ fn chat_meta_update(state: &Arc<AppState>) -> String {
let mut names = vec![]; let mut names = vec![];
for user in state.online_users.lock().unwrap().iter() { 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>(&ChatUpdate { to_string::<ChatUpdate>(&ChatUpdate {
@ -164,7 +164,7 @@ fn games_update(state: &Arc<AppState>) -> String {
names.push(format!( names.push(format!(
"Name: {} Host: {}", "Name: {} Host: {}",
game.name, game.name,
game.host.lock().unwrap().name game.host.read().unwrap().name
)); ));
} }
@ -181,7 +181,7 @@ fn announce_join(state: &Arc<AppState>, addr: &SocketAddr) -> String {
.unwrap() .unwrap()
.get(addr) .get(addr)
.unwrap() .unwrap()
.lock() .read()
.unwrap() .unwrap()
.name .name
); );

View file

@ -82,7 +82,7 @@ fn handle_chat_message(
tx: &Sender<String>, tx: &Sender<String>,
addr: SocketAddr, addr: SocketAddr,
) -> Result<()> { ) -> 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}"); tracing::debug!("{msg}");
tx.send(to_string::<ChatMessage>(&ChatMessage { text: msg })?)?; tx.send(to_string::<ChatMessage>(&ChatMessage { text: msg })?)?;
@ -102,7 +102,7 @@ fn handle_user_log_in(
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
.lock() .read()
.unwrap() .unwrap()
.name .name
.clone(); .clone();
@ -138,7 +138,7 @@ fn handle_user_log_in(
.unwrap() .unwrap()
.get_mut(&addr) .get_mut(&addr)
.unwrap() .unwrap()
.lock() .write()
.unwrap() .unwrap()
.change_name(user_log_in.username); .change_name(user_log_in.username);
@ -178,7 +178,7 @@ fn handle_close(
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
.lock() .read()
.unwrap() .unwrap()
.name, .name,
cf.code, cf.code,
@ -197,7 +197,7 @@ fn handle_close(
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
.lock() .read()
.unwrap() .unwrap()
.name .name
), ),
@ -211,7 +211,7 @@ fn handle_close(
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
.lock() .read()
.unwrap() .unwrap()
.name .name
.clone(); .clone();

View file

@ -8,7 +8,7 @@ use std::{
fs::{read_to_string, File}, fs::{read_to_string, File},
io::{BufRead, BufReader}, io::{BufRead, BufReader},
net::SocketAddr, net::SocketAddr,
sync::{Arc, Mutex}, sync::{Arc, Mutex, RwLock},
}; };
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
@ -43,8 +43,8 @@ fn load_names(path: &str) -> Result<Vec<String>> {
// Our shared state // Our shared state
pub struct AppState { pub struct AppState {
// We require unique usernames. This tracks which usernames have been taken. // We require unique usernames. This tracks which usernames have been taken.
online_users: Mutex<HashMap<SocketAddr, Arc<Mutex<User>>>>, online_users: Mutex<HashMap<SocketAddr, Arc<RwLock<User>>>>,
offline_users: Mutex<HashMap<String, Arc<Mutex<User>>>>, offline_users: Mutex<HashMap<String, Arc<RwLock<User>>>>,
// Channel used to send messages to all connected clients. // Channel used to send messages to all connected clients.
tx: broadcast::Sender<String>, tx: broadcast::Sender<String>,
// Master card decks // Master card decks
@ -70,8 +70,8 @@ async fn main() -> Result<()> {
// Set up application state for use with with_state(). // Set up application state for use with with_state().
// Main Broadcast Channel // Main Broadcast Channel
let (tx, _rx) = broadcast::channel(100); let (tx, _rx) = broadcast::channel(100);
let online_users = Mutex::new(HashMap::<SocketAddr, Arc<Mutex<User>>>::new()); let online_users = Mutex::new(HashMap::<SocketAddr, Arc<RwLock<User>>>::new());
let offline_users = Mutex::new(HashMap::<String, Arc<Mutex<User>>>::new()); let offline_users = Mutex::new(HashMap::<String, Arc<RwLock<User>>>::new());
let all_cards = load_cards_from_json("data/cah-cards-full.json")?; let all_cards = load_cards_from_json("data/cah-cards-full.json")?;
let games = Mutex::new(vec![]); let games = Mutex::new(vec![]);
let first_names = load_names("data/first.txt")?; let first_names = load_names("data/first.txt")?;