1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
use daemonfile::DaemonFile; use crate::bus::DaemonBus; use log::{info, LevelFilter}; use lifeline::{dyn_bus::DynBus, prelude::*}; use message::daemon::DaemonShutdown; use service::daemon::DaemonService; use simplelog::{CombinedLogger, TermLogger, TerminalMode, WriteLogger}; use std::time::Duration; use tab_api::{ config::{daemon_log, DaemonConfig}, launch::wait_for_shutdown, }; use tab_websocket::resource::listener::{WebsocketAuthToken, WebsocketListenerResource}; use tokio::net::TcpListener; mod auth; mod bus; mod daemonfile; mod message; mod prelude; mod service; mod state; pub fn daemon_main() -> anyhow::Result<()> { let mut runtime = tokio::runtime::Builder::new() .threaded_scheduler() .enable_io() .enable_time() .build() .unwrap(); let result = runtime.block_on(async { main_async().await }); runtime.shutdown_timeout(Duration::from_millis(25)); result?; Ok(()) } pub async fn new_bus() -> anyhow::Result<DaemonBus> { let server = TcpListener::bind("127.0.0.1:0").await?; let port = server.local_addr()?.port(); let websocket = WebsocketListenerResource(server); let auth_token = auth::gen_token(); let pid = std::process::id(); let config = DaemonConfig { pid: pid as i32, port, auth_token: auth_token.clone(), }; let bus = DaemonBus::default(); bus.store_resource::<DaemonConfig>(config); bus.store_resource::<WebsocketAuthToken>(auth_token.into()); bus.store_resource::<WebsocketListenerResource>(websocket); Ok(bus) } async fn main_async() -> anyhow::Result<()> { let log_file = daemon_log()?; let config = simplelog::ConfigBuilder::new() .set_time_format_str("%H:%M:%S%.3f DAE") .build(); CombinedLogger::init(vec![ TermLogger::new(LevelFilter::Info, config.clone(), TerminalMode::Stderr), WriteLogger::new(LevelFilter::Info, config, std::fs::File::create(log_file)?), ]) .unwrap(); let bus = new_bus().await?; let config = bus.resource::<DaemonConfig>()?; let daemon_file = DaemonFile::new(&config)?; info!("Daemon started."); info!("Daemon pid: {}", config.pid); info!("Daemon port: {}", config.port); let _service = DaemonService::spawn(&bus)?; let shutdown = bus.rx::<DaemonShutdown>()?; wait_for_shutdown(shutdown).await; info!("Daemon shutdown."); drop(daemon_file); Ok(()) }