use ggen_core::utils::error::Result;
use std::future::Future;
pub fn execute<F>(future: F) -> Result<()>
where
F: Future<Output = Result<()>>,
{
let runtime = match tokio::runtime::Runtime::new() {
Ok(rt) => rt,
Err(e) => {
let msg = format!("Failed to create Tokio runtime: {}", e);
log::error!("{}", msg);
return Err(ggen_core::utils::error::Error::new(&msg));
}
};
runtime.block_on(future)
}
pub fn block_on<F, T>(async_op: F) -> Result<T>
where
F: Future<Output = T> + Send,
T: Send,
{
match tokio::runtime::Handle::try_current() {
Ok(_) => {
std::thread::scope(|s| {
s.spawn(move || {
let rt = match tokio::runtime::Runtime::new() {
Ok(runtime) => runtime,
Err(e) => {
let msg = format!("Failed to create Tokio runtime: {}", e);
log::error!("{}", msg);
return Err(ggen_core::utils::error::Error::new(&msg));
}
};
Ok(rt.block_on(async_op))
})
.join()
.map_err(|_| ggen_core::utils::error::Error::new("Runtime thread panicked"))?
})
}
Err(_) => {
match tokio::runtime::Runtime::new() {
Ok(runtime) => Ok(runtime.block_on(async_op)),
Err(e) => {
let msg = format!("Failed to create Tokio runtime: {}", e);
log::error!("{}", msg);
Err(ggen_core::utils::error::Error::new(&msg))
}
}
}
}
}