use std::{io, time::Duration};
use tokio::time::sleep;
use tracing::level_filters::LevelFilter;
use tracing_subscriber::{EnvFilter, Layer, fmt, layer::SubscriberExt, util::SubscriberInitExt};
#[tokio::main]
async fn main() -> miette::Result<()> {
tracing_subscriber::registry()
.with(
fmt::Layer::new().with_writer(io::stderr).with_filter(
EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy(),
),
)
.init();
let root = tosub::build_root("hello_world")
.catch_signals()
.with_timeout(Duration::from_secs(5));
let exit_code = root.start(run).await?;
eprintln!("Exit code: {:?}", exit_code);
Ok(())
}
async fn run(root: tosub::Subsystem) -> miette::Result<()> {
root.spawn("child 1", child1);
root.spawn("child 2", child2);
root.spawn("child 3", child3);
root.shutdown_requested().await;
Ok(())
}
async fn child1(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.spawn("grandchild 1", grandchild1);
subsystem.spawn("grandchild 2", grandchild2);
subsystem.shutdown_requested().await;
println!("{} needs a second to shut down ...", subsystem.name());
sleep(Duration::from_secs(1)).await;
Ok(())
}
async fn grandchild2(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.spawn("great grandchild 1", great_grandchild1);
subsystem.shutdown_requested().await;
println!("{} needs a second to shut down ...", subsystem.name());
sleep(Duration::from_secs(1)).await;
Ok(())
}
async fn great_grandchild1(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.shutdown_requested().await;
println!("{} needs ten seconds to shut down ...", subsystem.name());
sleep(Duration::from_secs(10)).await;
Ok(())
}
async fn grandchild1(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.shutdown_requested().await;
println!("{} shuts down immedaiately.", subsystem.name());
Ok(())
}
async fn child2(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.spawn("grandchild 3", grandchild3);
subsystem.shutdown_requested().await;
println!("{} needs two seconds to shut down ...", subsystem.name());
sleep(Duration::from_secs(2)).await;
Ok(())
}
async fn grandchild3(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.shutdown_requested().await;
println!("{} needs two second to shut down ...", subsystem.name());
sleep(Duration::from_secs(2)).await;
Ok(())
}
async fn child3(subsystem: tosub::Subsystem) -> miette::Result<()> {
println!("Hello from {}", subsystem.name());
subsystem.shutdown_requested().await;
println!("{} needs thirty seconds to shut down ...", subsystem.name());
sleep(Duration::from_secs(30)).await;
Ok(())
}