From a985279db38a7d3c10dca792fbf81e99d2537f85 Mon Sep 17 00:00:00 2001 From: Condorra Date: Sat, 11 Feb 2023 00:36:09 +1100 Subject: [PATCH] Expose git version for use from deployment pipeline. --- Cargo.lock | 5 ++-- blastmud_game/build.rs | 9 ++++++ blastmud_game/src/regular_tasks.rs | 33 +++++++++++++++++++++- blastmud_interfaces/src/lib.rs | 1 + blastmud_listener/Cargo.toml | 1 + blastmud_listener/build.rs | 9 ++++++ blastmud_listener/src/main.rs | 44 ++++++++++++++++++++++++------ 7 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 blastmud_game/build.rs create mode 100644 blastmud_listener/build.rs diff --git a/Cargo.lock b/Cargo.lock index b5b8763..b28465a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,6 +188,7 @@ dependencies = [ "blastmud_interfaces", "futures", "log", + "once_cell", "rand", "serde", "serde_yaml", @@ -1111,9 +1112,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "ouroboros" diff --git a/blastmud_game/build.rs b/blastmud_game/build.rs new file mode 100644 index 0000000..7691571 --- /dev/null +++ b/blastmud_game/build.rs @@ -0,0 +1,9 @@ +use std::process::Command; + +pub fn main() { + let cmdout = Command::new("git") + .arg("rev-parse").arg("HEAD") + .output().expect("git rev-parse HEAD failed"); + println!("cargo:rustc-env=GIT_VERSION={}", + String::from_utf8(cmdout.stdout).expect("git revision not UTF-8")); +} diff --git a/blastmud_game/src/regular_tasks.rs b/blastmud_game/src/regular_tasks.rs index 43f390f..a52996c 100644 --- a/blastmud_game/src/regular_tasks.rs +++ b/blastmud_game/src/regular_tasks.rs @@ -212,9 +212,40 @@ fn start_task_runner(pool: db::DBPool) { }); } +async fn send_version_once(listener_map: ListenerMap) -> DResult<()> { + for listener_sender in listener_map.lock().await.values().cloned() { + let (tx, rx) = oneshot::channel(); + listener_sender.send( + ListenerSend { + message: MessageToListener::GameserverVersion { + version: env!("GIT_VERSION").to_owned() + }, + ack_notify: tx + } + ).await.unwrap_or(()); + rx.await.unwrap_or(()); + } + Ok(()) +} + +fn start_version_send_task(listener_map: ListenerMap) { + task::spawn(async move { + loop { + time::sleep(time::Duration::from_millis(30000)).await; + match send_version_once(listener_map.clone()).await { + Ok(()) => {} + Err(e) => { + warn!("Error processing tasks: {}", e); + } + } + } + }); +} + pub fn start_regular_tasks(pool: &db::DBPool, listener_map: ListenerMap) -> DResult<()> { start_session_cleanup_task(pool.clone()); - start_send_queue_task(pool.clone(), listener_map); + start_send_queue_task(pool.clone(), listener_map.clone()); + start_version_send_task(listener_map); start_task_runner(pool.clone()); Ok(()) } diff --git a/blastmud_interfaces/src/lib.rs b/blastmud_interfaces/src/lib.rs index 631c06d..393c4cb 100644 --- a/blastmud_interfaces/src/lib.rs +++ b/blastmud_interfaces/src/lib.rs @@ -12,6 +12,7 @@ pub enum MessageFromListener { #[derive(Serialize, Deserialize, Clone, Debug)] pub enum MessageToListener { + GameserverVersion { version: String }, DisconnectSession { session: Uuid }, SendToSession { session: Uuid, msg: String }, AcknowledgeMessage diff --git a/blastmud_listener/Cargo.toml b/blastmud_listener/Cargo.toml index 682be26..2a4606c 100644 --- a/blastmud_listener/Cargo.toml +++ b/blastmud_listener/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" blastmud_interfaces = { path = "../blastmud_interfaces" } futures = "0.3.25" log = "0.4.17" +once_cell = "1.17.0" rand = "0.8.5" serde = { version = "1.0.149", features = ["derive", "serde_derive"] } serde_yaml = "0.9.14" diff --git a/blastmud_listener/build.rs b/blastmud_listener/build.rs new file mode 100644 index 0000000..7691571 --- /dev/null +++ b/blastmud_listener/build.rs @@ -0,0 +1,9 @@ +use std::process::Command; + +pub fn main() { + let cmdout = Command::new("git") + .arg("rev-parse").arg("HEAD") + .output().expect("git rev-parse HEAD failed"); + println!("cargo:rustc-env=GIT_VERSION={}", + String::from_utf8(cmdout.stdout).expect("git revision not UTF-8")); +} diff --git a/blastmud_listener/src/main.rs b/blastmud_listener/src/main.rs index 6e8fee9..a68fae3 100644 --- a/blastmud_listener/src/main.rs +++ b/blastmud_listener/src/main.rs @@ -8,7 +8,7 @@ use tokio::task; use tokio::time::{self, Duration}; use tokio::net::{TcpStream, TcpListener, lookup_host}; use tokio::signal::unix::{signal, SignalKind}; -use tokio::sync::{mpsc, Mutex}; +use tokio::sync::{mpsc, Mutex, RwLock}; use tokio::io::{BufReader, AsyncWriteExt}; use log::{warn, info, LevelFilter}; use simple_logger::SimpleLogger; @@ -20,9 +20,9 @@ use tokio_serde::formats::Cbor; use futures::prelude::*; use uuid::Uuid; use tokio_stream::wrappers::ReceiverStream; -use warp; -use warp::filters::ws; -use warp::Filter; +use warp::{ + self, filters::ws, Filter, Reply +}; use std::time::Instant; #[derive(Deserialize, Debug)] @@ -159,7 +159,7 @@ where message_handler ); break 'full_select; - } + } Ok(Some(MessageToListener::AcknowledgeMessage)) => { break 'wait_for_ack; } @@ -238,6 +238,10 @@ type SessionMap = Arc>; async fn handle_server_message(session_map: SessionMap, message: MessageToListener) { match message { MessageToListener::AcknowledgeMessage => {} + MessageToListener::GameserverVersion { version } => { + let mut version_mut = version_data().write().await; + (*version_mut).gameserver_version = Some(version.clone()); + }, MessageToListener::DisconnectSession { session } => { match session_map.lock().await.by_uuid.get(&session) { // Just silently ignore it if they are disconnected. @@ -584,14 +588,35 @@ async fn handle_websocket( async fn upgrade_websocket(src: String, wsreq: ws::Ws, active_sessions: SessionMap, server_sender: mpsc::Sender) -> - Result { + Result { Ok( wsreq.on_upgrade(|wss| handle_websocket( wss, src, active_sessions, - server_sender)) + server_sender)).into_response() ) } +#[derive(Serialize)] +struct VersionData { + listener_version: String, + gameserver_version: Option, +} + +fn version_data() -> &'static Arc> { + static VERSION_DATA: once_cell::sync::OnceCell>> = + once_cell::sync::OnceCell::new(); + VERSION_DATA.get_or_init(|| { + Arc::new(RwLock::new(VersionData { + listener_version: env!("GIT_VERSION").to_owned(), + gameserver_version: None, + })) + }) +} + +async fn respond_version() -> Result { + Ok(warp::reply::json(&*version_data().read().await).into_response()) +} + async fn start_websocket(bind: String, active_sessions: SessionMap, server_sender: mpsc::Sender) -> DResult<()> { let sockaddr = lookup_host(bind).await?.next().expect("Can't resolve websocket bind name"); let routes = @@ -599,7 +624,10 @@ async fn start_websocket(bind: String, active_sessions: SessionMap, server_sende .and(warp::path("wsgame")) .and(warp::header("X-Forwarded-For")) .and(ws::ws()) - .and_then(move |src, wsreq| upgrade_websocket(src, wsreq, active_sessions.clone(), server_sender.clone())); + .and_then(move |src, wsreq| upgrade_websocket(src, wsreq, active_sessions.clone(), server_sender.clone())) + .or(warp::get() + .and(warp::path("version")) + .and_then(|| respond_version())); task::spawn( warp::serve(