pub fn with_timeout<T: Send + 'static, TFuture: Future<Output = T> + Send + 'static>(
    original_future: TFuture,
    timeout_ms: u64
) -> Pin<Box<dyn Future<Output = Option<T>> + Send + 'static>>
Expand description

Runs a future to completion or to timeout, whatever happens first.

Wraps the original result of a future into an Option to indicate if the future completed (Some(original result)) or timed out (None).

Examples

use std::time::Instant;

use cs_utils::{
    random_number,
    futures::{wait, with_timeout},
};

#[tokio::main]
async fn main() {
    let timeout: u64 = 25;

    // as future that never completes
    let forever_future = async move {
        loop {
            wait(5).await;
        }
    };

    // wrap the original future to get the `stop` function
    let with_timeout_future = with_timeout(forever_future, timeout);

    // record starting time
    let start_time = Instant::now();
 
    // wait for the future to complete
    let result = with_timeout_future.await;
         
    // calculate elapsed time
    let time_delta_ms = (Instant::now() - start_time).as_millis();

    assert!(
        result.is_none(),
        "Timed out future must complete with `None` result.",
    );

    // assert that the completion time of the future is close to the `timeout`
    assert!(
        time_delta_ms >= (timeout - 2) as u128,
        "Must have waited for at least duration of the timeout.",
    );
    assert!(
        time_delta_ms <= (timeout + 2) as u128,
        "Must have waited for at most duration of the timeout.",
    );
}