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?;
// 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
// 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
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());
}
@ -148,8 +148,8 @@ fn motd() -> String {
/// Generate server summary update - mostly debug stuff
fn server_summary_update(state: &Arc<AppState>) -> String {
let online_users = state.online_users.lock().unwrap().len();
let active_games = state.games.lock().unwrap().len();
let online_users = state.online_users.read().unwrap().len();
let active_games = state.games.read().unwrap().len();
to_string::<ServerStateSummary>(&ServerStateSummary {
online_users,
active_games,
@ -162,7 +162,7 @@ fn games_update(state: &Arc<AppState>) -> String {
// this may get expensive if there are many games
let mut names = vec![];
for game in state.games.lock().unwrap().iter() {
for game in state.games.read().unwrap().iter() {
names.push(format!(
"Name: {} Host: {}",
game.name,
@ -179,7 +179,7 @@ fn announce_join(state: &Arc<AppState>, addr: &SocketAddr) -> String {
"{} joined.",
state
.online_users
.lock()
.read()
.unwrap()
.get(addr)
.unwrap()

View file

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

View file

@ -8,7 +8,7 @@ use std::{
fs::{read_to_string, File},
io::{BufRead, BufReader},
net::SocketAddr,
sync::{Arc, Mutex, RwLock},
sync::{Arc, RwLock},
};
use tokio::sync::broadcast;
use tower_http::services::ServeDir;
@ -104,14 +104,14 @@ fn load_names(path: &str) -> Result<Vec<String>> {
// Our shared state
pub struct AppState {
// We require unique usernames. This tracks which usernames have been taken.
online_users: Mutex<HashMap<SocketAddr, Arc<RwLock<User>>>>,
offline_users: Mutex<HashMap<String, Arc<RwLock<User>>>>,
online_users: RwLock<HashMap<SocketAddr, Arc<RwLock<User>>>>,
offline_users: RwLock<HashMap<String, Arc<RwLock<User>>>>,
// Channel used to send messages to all connected clients.
tx: broadcast::Sender<String>,
// Master card decks
all_cards: Vec<CardSet>,
// Games list
games: Mutex<Vec<Game>>,
games: RwLock<Vec<Game>>,
// chatrooms: Mutex<HashMap<String, ChatRoom<'user>>>,
first_names: Vec<String>,
last_names: Vec<String>,
@ -131,10 +131,10 @@ 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::<SocketAddr, Arc<RwLock<User>>>::new());
let offline_users = Mutex::new(HashMap::<String, Arc<RwLock<User>>>::new());
let online_users = RwLock::new(HashMap::<SocketAddr, 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 games = Mutex::new(vec![]);
let games = RwLock::new(vec![]);
let first_names = load_names("data/first.txt")?;
let last_names = load_names("data/last.txt")?;