//! service_spaghetti - An example of messy service management. //! //! This example demonstrates how the service manager behaves when commands //! are issued in a less-than-ideal order, such as starting a service that's //! already running or removing a service that hasn't been stopped. use sal_service_manager::{create_service_manager, ServiceConfig}; use std::collections::HashMap; use std::thread; use std::time::Duration; fn main() { let manager = match create_service_manager() { Ok(manager) => manager, Err(e) => { eprintln!("Error: Failed to create service manager: {}", e); return; } }; let service_name = "com.herocode.examples.spaghetti"; let service_config = ServiceConfig { name: service_name.to_string(), binary_path: "/bin/sh".to_string(), args: vec![ "-c".to_string(), "while true; do echo 'Spaghetti service is running...'; sleep 5; done".to_string(), ], working_directory: None, environment: HashMap::new(), auto_restart: false, }; println!("--- Service Spaghetti Example ---"); println!("This example demonstrates messy, error-prone service management."); // Cleanup from previous runs to ensure a clean slate if let Ok(true) = manager.exists(service_name) { println!( "\nService '{}' found from a previous run. Cleaning up first.", service_name ); let _ = manager.stop(service_name); let _ = manager.remove(service_name); println!("Cleanup complete."); } // 1. Start the service (creates and starts in one step) println!("\n1. Starting the service for the first time..."); match manager.start(&service_config) { Ok(()) => println!(" -> Success: Service '{}' started.", service_name), Err(e) => { eprintln!( " -> Error: Failed to start service: {}. Halting example.", e ); return; } } thread::sleep(Duration::from_secs(2)); // 2. Try to start the service again while it's already running println!("\n2. Trying to start the *same service* again..."); match manager.start(&service_config) { Ok(()) => println!(" -> Unexpected Success: Service started again."), Err(e) => eprintln!( " -> Expected Error: {}. The manager should detect it is already running.", e ), } // 3. Let it run for a bit println!("\n3. Letting the service run for 5 seconds..."); thread::sleep(Duration::from_secs(5)); // 4. Remove the service without stopping it first // The `remove` function is designed to stop the service if it's running. println!("\n4. Removing the service without explicitly stopping it first..."); match manager.remove(service_name) { Ok(()) => println!(" -> Success: Service was stopped and removed."), Err(e) => eprintln!(" -> Error: Failed to remove service: {}", e), } // 5. Try to stop the service after it has been removed println!("\n5. Trying to stop the service that was just removed..."); match manager.stop(service_name) { Ok(()) => println!(" -> Unexpected Success: Stopped a removed service."), Err(e) => eprintln!( " -> Expected Error: {}. The manager knows the service is gone.", e ), } // 6. Try to remove the service again println!("\n6. Trying to remove the service again..."); match manager.remove(service_name) { Ok(()) => println!(" -> Unexpected Success: Removed a non-existent service."), Err(e) => eprintln!( " -> Expected Error: {}. The manager correctly reports it's not found.", e ), } println!("\n--- Spaghetti Example Finished ---"); }