This commit is contained in:
		| @@ -34,7 +34,22 @@ static THREADS: AtomicUsize = AtomicUsize::new(1); | ||||
| async fn main() { | ||||
|     env_logger::init(); | ||||
|  | ||||
|     let (sender, mut receiver) = unbounded_channel(); | ||||
|     let record = env::var("RECORD") | ||||
|         .ok() | ||||
|         .and_then(|record| { | ||||
|             record | ||||
|                 .parse() | ||||
|                 .inspect_err(|err| error!("Unable to parse record options: {err}")) | ||||
|                 .ok() | ||||
|         }) | ||||
|         .unwrap_or(false); | ||||
|  | ||||
|     let (sender, receiver) = if record { | ||||
|         let (sender, receiver) = unbounded_channel(); | ||||
|         (Some(sender), Some(receiver)) | ||||
|     } else { | ||||
|         (None, None) | ||||
|     }; | ||||
|  | ||||
|     debug!("Creating routes"); | ||||
|     let app = Router::new() | ||||
| @@ -59,51 +74,53 @@ async fn main() { | ||||
|     let port = env::var("PORT").unwrap_or_else(|_| "8000".into()); | ||||
|     let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await.unwrap(); | ||||
|  | ||||
|     debug!("Starting observer"); | ||||
|     tokio::spawn(async move { | ||||
|         let mut games = HashMap::new(); | ||||
|         while let Some((request_type, request)) = receiver.recv().await { | ||||
|             match request_type { | ||||
|                 RequestType::Start => { | ||||
|                     let game_id = request.game.id.clone(); | ||||
|                     info!("Got start request {game_id}"); | ||||
|                     if let Some(old_requests) = games.insert(game_id, vec![request]) { | ||||
|                         warn!("evicted duplicate game: {old_requests:?}"); | ||||
|                     } | ||||
|                 } | ||||
|                 RequestType::GetMove => { | ||||
|                     let game_id = request.game.id.clone(); | ||||
|                     info!("Got move request {game_id}"); | ||||
|                     games.entry(game_id).or_default().push(request); | ||||
|                 } | ||||
|                 RequestType::End => { | ||||
|                     let game_id = request.game.id.clone(); | ||||
|                     info!("Got end request {game_id}"); | ||||
|                     if let Some(mut requests) = games.remove(&game_id) { | ||||
|                         requests.push(request); | ||||
|                         let json = match serde_json::to_vec_pretty(&requests) { | ||||
|                             Ok(json) => json, | ||||
|                             Err(e) => { | ||||
|                                 error!("Unable to serealize json: {e}"); | ||||
|                                 continue; | ||||
|                             } | ||||
|                         }; | ||||
|                         match File::create_new(format!("games/{game_id}.json")).await { | ||||
|                             Ok(mut file) => { | ||||
|                                 if let Err(e) = file.write_all(&json).await { | ||||
|                                     error!("Unable to write jsone: {e}"); | ||||
|                                 } | ||||
|                             } | ||||
|                             Err(e) => error!("Unable to open file: {e}"), | ||||
|     if let Some(mut receiver) = receiver { | ||||
|         debug!("Starting observer"); | ||||
|         tokio::spawn(async move { | ||||
|             let mut games = HashMap::new(); | ||||
|             while let Some((request_type, request)) = receiver.recv().await { | ||||
|                 match request_type { | ||||
|                     RequestType::Start => { | ||||
|                         let game_id = request.game.id.clone(); | ||||
|                         info!("Got start request {game_id}"); | ||||
|                         if let Some(old_requests) = games.insert(game_id, vec![request]) { | ||||
|                             warn!("evicted duplicate game: {old_requests:?}"); | ||||
|                         } | ||||
|                     } | ||||
|                     RequestType::GetMove => { | ||||
|                         let game_id = request.game.id.clone(); | ||||
|                         info!("Got move request {game_id}"); | ||||
|                         games.entry(game_id).or_default().push(request); | ||||
|                     } | ||||
|                     RequestType::End => { | ||||
|                         let game_id = request.game.id.clone(); | ||||
|                         info!("Got end request {game_id}"); | ||||
|                         if let Some(mut requests) = games.remove(&game_id) { | ||||
|                             requests.push(request); | ||||
|                             let json = match serde_json::to_vec_pretty(&requests) { | ||||
|                                 Ok(json) => json, | ||||
|                                 Err(e) => { | ||||
|                                     error!("Unable to serealize json: {e}"); | ||||
|                                     continue; | ||||
|                                 } | ||||
|                             }; | ||||
|                             match File::create_new(format!("games/{game_id}.json")).await { | ||||
|                                 Ok(mut file) => { | ||||
|                                     if let Err(e) = file.write_all(&json).await { | ||||
|                                         error!("Unable to write jsone: {e}"); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 Err(e) => error!("Unable to open file: {e}"), | ||||
|                             } | ||||
|                         } else { | ||||
|                             warn!("end of game without game: {request:?}"); | ||||
|                         } | ||||
|                     } else { | ||||
|                         warn!("end of game without game: {request:?}"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         warn!("Observer stopped"); | ||||
|     }); | ||||
|             warn!("Observer stopped"); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     debug!("Starting server"); | ||||
|     axum::serve(listener, app).await.unwrap(); | ||||
| @@ -139,10 +156,12 @@ enum RequestType { | ||||
| } | ||||
|  | ||||
| async fn start( | ||||
|     State(sender): State<UnboundedSender<(RequestType, Request)>>, | ||||
|     State(sender): State<Option<UnboundedSender<(RequestType, Request)>>>, | ||||
|     Json(request): Json<Request>, | ||||
| ) { | ||||
|     if let Err(e) = sender.send((RequestType::Start, request.clone())) { | ||||
|     if let Some(sender) = sender | ||||
|         && let Err(e) = sender.send((RequestType::Start, request.clone())) | ||||
|     { | ||||
|         warn!("Unable to observe request: {e}"); | ||||
|     } | ||||
|     let board = Board::from(&request); | ||||
| @@ -151,11 +170,13 @@ async fn start( | ||||
|  | ||||
| #[allow(clippy::too_many_lines)] | ||||
| async fn get_move( | ||||
|     State(sender): State<UnboundedSender<(RequestType, Request)>>, | ||||
|     State(sender): State<Option<UnboundedSender<(RequestType, Request)>>>, | ||||
|     Json(request): Json<Request>, | ||||
| ) -> response::Json<Response> { | ||||
|     let start = Instant::now(); | ||||
|     if let Err(e) = sender.send((RequestType::GetMove, request.clone())) { | ||||
|     if let Some(sender) = sender | ||||
|         && let Err(e) = sender.send((RequestType::GetMove, request.clone())) | ||||
|     { | ||||
|         warn!("Unable to observe request: {e}"); | ||||
|     } | ||||
|     let board = Game::from(&request); | ||||
| @@ -285,10 +306,12 @@ fn score_standard(board: &Board, id: u8) -> u32 { | ||||
| } | ||||
|  | ||||
| async fn end( | ||||
|     State(sender): State<UnboundedSender<(RequestType, Request)>>, | ||||
|     State(sender): State<Option<UnboundedSender<(RequestType, Request)>>>, | ||||
|     Json(request): Json<Request>, | ||||
| ) { | ||||
|     if let Err(e) = sender.send((RequestType::End, request.clone())) { | ||||
|     if let Some(sender) = sender | ||||
|         && let Err(e) = sender.send((RequestType::End, request.clone())) | ||||
|     { | ||||
|         warn!("Unable to observe request: {e}"); | ||||
|     } | ||||
|     let board = Board::from(&request); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user