use tokio::{runtime::Handle, task};
pub trait HandleExt {
fn block_on_place<F: Future>(&self, future: F) -> F::Output;
}
impl HandleExt for Handle {
#[inline]
fn block_on_place<F: Future>(&self, future: F) -> F::Output {
#[cfg(feature = "tracing")]
if Handle::try_current().is_ok() {
tracing::warn!("Calling `block_on_place` from within a runtime context.");
}
task::block_in_place(|| self.block_on(future))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn inside_runtime() {
let handle = Handle::current();
handle.block_on_place(async {
});
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn outside_runtime() {
let handle = Handle::current();
let task = task::spawn_blocking(move || {
handle.block_on_place(async {
});
});
task.await.expect("should not fail")
}
}