trifid/tfclient/src/daemon.rs

139 lines
4.1 KiB
Rust

use log::{error, info};
use std::sync::mpsc;
use std::sync::mpsc::Sender;
use std::thread;
use crate::apiworker::{apiworker_main, APIWorkerMessage};
use crate::config::load_config;
use crate::nebulaworker::{NebulaWorkerMessage, nebulaworker_main};
use crate::socketworker::{socketworker_main, SocketWorkerMessage};
use crate::timerworker::{timer_main, TimerWorkerMessage};
use crate::util::{check_server_url, shutdown};
pub fn daemon_main(name: String, server: String) {
// Validate the `server`
check_server_url(&server);
info!("Loading config...");
let config = match load_config(&name) {
Ok(cfg) => cfg,
Err(e) => {
error!("Error loading configuration: {}", e);
std::process::exit(1);
}
};
info!("Creating transmitter");
let (tx_api, rx_api) = mpsc::channel::<APIWorkerMessage>();
let (tx_socket, rx_socket) = mpsc::channel::<SocketWorkerMessage>();
let (tx_nebula, rx_nebula) = mpsc::channel::<NebulaWorkerMessage>();
let (tx_timer, rx_timer) = mpsc::channel::<TimerWorkerMessage>();
let transmitter = ThreadMessageSender {
socket_thread: tx_socket,
api_thread: tx_api,
nebula_thread: tx_nebula,
timer_thread: tx_timer,
};
let mainthread_transmitter = transmitter.clone();
info!("Setting signal trap...");
match ctrlc::set_handler(move || {
info!("Ctrl-C detected. Stopping threads...");
shutdown(&mainthread_transmitter);
}) {
Ok(_) => (),
Err(e) => {
error!("Unable to set sigtrap: {}", e);
std::process::exit(1);
}
}
info!("Starting API thread...");
let config_api = config.clone();
let transmitter_api = transmitter.clone();
let name_api = name.clone();
let server_api = server;
let api_thread = thread::spawn(move || {
apiworker_main(config_api, name_api, server_api, transmitter_api, rx_api);
});
info!("Starting Nebula thread...");
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);
});
info!("Starting socket worker thread...");
let name_socket = name;
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);
});
info!("Starting timer thread...");
let timer_transmitter = transmitter;
let timer_thread = thread::spawn(move || {
timer_main(timer_transmitter, rx_timer, config.disable_automatic_config_updates);
});
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");
info!("Waiting for socket thread to exit...");
match socket_thread.join() {
Ok(_) => (),
Err(_) => {
error!("Error waiting for socket thread to exit.");
std::process::exit(1);
}
}
info!("Socket thread exited");
info!("Waiting for API thread to exit...");
match api_thread.join() {
Ok(_) => (),
Err(_) => {
error!("Error waiting for api thread to exit.");
std::process::exit(1);
}
}
info!("API thread exited");
info!("Waiting for Nebula thread to exit...");
match nebula_thread.join() {
Ok(_) => (),
Err(_) => {
error!("Error waiting for nebula thread to exit.");
std::process::exit(1);
}
}
info!("Nebula thread exited");
info!("All threads exited");
}
#[derive(Clone)]
pub struct ThreadMessageSender {
pub socket_thread: Sender<SocketWorkerMessage>,
pub api_thread: Sender<APIWorkerMessage>,
pub nebula_thread: Sender<NebulaWorkerMessage>,
pub timer_thread: Sender<TimerWorkerMessage>,
}