2023-05-14 17:47:49 +00:00
|
|
|
use log::{error, info};
|
2023-03-22 18:34:06 +00:00
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::sync::mpsc::Sender;
|
|
|
|
use std::thread;
|
2023-03-22 18:36:36 +00:00
|
|
|
|
2023-03-22 18:34:06 +00:00
|
|
|
use crate::apiworker::{apiworker_main, APIWorkerMessage};
|
2023-03-21 17:00:01 +00:00
|
|
|
use crate::config::load_config;
|
2023-03-29 00:42:36 +00:00
|
|
|
|
2023-05-28 20:13:35 +00:00
|
|
|
use crate::nebulaworker::{NebulaWorkerMessage, nebulaworker_main};
|
2023-03-22 18:34:06 +00:00
|
|
|
use crate::socketworker::{socketworker_main, SocketWorkerMessage};
|
2023-03-29 13:37:03 +00:00
|
|
|
use crate::timerworker::{timer_main, TimerWorkerMessage};
|
2023-03-22 18:34:06 +00:00
|
|
|
use crate::util::check_server_url;
|
2023-03-21 17:00:01 +00:00
|
|
|
|
|
|
|
pub fn daemon_main(name: String, server: String) {
|
|
|
|
// Validate the `server`
|
2023-03-22 18:34:06 +00:00
|
|
|
check_server_url(&server);
|
|
|
|
|
|
|
|
info!("Loading config...");
|
|
|
|
let config = match load_config(&name) {
|
|
|
|
Ok(cfg) => cfg,
|
2023-03-21 17:00:01 +00:00
|
|
|
Err(e) => {
|
2023-03-22 18:34:06 +00:00
|
|
|
error!("Error loading configuration: {}", e);
|
2023-03-21 17:00:01 +00:00
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
};
|
2023-03-22 18:34:06 +00:00
|
|
|
|
2023-03-23 17:17:37 +00:00
|
|
|
info!("Creating transmitter");
|
2023-03-22 18:34:06 +00:00
|
|
|
|
|
|
|
let (tx_api, rx_api) = mpsc::channel::<APIWorkerMessage>();
|
|
|
|
let (tx_socket, rx_socket) = mpsc::channel::<SocketWorkerMessage>();
|
2023-05-28 20:13:35 +00:00
|
|
|
let (tx_nebula, rx_nebula) = mpsc::channel::<NebulaWorkerMessage>();
|
2023-03-29 13:37:03 +00:00
|
|
|
let (tx_timer, rx_timer) = mpsc::channel::<TimerWorkerMessage>();
|
2023-03-22 18:34:06 +00:00
|
|
|
|
|
|
|
let transmitter = ThreadMessageSender {
|
|
|
|
socket_thread: tx_socket,
|
|
|
|
api_thread: tx_api,
|
2023-03-29 13:37:03 +00:00
|
|
|
nebula_thread: tx_nebula,
|
|
|
|
timer_thread: tx_timer,
|
2023-03-22 18:34:06 +00:00
|
|
|
};
|
|
|
|
|
2023-03-23 17:17:37 +00:00
|
|
|
let mainthread_transmitter = transmitter.clone();
|
|
|
|
|
|
|
|
info!("Setting signal trap...");
|
|
|
|
|
|
|
|
match ctrlc::set_handler(move || {
|
|
|
|
info!("Ctrl-C detected. Stopping threads...");
|
2023-05-14 17:47:49 +00:00
|
|
|
match mainthread_transmitter
|
|
|
|
.nebula_thread
|
|
|
|
.send(NebulaWorkerMessage::Shutdown)
|
|
|
|
{
|
2023-03-23 17:17:37 +00:00
|
|
|
Ok(_) => (),
|
|
|
|
Err(e) => {
|
2023-05-14 17:47:49 +00:00
|
|
|
error!(
|
|
|
|
"Error sending shutdown message to nebula worker thread: {}",
|
|
|
|
e
|
|
|
|
);
|
2023-03-23 17:17:37 +00:00
|
|
|
}
|
|
|
|
}
|
2023-05-14 17:47:49 +00:00
|
|
|
match mainthread_transmitter
|
|
|
|
.api_thread
|
|
|
|
.send(APIWorkerMessage::Shutdown)
|
|
|
|
{
|
2023-03-23 17:17:37 +00:00
|
|
|
Ok(_) => (),
|
|
|
|
Err(e) => {
|
|
|
|
error!("Error sending shutdown message to api worker thread: {}", e);
|
|
|
|
}
|
|
|
|
}
|
2023-05-14 17:47:49 +00:00
|
|
|
match mainthread_transmitter
|
|
|
|
.socket_thread
|
|
|
|
.send(SocketWorkerMessage::Shutdown)
|
|
|
|
{
|
2023-03-23 17:17:37 +00:00
|
|
|
Ok(_) => (),
|
|
|
|
Err(e) => {
|
2023-05-14 17:47:49 +00:00
|
|
|
error!(
|
|
|
|
"Error sending shutdown message to socket worker thread: {}",
|
|
|
|
e
|
|
|
|
);
|
2023-03-23 17:17:37 +00:00
|
|
|
}
|
|
|
|
}
|
2023-05-14 17:47:49 +00:00
|
|
|
match mainthread_transmitter
|
|
|
|
.timer_thread
|
|
|
|
.send(TimerWorkerMessage::Shutdown)
|
|
|
|
{
|
2023-03-29 13:37:03 +00:00
|
|
|
Ok(_) => (),
|
|
|
|
Err(e) => {
|
2023-05-14 17:47:49 +00:00
|
|
|
error!(
|
|
|
|
"Error sending shutdown message to timer worker thread: {}",
|
|
|
|
e
|
|
|
|
);
|
2023-03-29 13:37:03 +00:00
|
|
|
}
|
|
|
|
}
|
2023-03-23 17:17:37 +00:00
|
|
|
}) {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(e) => {
|
|
|
|
error!("Unable to set sigtrap: {}", e);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
info!("Starting API thread...");
|
|
|
|
|
2023-03-22 18:34:06 +00:00
|
|
|
let config_api = config.clone();
|
|
|
|
let transmitter_api = transmitter.clone();
|
2023-03-27 16:32:26 +00:00
|
|
|
let name_api = name.clone();
|
2023-05-14 17:47:49 +00:00
|
|
|
let server_api = server;
|
2023-03-22 18:34:06 +00:00
|
|
|
let api_thread = thread::spawn(move || {
|
2023-05-14 17:47:49 +00:00
|
|
|
apiworker_main(config_api, name_api, server_api, transmitter_api, rx_api);
|
2023-03-22 18:34:06 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
info!("Starting Nebula thread...");
|
2023-05-28 20:13:35 +00:00
|
|
|
let config_nebula = config.clone();
|
|
|
|
let transmitter_nebula = transmitter.clone();
|
|
|
|
let name_nebula = name.clone();
|
|
|
|
let nebula_thread = thread::spawn(move || {
|
|
|
|
nebulaworker_main(config_nebula, name_nebula, transmitter_nebula, rx_nebula);
|
|
|
|
});
|
2023-03-22 18:34:06 +00:00
|
|
|
|
2023-03-31 00:28:13 +00:00
|
|
|
info!("Starting socket worker thread...");
|
2023-05-14 17:47:49 +00:00
|
|
|
let name_socket = name;
|
2023-03-31 00:28:13 +00:00
|
|
|
let config_socket = config.clone();
|
|
|
|
let tx_socket = transmitter.clone();
|
|
|
|
let socket_thread = thread::spawn(move || {
|
|
|
|
socketworker_main(config_socket, name_socket, tx_socket, rx_socket);
|
|
|
|
});
|
|
|
|
|
2023-03-29 13:37:03 +00:00
|
|
|
info!("Starting timer thread...");
|
2023-03-30 21:34:00 +00:00
|
|
|
if !config.disable_automatic_config_updates {
|
2023-05-14 17:47:49 +00:00
|
|
|
let timer_transmitter = transmitter;
|
2023-03-30 21:34:00 +00:00
|
|
|
let timer_thread = thread::spawn(move || {
|
|
|
|
timer_main(timer_transmitter, rx_timer);
|
|
|
|
});
|
|
|
|
info!("Waiting for timer thread to exit...");
|
|
|
|
match timer_thread.join() {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(_) => {
|
|
|
|
error!("Error waiting for timer thread to exit.");
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
info!("Timer thread exited");
|
|
|
|
} else {
|
|
|
|
info!("automatic config updates have been disabled - not starting timer thread");
|
|
|
|
}
|
2023-03-29 13:37:03 +00:00
|
|
|
|
2023-03-22 18:34:06 +00:00
|
|
|
info!("Waiting for socket thread to exit...");
|
|
|
|
match socket_thread.join() {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(_) => {
|
|
|
|
error!("Error waiting for socket thread to exit.");
|
2023-03-21 17:00:01 +00:00
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
}
|
2023-03-23 17:17:37 +00:00
|
|
|
info!("Socket thread exited");
|
2023-03-21 17:00:01 +00:00
|
|
|
|
2023-03-22 18:34:06 +00:00
|
|
|
info!("Waiting for API thread to exit...");
|
|
|
|
match api_thread.join() {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(_) => {
|
|
|
|
error!("Error waiting for api thread to exit.");
|
2023-03-21 17:00:01 +00:00
|
|
|
std::process::exit(1);
|
|
|
|
}
|
2023-03-22 18:34:06 +00:00
|
|
|
}
|
2023-03-23 17:17:37 +00:00
|
|
|
info!("API thread exited");
|
2023-03-22 18:34:06 +00:00
|
|
|
|
|
|
|
info!("Waiting for Nebula thread to exit...");
|
2023-05-28 20:13:35 +00:00
|
|
|
match nebula_thread.join() {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(_) => {
|
|
|
|
error!("Error waiting for nebula thread to exit.");
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
}
|
2023-03-23 17:17:37 +00:00
|
|
|
info!("Nebula thread exited");
|
2023-03-22 18:34:06 +00:00
|
|
|
|
|
|
|
info!("All threads exited");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct ThreadMessageSender {
|
2023-03-23 17:17:37 +00:00
|
|
|
pub socket_thread: Sender<SocketWorkerMessage>,
|
|
|
|
pub api_thread: Sender<APIWorkerMessage>,
|
2023-03-29 13:37:03 +00:00
|
|
|
pub nebula_thread: Sender<NebulaWorkerMessage>,
|
2023-05-14 17:47:49 +00:00
|
|
|
pub timer_thread: Sender<TimerWorkerMessage>,
|
|
|
|
}
|