Add RCON cooldown, do not require active PID to stop server
This hopefully improves server stopping reliability.
This commit is contained in:
parent
b71d0d1013
commit
5ffc6ee911
@ -15,6 +15,13 @@ use crate::os;
|
|||||||
/// Used to give it some more time to quit forgotten threads, such as for RCON.
|
/// Used to give it some more time to quit forgotten threads, such as for RCON.
|
||||||
const SERVER_QUIT_COOLDOWN: Duration = Duration::from_millis(2500);
|
const SERVER_QUIT_COOLDOWN: Duration = Duration::from_millis(2500);
|
||||||
|
|
||||||
|
/// RCON cooldown. Required period between RCON invocations.
|
||||||
|
///
|
||||||
|
/// The Minecraft RCON implementation is very broken and brittle, this is used in the hopes to
|
||||||
|
/// improve reliability.
|
||||||
|
#[cfg(feature = "rcon")]
|
||||||
|
const RCON_COOLDOWN: Duration = Duration::from_secs(15);
|
||||||
|
|
||||||
/// Server state.
|
/// Server state.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub enum State {
|
pub enum State {
|
||||||
@ -91,6 +98,10 @@ pub struct Server {
|
|||||||
///
|
///
|
||||||
/// Used as starting/stopping timeout.
|
/// Used as starting/stopping timeout.
|
||||||
kill_at: RwLock<Option<Instant>>,
|
kill_at: RwLock<Option<Instant>>,
|
||||||
|
|
||||||
|
/// Last time server was stopped over RCON.
|
||||||
|
#[cfg(feature = "rcon")]
|
||||||
|
rcon_last_stop: Mutex<Option<Instant>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
@ -219,16 +230,9 @@ impl Server {
|
|||||||
|
|
||||||
/// Stop running server.
|
/// Stop running server.
|
||||||
///
|
///
|
||||||
/// This requires the server PID to be known.
|
/// This will attempt to stop the server with all available methods.
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub async fn stop(&self, config: &Config) -> bool {
|
pub async fn stop(&self, config: &Config) -> bool {
|
||||||
// We must have a running process
|
|
||||||
let has_process = self.pid.lock().unwrap().is_some();
|
|
||||||
if !has_process {
|
|
||||||
debug!(target: "lazymc", "Tried to stop server, while no PID is known");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to stop through RCON if started
|
// Try to stop through RCON if started
|
||||||
#[cfg(feature = "rcon")]
|
#[cfg(feature = "rcon")]
|
||||||
if self.state() == State::Started && stop_server_rcon(config, self).await {
|
if self.state() == State::Started && stop_server_rcon(config, self).await {
|
||||||
@ -337,6 +341,8 @@ impl Default for Server {
|
|||||||
last_active: Default::default(),
|
last_active: Default::default(),
|
||||||
keep_online_until: Default::default(),
|
keep_online_until: Default::default(),
|
||||||
kill_at: Default::default(),
|
kill_at: Default::default(),
|
||||||
|
#[cfg(feature = "rcon")]
|
||||||
|
rcon_last_stop: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,6 +425,18 @@ async fn stop_server_rcon(config: &Config, server: &Server) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure RCON has cooled down
|
||||||
|
let rcon_cooled_down = server
|
||||||
|
.rcon_last_stop
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.map(|t| t.elapsed() >= RCON_COOLDOWN)
|
||||||
|
.unwrap_or(true);
|
||||||
|
if !rcon_cooled_down {
|
||||||
|
debug!(target: "lazymc", "Not using RCON to stop server, in cooldown, used too recently");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// RCON address
|
// RCON address
|
||||||
let mut addr = config.server.address;
|
let mut addr = config.server.address;
|
||||||
addr.set_port(config.rcon.port);
|
addr.set_port(config.rcon.port);
|
||||||
@ -439,8 +457,12 @@ async fn stop_server_rcon(config: &Config, server: &Server) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set server to stopping state
|
// Set server to stopping state, update last RCON time
|
||||||
// TODO: set before stop command, revert state on failure
|
server
|
||||||
|
.rcon_last_stop
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.replace(Instant::now());
|
||||||
server.update_state(State::Stopping, config);
|
server.update_state(State::Stopping, config);
|
||||||
|
|
||||||
// Gracefully close connection
|
// Gracefully close connection
|
||||||
|
Loading…
x
Reference in New Issue
Block a user