Skip to content

Commit

Permalink
Merge pull request #14 from amiller68/board-stream
Browse files Browse the repository at this point in the history
Board stream
  • Loading branch information
amiller68 authored Jan 29, 2024
2 parents d09f0d9 + adf9ea1 commit 7dfe290
Show file tree
Hide file tree
Showing 18 changed files with 710 additions and 291 deletions.
364 changes: 219 additions & 145 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 6 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,22 @@ edition = "2021"
[dependencies]
askama = { version = "0.12.1", features = ["with-axum"] }
askama_axum = "0.4.0"
axum = "0.7.3"
axum = { version = "^0.7", features = ["tokio"] }
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"
shuttle-axum = "0.36.0"
shuttle-runtime = "0.36.0"
shuttle-shared-db = { version = "0.36.0", features = ["postgres"] }
shuttle-axum = "^0.37"
shuttle-runtime = "^0.37"
shuttle-shared-db = { version = "^0.37", features = ["sqlx", "postgres"] }
sqlx = { version = "0.7.3", features = ["macros", "uuid", "time"] }
thiserror = "1.0.56"
time = { version = "0.3.31", features = ["serde"] }
tokio = "1.28.2"
tokio-stream = { version = "0.1.14", features = ["sync"] }
tower-http = { version = "0.5.1", features = ["fs"] }
uuid = { version = "1.7.0", features = ["serde"] }
pleco = "0.5.0"

tracing = "^0.1"
tracing-appender = "^0.2"
tracing-futures = { version = "^0.2", default-features = false, features = ["std-future"] }
tracing-subscriber = { version = "^0.3", default-features = false, features = ["ansi", "env-filter", "fmt", "local-time", "time", "tracing"] }
pleco = "0.5.0"


# TODO: add prop tests for database types
# [dev-dependencies]
# proptest = "1.4.0"
# proptest-derive = "0.4.0"
tracing-subscriber = { version = "^0.3", default-features = false, features = ["ansi", "env-filter", "fmt", "local-time", "time", "tracing"] }
8 changes: 6 additions & 2 deletions src/api/games/make_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ use axum::{
};
use sqlx::types::Uuid;

use crate::api::models::ApiGameBoard;
use crate::api::templates::GameBoardTemplate;
use crate::database::models::{Game, GameBoard, GameError};
use crate::AppState;

use super::watch_game_sse::{GameUpdate, GameUpdateStream};
use super::watch_game_sse::GameUpdateStream;

#[derive(serde::Deserialize, Debug)]
pub struct MakeMoveRequest {
Expand All @@ -34,9 +36,11 @@ pub async fn handler(
// Returns the updated board if the move was valid. Otherwise, returns the latest board.
GameBoard::make_move(&mut conn, game_id, &uci_move, resign).await?;

// Wow this really sucks, the client should just read this again
let api_game_board = ApiGameBoard::from(GameBoard::latest(&mut conn, game_id).await?);
conn.commit().await?;

if tx.send(GameUpdate).is_err() {
if tx.send(GameBoardTemplate { api_game_board }).is_err() {
tracing::warn!("failed to send game update: game_id={}", game_id);
}

Expand Down
1 change: 0 additions & 1 deletion src/api/games/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ pub mod create_game;
pub mod make_move;
pub mod read_all_games;
pub mod read_game;
pub mod read_game_board;
pub mod watch_game_sse;
12 changes: 3 additions & 9 deletions src/api/games/read_game.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use askama::Template;
use axum::{
extract::{Path, State},
response::{IntoResponse, Response},
};
use sqlx::types::Uuid;

use crate::api::models::ApiGameBoard;
use crate::api::templates::GameIndexTemplate;
use crate::database::models::{Game, GameBoard, GameError};
use crate::AppState;

Expand All @@ -21,14 +21,8 @@ pub async fn handler(
let game_board = GameBoard::latest(&mut conn, game_id).await?;

let api_game_board = ApiGameBoard::from(game_board);

Ok(TemplateApiGameBoard { api_game_board })
}

#[derive(Template)]
#[template(path = "game_index.html")]
struct TemplateApiGameBoard {
api_game_board: ApiGameBoard,

Ok(GameIndexTemplate { api_game_board })
}

#[derive(Debug, thiserror::Error)]
Expand Down
16 changes: 10 additions & 6 deletions src/api/games/watch_game_sse.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
use std::convert::Infallible;
use std::time::Duration;

use askama::Template;
use axum::{
extract::Path,
response::{sse::Event, Sse},
Extension,
};
use serde::Serialize;
use sqlx::types::Uuid;
use tokio::sync::broadcast::Sender;
use tokio_stream::wrappers::BroadcastStream;
use tokio_stream::{Stream, StreamExt as _};

pub type GameUpdateStream = Sender<GameUpdate>;

#[derive(Clone, Serialize, Debug)]
pub struct GameUpdate;
use crate::api::templates::GameBoardTemplate;

// TODO: generalize and use the read_game_board handler
pub type GameUpdateStream = Sender<GameBoardTemplate>;
pub async fn handler(
Path(game_id): Path<Uuid>,
Extension(tx): Extension<GameUpdateStream>,
Expand All @@ -28,7 +27,12 @@ pub async fn handler(
// Catch all updata events for this game
Sse::new(
stream
.map(move |_| Event::default().event(format!("game-update-{}", game_id)))
.map(move |tagb| {
let tagb = tagb.unwrap();
Event::default()
.event(format!("game-update-{}", game_id))
.data(tagb.render().unwrap())
})
.map(Ok),
)
.keep_alive(
Expand Down
1 change: 1 addition & 0 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod games;
pub mod models;
pub mod templates;
1 change: 1 addition & 0 deletions src/api/models/api_game_board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::database::models::GameStatus;
use crate::database::models::GameWinner;
use crate::database::types::DatabaseBoard as Board;

#[derive(Clone)]
pub struct ApiGameBoard {
pub game_id: String,
pub board: Board,
Expand Down
9 changes: 9 additions & 0 deletions src/api/templates/game_board.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use askama::Template;

use crate::api::models::ApiGameBoard;

#[derive(Template, Clone)]
#[template(path = "game_board.html")]
pub struct GameBoardTemplate {
pub api_game_board: ApiGameBoard,
}
9 changes: 9 additions & 0 deletions src/api/templates/game_index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use askama::Template;

use crate::api::models::ApiGameBoard;

#[derive(Template)]
#[template(path = "game_index.html")]
pub struct GameIndexTemplate {
pub api_game_board: ApiGameBoard,
}
5 changes: 5 additions & 0 deletions src/api/templates/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod game_board;
mod game_index;

pub use game_board::GameBoardTemplate;
pub use game_index::GameIndexTemplate;
8 changes: 3 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use tower_http::services::ServeDir;
mod api;
mod database;

use api::templates::GameBoardTemplate;

#[derive(Clone)]
pub struct AppState {
database: PgPool,
Expand Down Expand Up @@ -37,7 +39,7 @@ async fn main(
.expect("Looks like something went wrong with migrations :(");
// Setup State
let state = AppState::new(db);
let (tx, _rx) = channel::<api::games::watch_game_sse::GameUpdate>(10);
let (tx, _rx) = channel::<GameBoardTemplate>(10);

// Register panics as they happen
register_panic_logger();
Expand All @@ -59,10 +61,6 @@ async fn main(
"/games/:game_id/sse",
get(api::games::watch_game_sse::handler),
)
.route(
"/games/:game_id/board",
get(api::games::read_game_board::handler),
)
.with_state(state)
.layer(Extension(tx))
// Static assets
Expand Down
Loading

0 comments on commit 7dfe290

Please sign in to comment.