Expand description
§soft-cycle
A small async Rust crate for coordinating soft restarts and graceful shutdowns using a shared controller. Tasks can wait on a listener and react when a restart or shutdown is triggered.
§Usage
Use SoftCycleController::new to create a new controller instance. Use try_restart and try_shutdown to trigger a restart or shutdown respectively. Only the first call to either method will succeed until the controller is cleared via clear. Use the listener method to be notified when a restart or shutdown is triggered.
§Notice
If listener is called while the controller is already in a triggered state, it will resolve on the next trigger, not the current one.
Currently, shutdowns and restarts are only distinguishable by the boolean returned by the listener: true for shutdown, false for restart. They have no other differing behavior.
§Features
global_instance(default): Enables a process-wide default controller and the free functionsget_lifetime_controller,try_restart,try_shutdown,listener, andclearat the crate root.
§Example
use std::sync::Arc;
use soft_cycle::SoftCycleController;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let controller = Arc::new(SoftCycleController::new());
// Spawn a task to trigger a restart or shutdown
let controller_clone = controller.clone();
tokio::spawn(async move {
// Simulate some external event triggering a restart
sleep(Duration::from_secs(2)).await;
assert!(controller_clone.try_restart().await);
controller_clone.clear();
// Simulate some external event triggering a shutdown
sleep(Duration::from_secs(2)).await;
assert!(controller_clone.try_shutdown().await);
});
// Simulate another working task
let controller_clone = controller.clone();
tokio::spawn(async move {
loop {
println!("Worker is doing some work...");
tokio::select! {
_ = sleep(Duration::from_millis(500)) => {},
is_shutdown = controller_clone.listener() => {
if is_shutdown {
println!("Worker received shutdown signal.");
break;
} else {
println!("Worker received restart signal.");
}
}
}
}
});
// Do something while waiting for the trigger: increment a counter and
// print it every 200 milliseconds
let mut counter = 0;
loop {
tokio::select! {
_ = sleep(Duration::from_millis(200)) => {
counter += 1;
println!("Main loop counter: {}", counter);
}
is_shutdown = controller.listener() => {
if is_shutdown {
println!("Main loop received shutdown signal.");
break;
} else {
println!("Main loop received restart signal.");
// Reset counter on restart
counter = 0;
}
}
}
}
}Structs§
- Soft
Cycle Controller - Controller for soft restarts and graceful shutdowns.
- Soft
Cycle Listener - Future that completes when the associated controller triggers a restart or shutdown.
Functions§
- clear
global_instance - Clears the triggered state on the global
SoftCycleControllerinstance. - get_
lifetime_ controller global_instance - Returns a reference to the global
SoftCycleController, initializing it on first call. - listener
global_instance - Listener that resolves when a restart or shutdown is triggered on the
global
SoftCycleControllerinstance. - try_
restart global_instance - Attempts to trigger a restart on the global
SoftCycleControllerinstance. - try_
shutdown global_instance - Attempts to trigger a shutdown on the global
SoftCycleControllerinstance.