See title. Both async-std and tokio before 0.2.0 (including 0.2.0-alpha.6) have a way to block on non-'static futures without having a mutable reference to the runtime.
The following function implements this more or less but at the cost of creating a FutureObj, a heap allocation and requiring the output type of the future to be 'static. It would be nicer if Runtime::block_on() would work with a immutable reference to the runtime again, or some other alternative.
fn block_on<F>(
runtime: &tokio::runtime::Runtime,
future: F,
) -> Result<F::Output, tokio::task::JoinError>
where
F: Send + Future,
F::Output: Send + 'static,
{
use futures::task::FutureObj;
use std::mem;
let future = FutureObj::new(Box::pin(future));
// We make sure here to block until the future is completely handled before returning
let future = unsafe { mem::transmute::<_, FutureObj<'static, _>>(future) };
let join_handle = runtime.spawn(future);
futures::executor::block_on(join_handle)
}
runtime.enter(|| futures::executor::block_on(future))
Thanks, that also works and is simpler indeed :) And it has the advantage the the current thread is not just idly waiting but actually polls the future.
Do you think it would make sense to have a convenience function for this, or at least to document this somewhere?
Definitely - I know that there's been some discussion on Discord about adding that interface to Handle, but I don't know if that's happened yet.
I believe this is resolved by #2437, which added block_on to Handle. It is roughly equivalent to handle.enter(|| futures::executor::block_on(future)), except that it has integration with the cooperative yielding system.
Most helpful comment