Shutdown command

This commit is contained in:
2025-12-21 15:09:44 +01:00
parent c45f9a59ca
commit 8aa3fe17c1
7 changed files with 66 additions and 9 deletions
+4
View File
@@ -113,6 +113,10 @@ pub fn start_cli(server: Arc<Server>, plugin_loader: PluginLoader) {
"ping" => {
LOGGER.info("pong");
}
"shutdown" => {
server.shutdown();
break;
}
_ => LOGGER.error(format!("Command not found: {}", args[0])),
}
}
+5 -1
View File
@@ -33,11 +33,13 @@ impl PluginLoader {
let plugin_json: PluginJson = serde_json::from_str(&json_string).unwrap();
LOGGER.info(format!("Loading {}", plugin_json.id));
let child = Arc::new(Mutex::new(
Command::new(plugin_json.file)
.args(plugin_json.args)
.current_dir(path)
.spawn()
.unwrap();
.unwrap(),
));
while self
.plugin_clients
@@ -59,6 +61,7 @@ impl PluginLoader {
stream: a.try_clone().unwrap(),
reader: BufReader::new(a),
id: plugin_json.id,
child,
}
}
@@ -88,6 +91,7 @@ impl Clone for Plugin {
stream: self.stream.try_clone().unwrap(),
reader: BufReader::new(self.stream.try_clone().unwrap()),
id: self.id.clone(),
child: self.child.clone(),
}
}
}
+9 -1
View File
@@ -4,7 +4,8 @@ pub mod types;
use std::{
io::{BufRead, BufReader, Write},
net::TcpStream,
sync::Arc,
process::Child,
sync::{Arc, Mutex},
};
use crate::{
@@ -17,6 +18,7 @@ pub struct Plugin {
stream: TcpStream,
reader: BufReader<TcpStream>,
id: String,
child: Arc<Mutex<Child>>,
}
impl Plugin {
@@ -60,4 +62,10 @@ impl Plugin {
}
}
}
pub fn stop(&mut self) {
self.send(&LoaderMessage::Shutdown).unwrap();
self.stream.shutdown(std::net::Shutdown::Both).unwrap();
self.child.lock().unwrap().kill().unwrap();
}
}
+2
View File
@@ -31,6 +31,8 @@ pub enum LoaderMessage {
user_id: String,
msg: Message,
},
Shutdown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
+33 -3
View File
@@ -3,7 +3,10 @@ use std::{
fs::{self},
net::{TcpListener, TcpStream},
path::{Path, PathBuf},
sync::{Arc, Mutex},
sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
},
};
use crate::{
@@ -22,13 +25,13 @@ pub struct ServerConfig {
pub channels: Vec<types::data::Channel>,
}
#[allow(dead_code)]
pub struct Server {
pub root: PathBuf,
pub config: ServerConfig,
pub clients: Mutex<HashSet<Client>>,
pub plugins: Mutex<Vec<Plugin>>,
pub db: utils::database::Database,
pub shutting_down: AtomicBool,
}
impl Default for ServerConfig {
@@ -63,6 +66,7 @@ impl Server {
config,
clients: Mutex::new(HashSet::new()),
plugins: Mutex::new(Vec::new()),
shutting_down: AtomicBool::new(false),
})
}
@@ -182,7 +186,7 @@ impl Server {
fn handle_client(self: &Arc<Self>, client: &Client) -> crate::Result<()> {
// The main req/res loop
loop {
while !self.shutting_down.load(Ordering::SeqCst) {
let req = client.read()?;
if let Some(r) = &req {
self.send_plugin_message(&LoaderMessage::Request {
@@ -192,6 +196,7 @@ impl Server {
self.wrap_err(&client, self.call_request(r, &client))?;
}
}
Ok(())
}
/// When there is a error it removes the client
@@ -217,4 +222,29 @@ impl Server {
}
Ok(())
}
pub fn shutdown(self: &Arc<Self>) {
Self::LOGGER.info("Server shutting down...");
// Signal shutdown
self.shutting_down.store(true, Ordering::SeqCst);
// Disconnect clients
let clients = self.clients.lock().unwrap();
for client in clients.iter() {
let _ = client.send(types::message::ServerMessage::Shutdown {
message: format!("Server shutting down... we'll be back shortly"),
});
let _ = client.close();
}
// Stop plugins
for plugin in self.plugins.lock().unwrap().iter_mut() {
let _ = plugin.stop();
}
Self::LOGGER.info("Shutdown complete");
Self::LOGGER.info("Exiting process..");
std::process::exit(0);
}
}
+4
View File
@@ -115,6 +115,10 @@ pub mod message {
user_id: Author,
channel_id: String,
},
Shutdown {
message: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
+5
View File
@@ -346,6 +346,11 @@ impl Client {
pub fn set_uuid(&mut self, uuid: &str) {
self.1 = Some(uuid.to_string())
}
pub fn close(&self) -> crate::Result<()> {
self.0.shutdown(std::net::Shutdown::Both)?;
Ok(())
}
}
impl Clone for Client {