use hero_runner::{spawn_sync_runner, script_mode::execute_script_mode}; use clap::Parser; use log::{error, info}; use tokio::sync::mpsc; mod engine; use engine::create_osiris_engine; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// Runner ID runner_id: String, /// Redis URL (also used as HeroDB URL) #[arg(short = 'r', long, default_value = "redis://localhost:6379")] redis_url: String, /// Base database ID for OSIRIS contexts #[arg(long, default_value_t = 1)] base_db_id: u16, /// Script to execute in single-job mode (optional) #[arg(short, long)] script: Option, } #[tokio::main] async fn main() -> Result<(), Box> { // Initialize logging env_logger::init(); let args = Args::parse(); // Check if we're in script mode if let Some(script_content) = args.script { info!("Running in script mode with runner ID: {}", args.runner_id); let redis_url = args.redis_url.clone(); let base_db_id = args.base_db_id; let result = execute_script_mode( &script_content, &args.runner_id, args.redis_url, std::time::Duration::from_secs(300), // Default timeout for OSIS move || create_osiris_engine() .expect("Failed to create OSIRIS engine"), ).await; match result { Ok(output) => { println!("Script execution result:\n{}", output); return Ok(()); } Err(e) => { error!("Script execution failed: {}", e); return Err(e); } } } info!("Starting OSIS Sync Runner with ID: {}", args.runner_id); info!("Redis URL: {}", args.redis_url); // Create shutdown channel let (shutdown_tx, shutdown_rx) = mpsc::channel::<()>(1); // Setup signal handling for graceful shutdown let shutdown_tx_clone = shutdown_tx.clone(); tokio::spawn(async move { tokio::signal::ctrl_c().await.expect("Failed to listen for ctrl+c"); info!("Received Ctrl+C, initiating shutdown..."); let _ = shutdown_tx_clone.send(()).await; }); // Spawn the sync runner with engine factory let redis_url = args.redis_url.clone(); let base_db_id = args.base_db_id; let runner_handle = spawn_sync_runner( args.runner_id.clone(), args.redis_url, shutdown_rx, move || create_osiris_engine() .expect("Failed to create OSIRIS engine"), ); info!("OSIS Sync Runner '{}' started successfully", args.runner_id); // Wait for the runner to complete match runner_handle.await { Ok(Ok(())) => { info!("OSIS Sync Runner '{}' shut down successfully", args.runner_id); } Ok(Err(e)) => { error!("OSIS Sync Runner '{}' encountered an error: {}", args.runner_id, e); return Err(e); } Err(e) => { error!("Failed to join OSIS Sync Runner '{}' task: {}", args.runner_id, e); return Err(Box::new(e)); } } Ok(()) } /// Example: Run a Rhai script with OSIRIS support pub fn run_osiris_script( script: &str, ) -> Result<(), Box> { let engine = create_osiris_engine()?; engine.run(script)?; Ok(()) }