Spawn a heartbeat task while players are connected to the server, aborting it once they're off.
This commit is contained in:
parent
9239c19cbe
commit
d2fe79b55c
1 changed files with 32 additions and 1 deletions
|
@ -4,7 +4,7 @@ use futures::{channel::mpsc::*, future::try_join, lock::Mutex, prelude::*};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use stream::iter;
|
use stream::iter;
|
||||||
use future::abortable;
|
use future::{AbortHandle, abortable};
|
||||||
|
|
||||||
/// There is a point at which a client falls far enough behind
|
/// There is a point at which a client falls far enough behind
|
||||||
/// that it's probably not worth trying to catch them up; for now,
|
/// that it's probably not worth trying to catch them up; for now,
|
||||||
|
@ -38,6 +38,7 @@ pub struct PlayerState {
|
||||||
|
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
players: Vec<Option<PlayerState>>,
|
players: Vec<Option<PlayerState>>,
|
||||||
|
heartbeat_task: Option<AbortHandle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -50,6 +51,7 @@ impl Server {
|
||||||
Handle {
|
Handle {
|
||||||
server: Arc::new(Mutex::new(Server {
|
server: Arc::new(Mutex::new(Server {
|
||||||
players: Vec::new(),
|
players: Vec::new(),
|
||||||
|
heartbeat_task: None,
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +77,10 @@ impl Server {
|
||||||
greet(&mut sender).await?;
|
greet(&mut sender).await?;
|
||||||
self.players[player_id] = Some(PlayerState { sender });
|
self.players[player_id] = Some(PlayerState { sender });
|
||||||
info!("Client#{} connected", player_id);
|
info!("Client#{} connected", player_id);
|
||||||
|
|
||||||
|
// ensure server task is running
|
||||||
|
self.spinup();
|
||||||
|
|
||||||
Ok(player_id)
|
Ok(player_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +91,31 @@ impl Server {
|
||||||
} else {
|
} else {
|
||||||
error!("Tried to disconnect Client#{} but there was no record for them", player_id);
|
error!("Tried to disconnect Client#{} but there was no record for them", player_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if no players left
|
||||||
|
if self.players.iter().all(Option::is_none) {
|
||||||
|
self.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start the heartbeat task, if it's not running
|
||||||
|
fn spinup(&mut self) {
|
||||||
|
if let None = self.heartbeat_task {
|
||||||
|
info!("Starting heartbeat task");
|
||||||
|
let (task, handle) = abortable(async {
|
||||||
|
info!("Heartbeat task started");
|
||||||
|
});
|
||||||
|
self.heartbeat_task = Some(handle);
|
||||||
|
tokio::spawn(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop any active heartbeat task
|
||||||
|
fn shutdown(&mut self) {
|
||||||
|
if let Some(handle) = self.heartbeat_task.take() {
|
||||||
|
info!("Stopping heartbeat task");
|
||||||
|
handle.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue