use failure::ResultExt;
use futures::executor::block_on;
use std::thread;
use tokio::sync::mpsc;
use crate::Result;
pub(crate) async fn run_sync_fn_in_background<F, T>(
thread_name: String,
f: F,
) -> Result<T>
where
F: (FnOnce() -> Result<T>) + Send + 'static,
T: Send + 'static,
{
let (mut sender, mut receiver) = mpsc::channel(1);
let thr = thread::Builder::new().name(thread_name);
let handle = thr
.spawn(move || {
if block_on(sender.send(f())).is_err() {
panic!("should always be able to send results from background thread");
}
})
.context("could not spawn thread")?;
let background_result = receiver.recv().await;
let result = match background_result {
Some(Ok(value)) => Ok(value),
Some(Err(err)) => Err(err),
None => {
unreachable!("background thread did not send any results");
}
};
handle.join().expect("background worker thread panicked");
result
}