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 std::sync::Arc;
|
||||
use stream::iter;
|
||||
use future::abortable;
|
||||
use future::{AbortHandle, abortable};
|
||||
|
||||
/// 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,
|
||||
|
@ -38,6 +38,7 @@ pub struct PlayerState {
|
|||
|
||||
pub struct Server {
|
||||
players: Vec<Option<PlayerState>>,
|
||||
heartbeat_task: Option<AbortHandle>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -50,6 +51,7 @@ impl Server {
|
|||
Handle {
|
||||
server: Arc::new(Mutex::new(Server {
|
||||
players: Vec::new(),
|
||||
heartbeat_task: None,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +77,10 @@ impl Server {
|
|||
greet(&mut sender).await?;
|
||||
self.players[player_id] = Some(PlayerState { sender });
|
||||
info!("Client#{} connected", player_id);
|
||||
|
||||
// ensure server task is running
|
||||
self.spinup();
|
||||
|
||||
Ok(player_id)
|
||||
}
|
||||
|
||||
|
@ -85,6 +91,31 @@ impl Server {
|
|||
} else {
|
||||
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