-
-
Couldn't load subscription status.
- Fork 2.8k
Description
Is your feature request related to a problem? Please describe.
As described in #5843, it's possible to run an async function from within a non-async context by combining Handle::block_on with task::block_in_place.
This is mentioned in the documentation for block_in_place, but not in the documentation for block_on or in the "Bridging with sync code" documentation. Additionally, the panic message when you attempt to use Handle::block_on without block_in_place does not point the user toward any solution:
This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks
"Driving asynchronous tasks" is (often) exactly why the user is invoking Handle::block_on, so this feels like a bit of a dead end, and googling the issue leads to threads such as this one about incorrect usage of #[tokio::main] (i.e. a tangentially-related issue).
It also appears to be possible to work around this issue using futures::executor::block_on; given a handle: Handle, this runs without panicking:
let _guard = handle.enter();
futures::executor::block_on(async { <some async code> });...but it's confusing that this version of block_on behaves differently from Tokio's block_on methods, so Tokio users may want to know that the "native" Tokio equivalent relies on block_in_place.
Describe the solution you'd like
The doc-comments for Handle::block_on (and possibly Runtime::block_on) should mention block_in_place for use when all of the following are true (though I may be missing some requirements; see "additional context"):
- the user wants to call
asynccode from asynccontext - the current thread may be the primary Tokio scheduler thread
- the current Tokio runtime is multithreaded
This should also be mentioned in the "Bridging with sync code" documentation.
Describe alternatives you've considered
It may be worth mentioning block_in_place in the "cannot spawn runtime within runtime" message, in case the user is trying to call async code from a sync context.
Additional context
- rfc: reducing "runtime not found" confusion #2435 mentions improving the "cannot spawn runtime within runtime" panic message, including adding "some options for fixing it", which is what I'm proposing here.
block_in_place+block_oncan hang on runtime shutdown / runtime drop #6463 is a bug related to the use ofblock_in_placewithblock_on, which suggests to me that this pattern may not be appropriate in all cases. I haven't read the issue carefully, but possibly there are specific caveats that should be included in any new documentation suggesting combiningblock_in_placewithblock_on.