pub struct Shutdown {
pub ctrlc: bool,
pub signals: HashSet<Sig>,
pub grace: u32,
pub mercy: u32,
pub force: bool,
/* private fields */
}
Expand description
Graceful shutdown configuration.
Summary
This structure configures when and how graceful shutdown occurs. The ctrlc
and signals
properties control when and the grace
and mercy
properties control how.
When a shutdown is triggered by an externally or internally initiated
Shutdown::notify()
, Rocket allows application I/O to make progress for
at most grace
seconds before initiating connection-level shutdown.
Connection shutdown forcibly terminates application I/O, but connections
are allowed an additional mercy
seconds to shutdown before being
forcefully terminated. This implies that a cooperating and active remote
client maintaining an open connection can stall shutdown for at most grace
seconds, while an uncooperative remote client can stall shutdown for at
most grace + mercy
seconds.
Triggers
All graceful shutdowns are initiated via Shutdown::notify()
. Rocket
can be configured to call Shutdown::notify()
automatically on certain
conditions, specified via the ctrlc
and signals
properties of this
structure. More specifically, if ctrlc
is true
(the default), ctrl-c
(SIGINT
) initiates a server shutdown, and on Unix, signals
specifies a
list of IPC signals that trigger a shutdown (["term"]
by default).
Grace Period
Once a shutdown is triggered, Rocket stops accepting new connections and
waits at most grace
seconds before initiating connection shutdown.
Applications can await
the Shutdown
future to detect
a shutdown and cancel any server-initiated I/O, such as from infinite
responders, to avoid abrupt I/O
cancellation.
Mercy Period
After the grace period has elapsed, Rocket initiates connection shutdown,
allowing connection-level I/O termination such as TLS’s close_notify
to
proceed nominally. Rocket waits at most mercy
seconds for connections to
shutdown before forcefully terminating all connections.
Runaway I/O
If tasks are still executing after both periods and a Rocket configured async runtime is in use, Rocket waits an unspecified amount of time (not to exceed 1s) and forcefully terminates the asynchronous runtime. This guarantees that the server process terminates, prohibiting uncooperative, runaway I/O from preventing shutdown altogether.
A “Rocket configured runtime” is one started by the #[rocket::main]
and
#[launch]
attributes. Rocket never forcefully terminates a custom
runtime. A server that creates its own async runtime must take care to
terminate itself if tasks it spawns fail to cooperate.
Under normal circumstances, forced termination should never occur. No use of
“normal” cooperative I/O (that is, via .await
or task::spawn()
) should
trigger abrupt termination. Instead, forced cancellation is intended to
prevent buggy code, such as an unintended infinite loop or unknown use of
blocking I/O, from preventing shutdown.
This behavior can be disabled by setting Shutdown::force
to false
.
Example
As with all Rocket configuration options, when using the default
Config::figment()
, Shutdown
can be
configured via a Rocket.toml
file. As always, defaults are provided
(documented below), and thus configuration only needs to provided to change
defaults.
use rocket::Config;
// If these are the contents of `Rocket.toml`...
[default.shutdown]
ctrlc = false
signals = ["term", "hup"]
grace = 10
mercy = 5
// The config parses as follows:
assert_eq!(config.shutdown.ctrlc, false);
assert_eq!(config.shutdown.grace, 10);
assert_eq!(config.shutdown.mercy, 5);
use rocket::config::Sig;
assert_eq!(config.shutdown.signals.len(), 2);
assert!(config.shutdown.signals.contains(&Sig::Term));
assert!(config.shutdown.signals.contains(&Sig::Hup));
Or, as with all configuration options, programmatically:
use rocket::config::{Config, Shutdown};
#[cfg(unix)]
use rocket::config::Sig;
let config = Config {
shutdown: Shutdown {
ctrlc: false,
#[cfg(unix)]
signals: {
let mut set = std::collections::HashSet::new();
set.insert(Sig::Term);
set.insert(Sig::Hup);
set
},
grace: 10,
mercy: 5,
force: true,
..Default::default()
},
..Config::default()
};
assert_eq!(config.shutdown.ctrlc, false);
assert_eq!(config.shutdown.grace, 10);
assert_eq!(config.shutdown.mercy, 5);
assert_eq!(config.shutdown.force, true);
#[cfg(unix)] {
assert_eq!(config.shutdown.signals.len(), 2);
assert!(config.shutdown.signals.contains(&Sig::Term));
assert!(config.shutdown.signals.contains(&Sig::Hup));
}
Fields§
§ctrlc: bool
Whether ctrl-c
(SIGINT
) initiates a server shutdown.
default: true
signals: HashSet<Sig>
On Unix, a set of signal which trigger a shutdown. On non-Unix, this option is unavailable and silently ignored.
default: { Sig::Term
}
grace: u32
The grace period: number of seconds to continue to try to finish outstanding server I/O for before forcibly terminating it.
default: 2
mercy: u32
The mercy period: number of seconds to continue to try to finish outstanding connection I/O for before forcibly terminating it.
default: 3
force: bool
Whether to force termination of an async runtime that refuses to cooperatively shutdown.
Rocket never forcefully terminates a custom runtime, irrespective of this value. A server that creates its own async runtime must take care to terminate itself if it fails to cooperate.
Note: Rocket only reads this value from sources in the default provider.
default: true
Trait Implementations§
source§impl<'de> Deserialize<'de> for Shutdown
impl<'de> Deserialize<'de> for Shutdown
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,
source§impl PartialEq<Shutdown> for Shutdown
impl PartialEq<Shutdown> for Shutdown
impl StructuralPartialEq for Shutdown
Auto Trait Implementations§
impl RefUnwindSafe for Shutdown
impl Send for Shutdown
impl Sync for Shutdown
impl Unpin for Shutdown
impl UnwindSafe for Shutdown
Blanket Implementations§
§impl<'a, T> AsTaggedExplicit<'a> for Twhere
T: 'a,
impl<'a, T> AsTaggedExplicit<'a> for Twhere T: 'a,
§impl<'a, T> AsTaggedImplicit<'a> for Twhere
T: 'a,
impl<'a, T> AsTaggedImplicit<'a> for Twhere T: 'a,
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> IntoCollection<T> for T
impl<T> IntoCollection<T> for T
§fn into_collection<A>(self) -> SmallVec<A>where
A: Array<Item = T>,
fn into_collection<A>(self) -> SmallVec<A>where A: Array<Item = T>,
self
into a collection.