larust_core/lifecycle/mod.rs
1//! Process lifecycle: graceful shutdown today, the dual-process
2//! zero-downtime restart handoff (listener passing, readiness protocol,
3//! admin restart channel) in later stages of the same feature.
4
5// `pub`, not `pub(crate)` on all three of these - needed so `lib.rs`'s
6// `#[doc(hidden)] pub mod __internal` can re-export them for this crate's
7// own fixture binaries and integration tests (which are separate crates
8// from this library, even though they share this package - see that
9// module's doc comment).
10pub mod admin;
11pub mod handoff;
12pub mod listener;
13pub(crate) mod readiness;
14mod signal;
15// Not re-exported via `__internal` like the four above -- only
16// `handoff.rs` ever calls into this; no fixture or external test needs
17// to reach it directly (see `supervisor`'s own doc comment).
18pub(crate) mod supervisor;
19
20pub(crate) use signal::wait_for_termination;
21
22use std::time::Duration;
23
24/// Configuration for [`crate::Application::with_graceful_shutdown`] -
25/// **opt-in**: an `Application` that never calls that method keeps today's
26/// exact behavior (a bare `axum::serve` that exits the instant Ctrl+C is
27/// pressed). Flipping every existing app's shutdown behavior silently
28/// would be exactly the kind of surprise a framework upgrade shouldn't
29/// introduce.
30#[derive(Debug, Clone)]
31pub struct GracefulShutdown {
32 /// Upper bound on how long `serve()` waits for in-flight requests to
33 /// finish after a shutdown signal, before forcing the process to exit
34 /// anyway. Never "wait forever" - a stuck connection (a slow client, a
35 /// hung upstream call) must not prevent a deploy or a plain Ctrl+C
36 /// from ever completing.
37 pub drain_timeout: Duration,
38 /// If `true`, also runs the local restart-trigger admin channel (see
39 /// `lifecycle::admin`) alongside plain Ctrl+C/SIGTERM handling - a
40 /// second, independent opt-in on top of graceful shutdown itself,
41 /// since not every app wants a local IPC surface open even when it
42 /// does want graceful shutdown. `false` by default. The binary to
43 /// spawn as a replacement is `std::env::current_exe()` for now (a
44 /// release-pointer convention, so a *newly built* binary rather than
45 /// the exact file currently running can be targeted, is a later
46 /// addition to this same feature).
47 pub restart_channel: bool,
48}
49
50impl Default for GracefulShutdown {
51 fn default() -> Self {
52 Self {
53 drain_timeout: Duration::from_secs(30),
54 restart_channel: false,
55 }
56 }
57}