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