Skip to content

Commit

Permalink
refactor: peaceful shutdown
Browse files Browse the repository at this point in the history
Fixes #12
  • Loading branch information
Erb3 committed Jun 5, 2024
1 parent d482722 commit f9afc03
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
socketioxide = {version = "0.13.1", features=["extensions", "state"]}
tokio = {version = "1.38.0", features=["full"]}
tower-http = {version = "0.5.2", features=["cors", "fs"]}
tower-http = {version = "0.5.2", features=["cors", "fs", "timeout"]}
serde = {version = "1.0", features=["derive"]}
rand = {version = "0.8.5", features=["std_rng"]}
axum = "0.7.5"
Expand Down
2 changes: 1 addition & 1 deletion frontend/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ socket.on("join-response", () => {

socket.on("kick", (data) => {
console.log(data);
location.href = "/?error=" + data.message;
location.href = "/?message=" + data.message;
});

socket.on("connect", () => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/landing.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ <h2>

const params = new URLSearchParams(window.location.search);
const errorElement = document.querySelector(".error");
if (params.has("error")) {
errorElement.innerHTML = "Error: " + params.get("error");
if (params.has("message")) {
errorElement.innerHTML = params.get("message");
errorElement.style.display = "block";
}
</script>
Expand Down
3 changes: 2 additions & 1 deletion src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rand::{thread_rng, Rng};
use regex::Regex;
use socketioxide::extract::{Data, SocketRef, State};
use socketioxide::SocketIo;
use std::sync::Arc;
use std::time::Duration;
use tokio::time;
use tracing::info;
Expand Down Expand Up @@ -75,7 +76,7 @@ pub fn on_connect(socket: SocketRef) {
});
}

pub async fn game_loop(cities: Vec<datasource::City>, io: SocketIo, state: GameState) {
pub async fn game_loop(cities: Vec<datasource::City>, io: Arc<SocketIo>, state: GameState) {
let mut interval = time::interval(Duration::from_secs(5));
let mut last_city: Option<&datasource::City> = None;

Expand Down
62 changes: 57 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ mod utils;
use axum::http::Method;
use dotenvy::dotenv;
use memory_serve::{load_assets, MemoryServe};
use socketioxide::SocketIoBuilder;
use socketioxide::{SocketIo, SocketIoBuilder};
use state::GameState;
use std::sync::Arc;
use std::time::Duration;
use tokio::signal;
use tower::ServiceBuilder;
use tower_http::cors::{Any, CorsLayer};
use tower_http::timeout::TimeoutLayer;
use tracing::info;
use tracing_subscriber::FmtSubscriber;

Expand Down Expand Up @@ -51,12 +55,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.allow_origin(Any),
)
.layer(socketio_layer),
);
)
.layer(TimeoutLayer::new(Duration::from_secs(2)));

info!("🎮 Starting game loop");

tokio::spawn(async {
game::game_loop(cities, io, socketio_state).await;
let io_arc = Arc::new(io);
let game_io = Arc::clone(&io_arc);
let shutdown_io = Arc::clone(&io_arc);

tokio::spawn(async move {
game::game_loop(cities, game_io, socketio_state).await;
});

info!("⏳ Starting HTTP server");
Expand All @@ -69,6 +78,49 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.unwrap();

info!("✅ Listening on http://{}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal(shutdown_io))
.await
.unwrap();
Ok(())
}

async fn shutdown_signal(io: Arc<SocketIo>) {
let ctrl_c = async {
signal::ctrl_c()
.await
.expect("failed to install Ctrl+C handler");
};

#[cfg(unix)]
let terminate = async {
signal::unix::signal(signal::unix::SignalKind::terminate())
.expect("failed to install signal handler")
.recv()
.await;
};

#[cfg(not(unix))]
let terminate = std::future::pending::<()>();

tokio::select! {
_ = ctrl_c => {},
_ = terminate => {},
}

info!("Termination signal received, starting graceful shutdown. Exiting in 5s");
for socket in io.sockets().unwrap() {
socket
.emit(
"kick",
packets::DisconnectPacket {
message: "Server going down".to_string(),
},
)
.unwrap();
socket.disconnect().unwrap();
}

tokio::time::sleep(Duration::from_secs(5)).await;
info!("Exit imminent")
}

0 comments on commit f9afc03

Please sign in to comment.