-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rt: add Handle::block_on #3549
rt: add Handle::block_on #3549
Conversation
/// TODO: write docs if this is a good direction | ||
pub fn block_on<F: Future>(&self, future: F) -> F::Output { | ||
// Enter the **runtime** context. This configures spawning, the current I/O driver, ... | ||
let _rt_enter = self.enter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can enter check if the runtime is still alive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you opened a different issue, but that is someone of an orthogonal concern :)
let mut _blocking_enter = crate::runtime::enter(true); | ||
|
||
// Block on the future | ||
_blocking_enter.block_on(future).expect("failed to park thread") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then this should be a block on that runs the task and can wake up on runtime shutdown. We likely wanna use the same notify trick?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The future isn't a task per se. When the runtime is shutdown, in theory all resources should transition to a "shutdown" state and in-flight operations canceled. This would result in this block_on waking up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if the task is doing nothing? E.g. if I just call handle.block_on(std::future::pending())
, then what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I guess my gut is that calling Handle::block_on
shouldn't necessarily force exit when the runtime shuts down. My gut reaction is that handle.block_on(std::future::pending())
would just run indefinitely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An infallible API like this certainly works for us if it is safe to implement this way. But if it is necessary to be fallible (returning Result<F::Output, TheRuntimeIsGone>
) as @Darksonn has suggested due to Handle
being a weak reference, that's fine with us too.
There has been some concern about the behavior of
There was some concern regarding hanging futures. I believe the above proposal avoids any hanging tasks on runtime shutdown, but if there is some reason it cannot be implemented to avoid hangs, we will need some other solution. |
Should this be closed in favor of #3569 ? |
yes. |
Add
runtime::Handle::block_on
. The function enters the runtime context and blocks the current thread while the future executes. This strategy does not do anything special with thecurrent_thread
runtime. If there is no thread "driving" the runtime, then neither spawned tasks nor I/O resources will not make progress. To avoid this, it is recommended to use the multi-threaded scheduler (perhaps w/ core-threads set to 1).This is a draft PR to demonstrate the direction. Before merging, the PR would need API documentation and tests.
Refs: #3097
Fixes #2965, #3096
cc @stuhood, @Keruspe