149 lines
4.5 KiB
Rust
149 lines
4.5 KiB
Rust
//! Simplified main function for Baobab Actor TUI
|
|
//!
|
|
//! This binary provides a clean entry point for the actor monitoring and job dispatch interface.
|
|
|
|
use anyhow::{Result, Context};
|
|
use baobab_actor::terminal_ui::{App, setup_and_run_tui};
|
|
use clap::Parser;
|
|
use log::{info, warn, error};
|
|
use std::path::PathBuf;
|
|
use std::process::{Child, Command};
|
|
use tokio::signal;
|
|
|
|
#[derive(Parser)]
|
|
#[command(name = "baobab-actor-tui")]
|
|
#[command(about = "Terminal UI for Baobab Actor - Monitor and dispatch jobs to a single actor")]
|
|
struct Args {
|
|
/// Redis URL for job queue
|
|
#[arg(short, long, default_value = "redis://localhost:6379")]
|
|
redis_url: String,
|
|
|
|
/// Enable verbose logging
|
|
#[arg(short, long)]
|
|
verbose: bool,
|
|
}
|
|
|
|
/// Initialize logging based on verbosity level
|
|
fn init_logging(verbose: bool) {
|
|
if verbose {
|
|
env_logger::Builder::from_default_env()
|
|
.filter_level(log::LevelFilter::Debug)
|
|
.init();
|
|
} else {
|
|
env_logger::Builder::from_default_env()
|
|
.filter_level(log::LevelFilter::Info)
|
|
.init();
|
|
}
|
|
}
|
|
|
|
/// Create and configure the TUI application
|
|
fn create_app(args: &Args) -> Result<App> {
|
|
let actor_id = "osis".to_string();
|
|
|
|
// Get the crate root directory
|
|
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
|
|
.unwrap_or_else(|_| ".".to_string());
|
|
let crate_root = PathBuf::from(crate_root);
|
|
|
|
let actor_path = crate_root.join("target/debug/actor_osis");
|
|
let example_dir = Some(crate_root.join("examples/scripts"));
|
|
|
|
App::new(
|
|
actor_id,
|
|
actor_path,
|
|
args.redis_url.clone(),
|
|
example_dir,
|
|
)
|
|
}
|
|
|
|
/// Spawn the actor binary as a background process
|
|
fn spawn_actor_process(_args: &Args) -> Result<Child> {
|
|
// Get the crate root directory
|
|
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
|
|
.unwrap_or_else(|_| ".".to_string());
|
|
let actor_path = PathBuf::from(crate_root).join("target/debug/actor_osis");
|
|
info!("🎬 Spawning actor process: {}", actor_path.display());
|
|
|
|
let mut cmd = Command::new(&actor_path);
|
|
|
|
// Redirect stdout and stderr to null to prevent logs from interfering with TUI
|
|
cmd.stdout(std::process::Stdio::null())
|
|
.stderr(std::process::Stdio::null());
|
|
|
|
// Spawn the process
|
|
let child = cmd
|
|
.spawn()
|
|
.with_context(|| format!("Failed to spawn actor process: {}", actor_path.display()))?;
|
|
|
|
info!("✅ Actor process spawned with PID: {}", child.id());
|
|
Ok(child)
|
|
}
|
|
|
|
/// Cleanup function to terminate actor process
|
|
fn cleanup_actor_process(mut actor_process: Child) {
|
|
info!("🧹 Cleaning up actor process...");
|
|
|
|
match actor_process.try_wait() {
|
|
Ok(Some(status)) => {
|
|
info!("Actor process already exited with status: {}", status);
|
|
}
|
|
Ok(None) => {
|
|
info!("Terminating actor process...");
|
|
if let Err(e) = actor_process.kill() {
|
|
error!("Failed to kill actor process: {}", e);
|
|
} else {
|
|
match actor_process.wait() {
|
|
Ok(status) => info!("Actor process terminated with status: {}", status),
|
|
Err(e) => error!("Failed to wait for actor process: {}", e),
|
|
}
|
|
}
|
|
}
|
|
Err(e) => {
|
|
error!("Failed to check actor process status: {}", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
let args = Args::parse();
|
|
|
|
// Initialize logging
|
|
init_logging(args.verbose);
|
|
|
|
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
|
|
.unwrap_or_else(|_| ".".to_string());
|
|
|
|
info!("🚀 Starting Baobab Actor TUI...");
|
|
info!("Actor ID: osis");
|
|
info!("Actor Path: {}/target/debug/actor_osis", crate_root);
|
|
info!("Redis URL: {}", args.redis_url);
|
|
info!("Example Directory: {}/examples/scripts", crate_root);
|
|
|
|
// Spawn the actor process first
|
|
let actor_process = spawn_actor_process(&args)?;
|
|
|
|
// Give the actor a moment to start up
|
|
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
|
|
|
// Create app and run TUI
|
|
let app = create_app(&args)?;
|
|
|
|
// Set up signal handling for graceful shutdown
|
|
let result = tokio::select! {
|
|
tui_result = setup_and_run_tui(app) => {
|
|
info!("TUI exited");
|
|
tui_result
|
|
}
|
|
_ = signal::ctrl_c() => {
|
|
info!("Received Ctrl+C, shutting down...");
|
|
Ok(())
|
|
}
|
|
};
|
|
|
|
// Clean up the actor process
|
|
cleanup_actor_process(actor_process);
|
|
|
|
result
|
|
}
|