Struct graceful_shutdown::Shutdown
source · pub struct Shutdown(_);
Expand description
Future for graceful shutdown.
This is a Future
which doesn’t complete until a shutdown has been
initiated (for example with Shutdown::shutdown
) and any pending tasks have been completed.
It also contains associated functions for keeping track of tasks that need to be completed
before shutdown and an initiated
function to create a future that only
waits until shutdown has been initiated.
Implementations
sourceimpl Shutdown
impl Shutdown
sourcepub fn with_terminator<T: Future<Output = ()>>(
self,
terminator: T
) -> WithTerminator<T> ⓘ
pub fn with_terminator<T: Future<Output = ()>>(
self,
terminator: T
) -> WithTerminator<T> ⓘ
Add an early termination condition.
After shutdown has been initiated, the terminator
future will be run, and if it completes
before all tasks are completed the shutdown future will complete, thus finishing the
shutdown even if there are outstanding tasks. This can be useful for using a timeout or
signal (or combination) to force a full shutdown even if one or more tasks are taking
longer than expected to finish.
The returned future has a boolean output that is true
if the future was terminated early
due to the termination condition, and false
if all remaining tasks completed normally.
Note that terminator
will not start to be polled until after shutdown has been initiated.
However, you may need to delay creation of the actual timeout future until
the first poll, so that the end time is set correctly. This can be done using something
like
let shutdown = Shutdown::new().with_terminator(async {
tokio::time::sleep(Duration::from_secs(30)).await;
});
sourcepub fn shutdown(&self)
pub fn shutdown(&self)
Initiate shutdown.
This signals that a graceful shutdown shold be started. After calling this
is_shutting_down
will return true for any reference to the
same Shutdown
instance. And once all pending tasks are completed, the Shutdown
future
will complete.
sourcepub fn shutdown_after<F: Future>(&self, f: F) -> impl Future<Output = F::Output>
pub fn shutdown_after<F: Future>(&self, f: F) -> impl Future<Output = F::Output>
Return a new future that waits for f
to complete, then initiates shutdown.
Examples
let shutdown = Shutdown::new();
let interrupt = shutdown.shutdown_after(ctrl_c());
async {
interrupt.await.expect("Unable to listen to signal");
// peform additional cleanup before shutting down
cleanup();
shutdown.await;
}
sourcepub fn is_shutting_down(&self) -> bool
pub fn is_shutting_down(&self) -> bool
Return true if shutdown as been initiated.
sourcepub fn num_pending(&self) -> usize
pub fn num_pending(&self) -> usize
Return how many tasks are currently pending.
This should not be relied on to be completely accurate in a multi-threaded context. However, it may be useful for reporting approximately how much work still needs to be done before shutting down the program.
sourcepub fn graceful<F: Future>(&self, task: F) -> Graceful<F> ⓘ
pub fn graceful<F: Future>(&self, task: F) -> Graceful<F> ⓘ
Wrap a future so that it prevents the Shutdown
future from completing until
after this future completes.
sourcepub fn cancel_on_shutdown<F: Future>(&self, future: F) -> CancelOnShutdown<F> ⓘ
pub fn cancel_on_shutdown<F: Future>(&self, future: F) -> CancelOnShutdown<F> ⓘ
Wrap a future so that it is cancelled if shutdown is initiated.
If the future completes the result is returned in a Some
. If it is canceled
due to shutdown, None
is returned.
Examples
Event loop with shutdown:
let shutdown = Shutdown::new();
loop {
match shutdown.cancel_on_shutdown(getEvent()).await {
Some(_) => unimplemented!(),
None => break,
}
}
shutdown.await;
Future that waits for shutdown to be initiated:
use graceful_shutdown::Shutdown;
let shutdown = Shutdown::new();
let future = shutdown.cancel_on_shutdown(std::future::pending::<()>());