Server/logging #23

Merged
htamas1210 merged 3 commits from Server/logging into master 2025-11-24 13:30:22 +01:00
5 changed files with 226 additions and 18 deletions

177
server/Cargo.lock generated
View File

@@ -2,6 +2,65 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
]
[[package]]
name = "anyhow"
version = "1.0.100"
@@ -47,6 +106,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "cpufeatures"
version = "0.2.17"
@@ -102,6 +167,29 @@ dependencies = [
"serde_json",
]
[[package]]
name = "env_filter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]]
name = "fnv"
version = "1.0.7"
@@ -313,12 +401,42 @@ dependencies = [
"icu_properties",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde_core",
]
[[package]]
name = "jiff-static"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "js-sys"
version = "0.3.82"
@@ -379,6 +497,12 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "parking_lot"
version = "0.12.5"
@@ -420,6 +544,21 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "portable-atomic"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "potential_utf"
version = "0.1.4"
@@ -530,6 +669,35 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]]
name = "rustversion"
version = "1.0.22"
@@ -597,6 +765,9 @@ version = "0.1.0"
dependencies = [
"anyhow",
"engine",
"env_logger",
"futures-util",
"log",
"futures-util",
"rand 0.9.2",
"serde",
@@ -803,6 +974,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.18.1"

View File

@@ -15,6 +15,8 @@ uuid = {version = "1.18.1", features = ["v4", "serde"] }
anyhow = "1.0.100"
rand = "0.9.2"
engine = {path = "../engine/"}
log = {version = "0.4.28"}
env_logger = "0.11.8"
[[bin]]

View File

@@ -4,6 +4,7 @@ use engine::chessmove::ChessMove;
use engine::gameend::GameEnd::{self, *};
use engine::{get_available_moves, is_game_over};
use futures_util::{SinkExt, StreamExt};
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
use std::char::from_u32_unchecked;
use std::collections::{HashMap, VecDeque};
@@ -25,14 +26,17 @@ pub async fn clean_up_match(matches: &MatchMap, match_id: &Uuid) {
// Helper functions to create new instances
pub fn new_connection_map() -> ConnectionMap {
warn!("Created new connection map");
Arc::new(Mutex::new(HashMap::new()))
}
pub fn new_match_map() -> MatchMap {
warn!("Created new match map");
Arc::new(Mutex::new(HashMap::new()))
}
pub fn new_waiting_queue() -> WaitingQueue {
warn!("Created new waiting queue");
Arc::new(Mutex::new(VecDeque::new()))
}
@@ -107,11 +111,11 @@ pub async fn send_message_to_player_connection(
) -> Result<(), tokio_tungstenite::tungstenite::Error> {
match connection {
Some(connection) => {
println!("sending message to: {}", connection.id);
info!("sending message to: {}", connection.id);
connection.tx.send(Message::Text(message.to_string())).await
}
None => {
eprintln!("No connection provided");
error!("No connection provided");
Err(tokio_tungstenite::tungstenite::Error::ConnectionClosed)
}
}
@@ -123,7 +127,7 @@ pub async fn broadcast_to_all(connections: &ConnectionMap, message: &str) {
for (id, connection) in connections_lock.iter_mut() {
if let Err(e) = connection.tx.send(Message::Text(message.to_string())).await {
eprintln!("Failed to send to {}: {}", id, e);
error!("Failed to send to {}: {}", id, e);
dead_connections.push(*id);
}
}
@@ -140,6 +144,7 @@ pub async fn broadcast_to_match(
match_id: Uuid,
message: &str,
) -> Result<(), Box<dyn std::error::Error>> {
info!("Broadcasting data to match: {}", &match_id);
let matches_lock = matches.lock().await;
if let Some(game_match) = matches_lock.get(&match_id) {
send_message_to_player_connection(
@@ -167,6 +172,7 @@ pub async fn handle_connection(
let ws_stream = accept_async(stream).await?;
let (write, mut read) = ws_stream.split();
warn!("Accepted new connection");
let player_id = Uuid::new_v4();
@@ -184,13 +190,13 @@ pub async fn handle_connection(
);
}
println!("New connection: {}", player_id);
info!("id: {}", &player_id);
// Message processing loop
while let Some(Ok(message)) = read.next().await {
if message.is_text() {
let text = message.to_text()?;
println!("Received from {}: {}", player_id, text);
info!("Received from {}: {}", player_id, text);
let client_data: ClientEvent = serde_json::from_str(text)
.expect("Failed to convert data into json at handle_connection");
@@ -200,7 +206,8 @@ pub async fn handle_connection(
{
let mut conn_map = connections.lock().await;
let player = conn_map.get_mut(&player_id).unwrap();
player.username = Some(username);
player.username = Some(username.clone());
info!("player: {}, set username: {}", &player_id, username);
}
//respone to client
@@ -216,8 +223,8 @@ pub async fn handle_connection(
FindMatch => {
let mut wait_queue = waiting_queue.lock().await;
wait_queue.push_back(player_id.clone());
println!("Appended {} to the waiting queue", player_id);
println!("queue {:?}", wait_queue);
info!("Appended {} to the waiting queue", player_id);
info!("queue {:?}", wait_queue);
}
Move { step } => {
let match_id = connections
@@ -229,6 +236,7 @@ pub async fn handle_connection(
.unwrap();
{
info!("updating board state in match: {}", &match_id);
let mut matches = matches.lock().await;
matches.get_mut(&match_id).unwrap().board_state =
engine::get_board_after_move(
@@ -261,6 +269,7 @@ pub async fn handle_connection(
match is_game_end {
Some(res) => {
warn!("A player won the match: {}", &match_id);
let message = ServerMessage2::GameEnd { winner: res };
let _ = broadcast_to_match(
&connections,
@@ -272,21 +281,23 @@ pub async fn handle_connection(
clean_up_match(&matches, &match_id);
}
None => {
println!("No winner match continues.")
info!("No winner match continues. Id: {}", &match_id);
}
}
}
}
RequestLegalMoves { fen } => {
info!("Requesting legal moves player: {}", &player_id);
let moves = get_available_moves(&fen);
let _ = send_message_to_player_connection(
connections.lock().await.get_mut(&player_id),
&serde_json::to_string(&moves).unwrap(),
)
.await;
println!("Sent moves to player: {}", player_id);
info!("Sent moves to player: {}", player_id);
}
Resign => {
warn!("Resigned!");
let (fuck, fuck_id): (ServerMessage2, &Uuid) = {
let matches = matches.lock().await;
@@ -347,7 +358,7 @@ pub async fn handle_connection(
clean_up_match(&matches, fuck_id);
}
_ => {
println!("Not known client event");
warn!("Not known client event");
}
}
}
@@ -355,7 +366,7 @@ pub async fn handle_connection(
// Cleanup on disconnect
cleanup_player(player_id, &connections, &matches, &waiting_queue).await;
println!("Connection {} closed", player_id);
warn!("Connection {} closed", player_id);
Ok(())
}
@@ -372,7 +383,7 @@ async fn cleanup_player(
// Remove from connections
connections.lock().await.remove(&player_id);
println!("Cleaned up player {}", player_id);
warn!("Cleaned up player {}", player_id);
}
#[cfg(test)]

View File

@@ -1,12 +1,18 @@
mod connection;
mod matchmaking;
use env_logger::{Env, Logger};
use log::{error, info, warn};
use std::env;
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let env = Env::default().filter_or("MY_LOG_LEVEL", "INFO");
env_logger::init_from_env(env);
let address = "0.0.0.0:9001";
let listener = TcpListener::bind(address).await?;
println!("Server running on ws://{}", address);
info!("Server running on ws://{}", address);
// Shared state initialization using the new helper functions
let connections = connection::new_connection_map();
@@ -33,7 +39,7 @@ async fn main() -> anyhow::Result<()> {
if let Err(e) =
connection::handle_connection(stream, connections, matches, waiting_queue).await
{
eprintln!("Connection error: {}", e);
error!("Connection error: {}", e);
}
});
}

View File

@@ -1,5 +1,6 @@
use crate::connection::ServerMessage2;
use crate::connection::{ConnectionMap, GameMatch, MatchMap, WaitingQueue};
use crate::connection::{ConnectionMap, GameMatch, MatchMap, WaitingQueue, broadcast_to_match};
use log::{error, info, warn};
use rand::random;
use uuid::Uuid;
@@ -30,16 +31,21 @@ impl MatchmakingSystem {
}
async fn try_create_match(&self) {
info!("Checking for new matches!");
let mut queue = self.waiting_queue.lock().await;
while queue.len() >= 2 {
let player1 = queue.pop_front().unwrap();
let player2 = queue.pop_front().unwrap();
info!("Creating new match. Players: {}, {}", &player1, &player2);
let match_id = Uuid::new_v4();
let (white_player, black_player) = if random::<bool>() {
info!("player1 is white, player2 is black");
(player1, player2)
} else {
info!("player2 is white, player1 is black");
(player2, player1)
};
@@ -51,6 +57,8 @@ impl MatchmakingSystem {
move_history: Vec::new(),
};
info!("Match id: {}", &game_match.id);
// Store the match
self.matches.lock().await.insert(match_id, game_match);
@@ -59,14 +67,18 @@ impl MatchmakingSystem {
let mut conn_map = self.connections.lock().await;
if let Some(player) = conn_map.get_mut(&white_player) {
player.current_match = Some(match_id);
} else {
error!("Could not store match id for white player");
}
if let Some(player) = conn_map.get_mut(&black_player) {
player.current_match = Some(match_id);
} else {
error!("Could not store match id for black player");
}
}
// Notify players
println!(
info!(
"Notifying player for a match: {:?} | {:?}",
white_player, black_player
);
@@ -116,7 +128,7 @@ impl MatchmakingSystem {
.await;
}
println!("Match created: {} (white) vs {} (black)", white, black);
info!("Match created: {} (white) vs {} (black)", white, black);
}
}