Skip to main content

Crate soft_cycle

Crate soft_cycle 

Source
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

§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§

SoftCycleController
Controller for soft restarts and graceful shutdowns.
SoftCycleListener
Future that completes when the associated controller triggers a restart or shutdown.

Functions§

clearglobal_instance
Clears the triggered state on the global SoftCycleController instance.
get_lifetime_controllerglobal_instance
Returns a reference to the global SoftCycleController, initializing it on first call.
listenerglobal_instance
Listener that resolves when a restart or shutdown is triggered on the global SoftCycleController instance.
try_restartglobal_instance
Attempts to trigger a restart on the global SoftCycleController instance.
try_shutdownglobal_instance
Attempts to trigger a shutdown on the global SoftCycleController instance.