use std::{sync::Arc, time::Duration};
use allframe_core::shutdown::{
GracefulShutdown, GracefulShutdownExt, ShutdownAwareTaskSpawner, ShutdownExt,
};
#[tokio::main]
async fn main() {
println!("=== Shutdown Patterns ===\n");
pattern_basic_spawner().await;
pattern_with_results().await;
pattern_cleanup().await;
pattern_shutdown_ext().await;
pattern_multiple_workers().await;
println!("\n=== All patterns demonstrated ===");
}
async fn pattern_basic_spawner() {
println!("--- Pattern 1: Basic Task Spawning ---\n");
let shutdown = Arc::new(GracefulShutdown::new());
let spawner = ShutdownAwareTaskSpawner::new(shutdown.clone());
let handle = spawner.spawn("worker", || async {
println!(" Worker started");
tokio::time::sleep(Duration::from_millis(50)).await;
println!(" Worker completed");
});
handle.await.unwrap();
println!();
}
async fn pattern_with_results() {
println!("--- Pattern 2: Tasks with Results ---\n");
let shutdown = Arc::new(GracefulShutdown::new());
let spawner = ShutdownAwareTaskSpawner::new(shutdown.clone());
let handle = spawner.spawn_with_result("compute", || async {
tokio::time::sleep(Duration::from_millis(50)).await;
42
});
match handle.await.unwrap() {
Some(result) => println!(" Completed with result: {}", result),
None => println!(" Task was cancelled"),
}
let handle = spawner.spawn_with_result("long_compute", || async {
tokio::time::sleep(Duration::from_secs(60)).await;
999
});
shutdown.shutdown();
match handle.await.unwrap() {
Some(result) => println!(" Completed with result: {}", result),
None => println!(" Task was cancelled (as expected)"),
}
println!();
}
async fn pattern_cleanup() {
println!("--- Pattern 3: Cleanup with Error Handling ---\n");
let shutdown = GracefulShutdown::new();
let result: Result<(), &str> = shutdown
.perform_shutdown(|| async {
println!(" Running cleanup...");
tokio::time::sleep(Duration::from_millis(50)).await;
println!(" Cleanup done");
Ok(())
})
.await;
println!(" Result: {:?}", result);
let result: Result<(), &str> = shutdown
.perform_shutdown(|| async {
println!(" Running cleanup that fails...");
Err("connection timeout")
})
.await;
println!(" Result: {:?}", result);
println!();
}
async fn pattern_shutdown_ext() {
println!("--- Pattern 4: Cancellable Futures ---\n");
let shutdown = GracefulShutdown::new();
let result = async { "completed" }.with_shutdown(&shutdown).await;
println!(" with_shutdown (completes): {:?}", result);
let shutdown = GracefulShutdown::new();
let result = shutdown.run_until_shutdown(async { "done" }).await;
println!(" run_until_shutdown (completes): {:?}", result);
let shutdown = Arc::new(GracefulShutdown::new());
let shutdown_clone = shutdown.clone();
tokio::spawn(async move {
tokio::time::sleep(Duration::from_millis(50)).await;
shutdown_clone.shutdown();
});
let result = shutdown
.run_until_shutdown(async {
tokio::time::sleep(Duration::from_millis(200)).await;
"never reached"
})
.await;
println!(" run_until_shutdown (cancelled): {:?}", result);
println!();
}
async fn pattern_multiple_workers() {
println!("--- Pattern 5: Multiple Workers ---\n");
let shutdown = Arc::new(GracefulShutdown::new());
let spawner = ShutdownAwareTaskSpawner::new(shutdown.clone());
let mut handles = vec![];
for i in 1..=3 {
let spawner = spawner.clone(); let handle = spawner.spawn(&format!("worker_{}", i), move || async move {
println!(" Worker {} started", i);
tokio::time::sleep(Duration::from_millis(50 * i as u64)).await;
println!(" Worker {} done", i);
});
handles.push(handle);
}
for handle in handles {
handle.await.unwrap();
}
println!();
}