Function cs_utils::futures::with_thread
source · [−]pub fn with_thread<T: Send + 'static, TFuture: Future<Output = T> + Send + 'static>(
original_future: TFuture
) -> Pin<Box<dyn Future<Output = T> + Send + 'static>>Expand description
Run a future on a separate thread.
Useful when future has a blocking code. Normally such blocking code will also block current all asynchronous tasks. This helper mitigates such issue by running blocking future on a separate thread with its own Tokio runtime.
Examples
use std::{thread, pin::Pin, time::Duration};
use futures::{future, Future};
use cs_utils::futures::{wait, with_thread};
#[tokio::main(worker_threads = 1)]
async fn main() {
// variable to count how many iterations
// the normal future has run
static mut RUN_CNT: u64 = 0;
// create a future that blocks current thread
let blocking_future = async move {
thread::sleep(Duration::from_secs(1));
};
// create a future that intended to run in background
let normal_future = async move {
loop {
unsafe { RUN_CNT += 1 }
wait(100).await;
}
};
// create futures list
let futures: Vec<Pin<Box<dyn Future<Output = ()>>>> = vec![
Box::pin(with_thread(blocking_future)), // <-- wrap the blocking future here
Box::pin(normal_future),
];
// race futures to completion
future::select_all(futures).await;
// must go thru multiple iterations in the normal future
assert!(
unsafe { RUN_CNT >= 8 } && unsafe { RUN_CNT <= 10 },
"Normal future must run iterations multiple times.",
);
}