Skip to main content

tab_pty/
lib.rs

1use crate::prelude::*;
2
3use message::pty::MainShutdown;
4use simplelog::{CombinedLogger, TermLogger, TerminalMode, WriteLogger};
5use std::time::Duration;
6use tab_api::{config::pty_log, launch::*, log::get_level, pty::PtyWebsocketRequest};
7
8use lifeline::dyn_bus::DynBus;
9use service::main::MainService;
10use tab_websocket::resource::connection::WebsocketResource;
11
12mod bus;
13mod message;
14mod prelude;
15mod service;
16
17pub fn pty_main() -> anyhow::Result<()> {
18    init()?;
19
20    debug!("pty process started");
21    let mut runtime = tokio::runtime::Builder::new()
22        .threaded_scheduler()
23        .enable_io()
24        .enable_time()
25        .build()
26        .unwrap();
27
28    let result = runtime.block_on(async { main_async().await });
29
30    runtime.shutdown_timeout(Duration::from_millis(25));
31    debug!("pty process terminated");
32
33    result?;
34
35    Ok(())
36}
37
38fn init() -> anyhow::Result<()> {
39    let log_file = pty_log()?;
40
41    let config = simplelog::ConfigBuilder::new()
42        .set_time_format_str("%H:%M:%S%.3f DAE")
43        .build();
44
45    let level = get_level().unwrap_or(LevelFilter::Info);
46    CombinedLogger::init(vec![
47        TermLogger::new(level, config.clone(), TerminalMode::Stderr),
48        WriteLogger::new(level, config, std::fs::File::create(log_file)?),
49    ])
50    .unwrap();
51
52    log_panics::init();
53
54    Ok(())
55}
56
57async fn main_async() -> anyhow::Result<()> {
58    let (_tx, rx, _lifeline) = spawn().await?;
59    wait_for_shutdown(rx).await;
60    info!("PTY process terminated.");
61
62    Ok(())
63}
64
65async fn spawn() -> anyhow::Result<(
66    impl Sender<PtyWebsocketRequest>,
67    impl Receiver<MainShutdown>,
68    MainService,
69)> {
70    let config = launch_daemon().await?;
71
72    let bus = MainBus::default();
73    bus.capacity::<PtyWebsocketRequest>(64)?;
74
75    let ws_url = format!("ws://127.0.0.1:{}/pty", config.port);
76    let websocket = tab_websocket::connect_authorized(ws_url, config.auth_token.clone()).await?;
77    bus.store_resource(WebsocketResource(websocket));
78    bus.store_resource(config);
79
80    let main = MainService::spawn(&bus)?;
81
82    let tx = bus.tx::<PtyWebsocketRequest>()?;
83    let main_shutdown = bus.rx::<MainShutdown>()?;
84
85    Ok((tx, main_shutdown, main))
86}