Tokio: Provide a way to block_on() non-'static futures without having a mutable reference to the Runtime

Created on 31 Dec 2019  路  4Comments  路  Source: tokio-rs/tokio

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)
}
T-docs

Most helpful comment

runtime.enter(|| futures::executor::block_on(future))

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings