use RwLock instead of Mutex

This commit is contained in:
Adam 2024-08-03 00:42:32 -04:00
parent cf7b5367f8
commit b4cfe7acca
3 changed files with 28 additions and 28 deletions

View file

@ -83,7 +83,7 @@ async fn handle_new_user(
.await?; .await?;
// Register using `addr` as key until something longer lived exists // Register using `addr` as key until something longer lived exists
state.online_users.lock().unwrap().insert(*addr, new_user); state.online_users.write().unwrap().insert(*addr, new_user);
// Hydrate client // Hydrate client
// this should probably be combined and sent as one // this should probably be combined and sent as one
@ -127,7 +127,7 @@ fn chat_meta_update(state: &Arc<AppState>) -> String {
// this may get expensive if there are many users // this may get expensive if there are many users
let mut names = vec![]; let mut names = vec![];
for user in state.online_users.lock().unwrap().iter() { for user in state.online_users.read().unwrap().iter() {
names.push(user.1.read().unwrap().name.clone()); names.push(user.1.read().unwrap().name.clone());
} }
@ -148,8 +148,8 @@ fn motd() -> String {
/// Generate server summary update - mostly debug stuff /// Generate server summary update - mostly debug stuff
fn server_summary_update(state: &Arc<AppState>) -> String { fn server_summary_update(state: &Arc<AppState>) -> String {
let online_users = state.online_users.lock().unwrap().len(); let online_users = state.online_users.read().unwrap().len();
let active_games = state.games.lock().unwrap().len(); let active_games = state.games.read().unwrap().len();
to_string::<ServerStateSummary>(&ServerStateSummary { to_string::<ServerStateSummary>(&ServerStateSummary {
online_users, online_users,
active_games, active_games,
@ -162,7 +162,7 @@ fn games_update(state: &Arc<AppState>) -> String {
// this may get expensive if there are many games // this may get expensive if there are many games
let mut names = vec![]; let mut names = vec![];
for game in state.games.lock().unwrap().iter() { for game in state.games.read().unwrap().iter() {
names.push(format!( names.push(format!(
"Name: {} Host: {}", "Name: {} Host: {}",
game.name, game.name,
@ -179,7 +179,7 @@ fn announce_join(state: &Arc<AppState>, addr: &SocketAddr) -> String {
"{} joined.", "{} joined.",
state state
.online_users .online_users
.lock() .read()
.unwrap() .unwrap()
.get(addr) .get(addr)
.unwrap() .unwrap()

View file

@ -58,7 +58,7 @@ fn handle_new_game(
name: new_game.name, name: new_game.name,
host: state host: state
.online_users .online_users
.lock() .read()
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
@ -67,7 +67,7 @@ fn handle_new_game(
// create game // create game
if let Ok(new_game_object) = Game::new(manifest) { if let Ok(new_game_object) = Game::new(manifest) {
state.games.lock().unwrap().push(new_game_object); state.games.write().unwrap().push(new_game_object);
tx.send(games_update(state))?; tx.send(games_update(state))?;
tx.send(server_summary_update(state))?; tx.send(server_summary_update(state))?;
} }
@ -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().read().unwrap().name, chat_message.text}; let msg = format! {"{0}: {1}", state.online_users.read().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 })?)?;
@ -98,7 +98,7 @@ fn handle_user_log_in(
) -> Result<()> { ) -> Result<()> {
let old_name = state let old_name = state
.online_users .online_users
.lock() .read()
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
@ -108,16 +108,16 @@ fn handle_user_log_in(
.clone(); .clone();
let new_name = user_log_in.username.clone(); let new_name = user_log_in.username.clone();
if state.offline_users.lock().unwrap().contains_key(&new_name) { if state.offline_users.read().unwrap().contains_key(&new_name) {
state state
.online_users .online_users
.lock() .write()
.unwrap() .unwrap()
.insert( .insert(
addr, addr,
state state
.offline_users .offline_users
.lock() .write()
.unwrap() .unwrap()
.remove(&new_name) .remove(&new_name)
.unwrap(), .unwrap(),
@ -134,7 +134,7 @@ fn handle_user_log_in(
} else { } else {
state state
.online_users .online_users
.lock() .write()
.unwrap() .unwrap()
.get_mut(&addr) .get_mut(&addr)
.unwrap() .unwrap()
@ -154,8 +154,8 @@ fn handle_user_log_in(
tracing::debug!( tracing::debug!(
"Online Users: {} Offline Users: {}", "Online Users: {} Offline Users: {}",
state.online_users.lock().unwrap().len(), state.online_users.read().unwrap().len(),
state.offline_users.lock().unwrap().len() state.offline_users.read().unwrap().len()
); );
tx.send(games_update(state))?; tx.send(games_update(state))?;
@ -174,7 +174,7 @@ fn handle_close(
"Close received from {0} with code: {1} and reason: {2}", "Close received from {0} with code: {1} and reason: {2}",
state state
.online_users .online_users
.lock() .read()
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
@ -193,7 +193,7 @@ fn handle_close(
"{0} left.", "{0} left.",
state state
.online_users .online_users
.lock() .read()
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
@ -207,7 +207,7 @@ fn handle_close(
tx.send(to_string::<ChatMessage>(&msg)?)?; tx.send(to_string::<ChatMessage>(&msg)?)?;
let name = state let name = state
.online_users .online_users
.lock() .read()
.unwrap() .unwrap()
.get(&addr) .get(&addr)
.unwrap() .unwrap()
@ -216,9 +216,9 @@ fn handle_close(
.name .name
.clone(); .clone();
state.offline_users.lock().unwrap().insert( state.offline_users.write().unwrap().insert(
name.clone(), name.clone(),
state.online_users.lock().unwrap().remove(&addr).unwrap(), state.online_users.write().unwrap().remove(&addr).unwrap(),
); );
tx.send(server_summary_update(state))?; tx.send(server_summary_update(state))?;

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, RwLock}, sync::{Arc, RwLock},
}; };
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
@ -104,14 +104,14 @@ 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<RwLock<User>>>>, online_users: RwLock<HashMap<SocketAddr, Arc<RwLock<User>>>>,
offline_users: Mutex<HashMap<String, Arc<RwLock<User>>>>, offline_users: RwLock<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
all_cards: Vec<CardSet>, all_cards: Vec<CardSet>,
// Games list // Games list
games: Mutex<Vec<Game>>, games: RwLock<Vec<Game>>,
// chatrooms: Mutex<HashMap<String, ChatRoom<'user>>>, // chatrooms: Mutex<HashMap<String, ChatRoom<'user>>>,
first_names: Vec<String>, first_names: Vec<String>,
last_names: Vec<String>, last_names: Vec<String>,
@ -131,10 +131,10 @@ 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<RwLock<User>>>::new()); let online_users = RwLock::new(HashMap::<SocketAddr, Arc<RwLock<User>>>::new());
let offline_users = Mutex::new(HashMap::<String, Arc<RwLock<User>>>::new()); let offline_users = RwLock::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 = RwLock::new(vec![]);
let first_names = load_names("data/first.txt")?; let first_names = load_names("data/first.txt")?;
let last_names = load_names("data/last.txt")?; let last_names = load_names("data/last.txt")?;