mod app;
mod cardinality;
mod panes;
mod render;
mod theme;
mod transport;
#[cfg(test)]
mod snapshot_tests;
use crate::cli::{TopDetail, TopGlyphs};
use self::cardinality::DetailGuard;
use self::render::RenderConfig;
use self::transport::{spawn_certs, spawn_collector, spawn_events, spawn_listeners};
use super::{CommandManager, CtlError};
#[derive(Debug, Clone)]
pub struct TopArgs {
pub refresh_ms: u64,
pub no_mouse: bool,
pub skin: Option<String>,
pub detail: Option<TopDetail>,
pub lease_ttl_seconds: u32,
pub snapshot: Option<u32>,
pub tick_once: bool,
pub glyphs: Option<TopGlyphs>,
}
impl CommandManager {
pub fn run_top(&mut self, args: TopArgs) -> Result<(), CtlError> {
let shutdown = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let lease_status_slot = cardinality::new_status_slot();
let (snapshot_rx, collector) = spawn_collector(
self.config.clone(),
args.refresh_ms,
std::sync::Arc::clone(&lease_status_slot),
)?;
let (events_rx, events) = spawn_events(
self.config.clone(),
std::sync::Arc::clone(&shutdown),
std::sync::Arc::clone(&lease_status_slot),
)?;
let (listeners_rx, listeners) = spawn_listeners(
self.config.clone(),
std::sync::Arc::clone(&lease_status_slot),
)?;
let (certs_rx, certs) = spawn_certs(
self.config.clone(),
std::sync::Arc::clone(&lease_status_slot),
)?;
let detail = args.detail.unwrap_or(TopDetail::Backend);
let (lease, lease_status) = match DetailGuard::apply(
&self.config,
detail,
args.lease_ttl_seconds,
"sozu top",
std::sync::Arc::clone(&lease_status_slot),
) {
Ok(g) => (Some(g), None),
Err(e) => (
None,
Some(format!(
"could not elevate metric detail (continuing without lease): {e}"
)),
),
};
let render_cfg = RenderConfig {
mouse: !args.no_mouse,
tick_once: args.tick_once,
snapshot_frames: args.snapshot,
skin: args.skin.clone(),
glyphs: args.glyphs,
initial_status: lease_status,
lease_status: lease_status_slot,
};
let result = render::run(render_cfg, snapshot_rx, events_rx, listeners_rx, certs_rx);
drop(lease);
shutdown.store(true, std::sync::atomic::Ordering::Relaxed);
let _ = collector.join();
let _ = listeners.join();
let _ = certs.join();
let _ = events.join();
result.map_err(|e| {
CtlError::ResolvePath("sozu top render loop".to_owned(), std::io::Error::other(e))
})
}
}