use crate::server::BackupManager; use crate::server::ServerType; use std::io::Write; use std::process::Child; pub struct ServerProcess { type_: ServerType, version: String, child: Child, backups: BackupManager, } impl ServerProcess { pub fn new( type_: ServerType, version: String, manager: BackupManager, child: Child, ) -> ServerProcess { ServerProcess { type_, version, child, backups: manager, } } pub fn send_command(&mut self, cmd: &str) -> std::io::Result<()> { match cmd.trim() { "stop" | "exit" => self.stop()?, "backup" => self.backup()?, s => self.custom(s)?, } Ok(()) } fn custom(&mut self, cmd: &str) -> std::io::Result<()> { let mut stdin = self.child.stdin.as_ref().unwrap(); stdin.write_all(format!("{}\n", cmd.trim()).as_bytes())?; stdin.flush()?; Ok(()) } pub fn stop(&mut self) -> std::io::Result<()> { self.custom("stop")?; self.child.wait()?; Ok(()) } pub fn kill(&mut self) -> std::io::Result<()> { self.child.kill() } /// Perform a backup by disabling the server's save feature and flushing its data, before /// creating an archive file. pub fn backup(&mut self) -> std::io::Result<()> { self.custom("say backing up server")?; // Make sure the server isn't modifying the files during the backup self.custom("save-off")?; self.custom("save-all")?; // TODO implement a better mechanism // We wait some time to (hopefully) ensure the save-all call has completed std::thread::sleep(std::time::Duration::from_secs(10)); let start_time = chrono::offset::Utc::now(); let res = self.backups.create_backup(); // if res.is_ok() { // self.backups.remove_old_backups()?; // } // The server's save feature needs to be enabled again even if the archive failed to create self.custom("save-on")?; let duration = chrono::offset::Utc::now() - start_time; let duration_str = format!( "{}m{}s", duration.num_seconds() / 60, duration.num_seconds() % 60 ); if res.is_ok() { self.custom(&format!("say server backed up in {}", duration_str))?; } else { self.custom(&format!( "an error occured after {} while backing up the server", duration_str ))?; } res } }