sal/service_manager/examples/service_spaghetti.rs
2025-07-02 05:50:18 +02:00

96 lines
3.8 KiB
Rust

//! 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 = create_service_manager(None).expect("Failed to create service manager");
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. Create the service
println!("\n1. Creating the service...");
match manager.create(&service_config) {
Ok(()) => println!(" -> Success: Service '{}' created.", service_name),
Err(e) => {
eprintln!(" -> Error: Failed to create service: {}. Halting example.", e);
return;
}
}
// 2. Start the service
println!("\n2. Starting the service for the first time...");
match manager.start(service_name) {
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));
// 3. Try to start the service again while it's already running
println!("\n3. Trying to start the *same service* again...");
match manager.start(service_name) {
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 ---");
}