karyon_core/async_util/
timeout.rs

1use std::{future::Future, time::Duration};
2
3use crate::{error::Error, Result};
4
5use super::{select, sleep, Either};
6
7/// Waits for a future to complete or times out if it exceeds a specified
8/// duration.
9///
10/// # Example
11///
12/// ```
13/// use std::{future, time::Duration};
14///
15/// use karyon_core::async_util::timeout;
16///
17/// async {
18///     let fut = future::pending::<()>();
19///     assert!(timeout(Duration::from_millis(100), fut).await.is_err());
20/// };
21///
22/// ```
23///
24pub async fn timeout<T, F>(delay: Duration, future1: F) -> Result<T>
25where
26    F: Future<Output = T>,
27{
28    let result = select(sleep(delay), future1).await;
29
30    match result {
31        Either::Left(_) => Err(Error::Timeout),
32        Either::Right(res) => Ok(res),
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use std::{future, time::Duration};
40
41    #[test]
42    fn test_timeout() {
43        crate::async_runtime::block_on(async move {
44            let fut = future::pending::<()>();
45            assert!(timeout(Duration::from_millis(10), fut).await.is_err());
46
47            let fut = sleep(Duration::from_millis(10));
48            assert!(timeout(Duration::from_millis(50), fut).await.is_ok())
49        });
50    }
51}